Service Oriented vs Microservice Architecture

Service Oriented vs Microservice Architecture

I have observed people mistakenly taking service-oriented architecture as microservice architecture. Hence, I decided to briefly discuss the different architecture styles and then compare Service Oriented and Microservice architecture on various parameters.

Monolithic Architecture: A monolithic application is built as a single unit and in 3 layers:

  1. The client-side user interface or Presentation layer - Consists of HTML pages and JS running in a browser on the user's machine
  2. Database or Data Tier - Consists of tables inserted into a common, and usually relational, database management system
  3. Server-side application or Application Tier - Handles HTTP requests, executes domain logic, retrieves and updates data from the database, and selects and populates HTML views to be sent to the browser.

This servicer side application is a monolith as it is a single logical executable. Entire logic to handle a request runs in a single process, which allows using the basic features of the language to divide up the application into classes and functions. One may even horizontally scale the monolith by running many instances behind a load-balancer.

Though Monolithic applications have infinite success stories, with the advent of cloud technologies, they are no longer the first choice as a change made to even a small part of the application, requires the entire monolith to be rebuilt and deployed. In addition, it's often hard to keep a good modular structure, making it harder to keep changes that ought to only affect one module within that module. Scaling requires scaling of the entire application rather than parts of it that require greater resource.

Service Oriented Architecture (SOA): Here, the solution is composed of distinct components (or services) which facilitate some business requirement/function such as user account creation. These components provide services to other components using an agreed communication protocol over the network. The communication may comprise direct data passing or via a connecting service. More often than not, loosely coupled components of SOA use Enterprise service bus (ESB) messaging protocol to communicate among themselves. The focus of SOA is more of to integrate various distributed, separately-maintained and deployed services and less on the modularization of application. SOA services are primarily divided into service provider and service consumer. Consumer layer is the place where the services interact with other entities such as other services, UI, third parties, etc. Provider layer comprises all the services within SOA.

Microservices Architecture (MSA): Microservices architecture is a suite of completely independent deployable services each one of which serves only one specific business requirement such as user management, etc. Services have specific characteristics such as organization around business capability, automated deployment, intelligent endpoints, decentralized control of technologies and data. In brief, MSA is an approach to develop a single application as a suite of small services with bare-minimum centralized management, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. Below are a few characteristics of MSA:

  • Componentization - As an analogy to the real world, it is always easy to build anything in components and plug them together. A component from MSA perspective may be defined as a unit of software that is independently replaceable and upgradable. In MSA, along with using libraries (libraries are components that are linked into a program and called using in-memory function calls), the software is broken down into services to achieve componentization. Services are out of process components which communicate with mechanisms such as a web-service request or remote procedural calls. However, the approach of service is preferred over libraries as unlike libraries, services are independently deployable and don't require entire application redeployment. Moreover, using services as components help in making component interface more explicit. On the negative side, as services encourage the use of remote calls which are more expensive rather than in-process calls, the remote calls need to be fine-grained.
  • Organization around business capabilities - Usually, conventional ways are followed to split the large application which is based on technology layers, resulting in UI teams, server-side logic teams, and database teams. As part of optimization, the engineers force the logic in whichever application they get access to. However, the microservice approach to split the application is different and organized around business capability. Such services take a full-stack implementation of software for that business area, including user-interface, persistent storage, and any external collaborations. Hence, the teams are cross-functional, including the full range of skills required for the development: user-experience, database, and project management.
  • Products not projects - Under this model, it is preferred to have a team own a product over its full lifetime and software team takes full responsibility for the software in production. This brings developers into day-to-day contact with how their software behaves in production and increases contact with their users, as they have to take on at least some of the support burden. Rather than looking at the software as a set of functionality to be completed, there is an on-going relationship where the question is how can software assist its users to enhance business capability. The same approach can be taken even with monolithic applications, but the smaller granularity of services makes it easier to create personal relationships between service developers and their users.
  • Smart endpoints and dumb pipes - When building communication structures between different processes, most of the times, lot of focus and functionality is embedded in the communication mechanism itself. E.g. Enterprise Service Bus (ESB), where ESB products often include sophisticated facilities for message routing, choreography, transformation, and applying business rules. The microservice community favours an alternative approach: smart endpoints and dumb pipes. Applications built from microservices aim to be as decoupled and as cohesive as possible - they own their own domain logic and act more as filters in the classical Unix sense - receiving a request, applying logic as appropriate and producing a response. These are choreographed using simple RESTful protocols rather than complex protocols such as WS-Choreography or BPEL or orchestration by a central tool. The two protocols used most commonly are HTTP request-response with resource API's and lightweight messaging. Microservice teams use the principles and protocols that the world wide web (and to a large extent, Unix) is built on. The second approach in common use is messaging over a lightweight message bus. The infrastructure chosen is typically dumb (dumb as in acts as a message router only) - simple implementations such as RabbitMQ or ZeroMQ don't do much more than provide a reliable asynchronous fabric - the smarts still live in the endpoints that are producing and consuming messages; in the services. In a monolith, the components are executing in-process and communication between them is via either method invocation or function call. The biggest issue in changing a monolith into microservices lies in changing the communication pattern. A naive conversion from in-memory method calls to RPC leads to chatty communications which don't perform well. Instead, you need to replace the fine-grained communication with a coarser -grained approach.
  • Decentralized Governance - Centralized governance results in the utilization of single technology platforms. When you split the monolith's components out into services, you may choose the required and preferred technology platform effectively. e.g. Use Node.js to stand up a simple reports page, C++ for a particularly gnarly near-real-time component, swap in a different flavour of the database that better suits the read behaviour of one component, etc. Teams building microservices don't prefer to use a set of defined standards, but they prefer the idea of producing useful tools that other developers can use to solve similar problems to the ones they are facing. Now that git and GitHub have become the de facto version control system of choice, open source practices are becoming more and more common in-house. Netflix is a good example of an organisation that follows this philosophy. Sharing useful and, above all, battle-tested code as libraries encourages other developers to solve similar problems in similar ways yet leaves the door open to picking a different approach, if required. For the microservice community, overheads are particularly unattractive. Having said that, it doesn't mean that service contracts are not valued. Rather, there tend to be many more of them. It's just that they are looking at different ways of managing those contracts. These aid service contracts in evolving independently. Executing consumer-driven contracts as part of your build increases confidence and provides fast feedback on whether your services are functioning. Indeed we know of a team in Australia who drive the build of new services with consumer-driven contracts. They use simple tools that allow them to define the contract for service. This becomes part of the automated build before code for the new service is even written.
  • Decentralized Data Management - At the most abstract level, decentralization of data management means that the conceptual model of the world will differ between systems. This is a common issue when integrating across a large enterprise, the sales view of a customer will differ from the support view. Some things that are called customers in the sales view may not appear at all in the support view. Those that do may have different attributes and (worse) common attributes with subtly different semantics. This issue is common between applications, but can also occur within applications, particular when that application is divided into separate components. A useful way of thinking about this is Domain-Driven Design. DDD divides a complex domain up into multiple bounded contexts and maps out the relationships between them. This process is useful for both monolithic and microservice architectures, but there is a natural correlation between service and context boundaries that helps clarify, and as we describe in the section on business capabilities, reinforce the separations. As well as decentralizing decisions about conceptual models, microservices also decentralize data storage decisions. While monolithic applications prefer a single logical database for persistent data, enterprises often prefer a single database across a range of applications - many of these decisions driven through vendor's commercial models around licensing. Microservices prefer letting each service manage its own database, either different instances of the same database technology, or entirely different database systems - an approach called Ploygot Persistence. Decentralizing responsibility for data across microservices has implications for managing updates. The common approach to dealing with updates has been to use transactions to guarantee consistency when updating multiple resources. This approach is often used within monoliths. Using transactions like this helps with consistency, but imposes significant temporal coupling, which is problematic across multiple services. Distributed transactions are notoriously difficult to implement and as a consequence microservice architectures emphasize transactionless coordination between services.
  • Infrastructure Automation - The evolution of the cloud and AWS, in particular, has reduced the operational complexity of the building, deploying and operating microservices. Many of the products or systems being built with microservices are being built by teams with extensive experience of Continuous Delivery. To maximize confidence that the software is working, lots of automated tests are executed.
  • Design for failure - Applications need to be designed so that they can tolerate the failure of services. Any service call could fail due to the unavailability of the supplier, the client has to respond to this as gracefully as possible. This is a disadvantage compared to a monolithic design as it introduces additional complexity to handle it. The consequence is that microservice teams constantly reflect on how service failures affect the user experience. Since services can fail at any time, it's important to be able to detect the failures quickly and, if possible, automatically restore service. Microservice applications put a lot of emphasis on real-time monitoring of the application, checking both architectural elements (how many requests per second is the database getting) and business relevant metrics (such as how many orders per minute are received). Semantic monitoring can provide an early warning system of something going wrong that triggers development teams to follow up and investigate. Monitoring is vital to spot bad emergent behavior quickly so it can be fixed. Microservice teams would expect to see sophisticated monitoring and logging setups for each individual service such as dashboards showing up/down status and a variety of operational and business relevant metrics. Details on circuit breaker status, current throughput and latency are other examples we often encounter.
  • Evolutionary design - Following principles should be considered:
  1. Service decomposition should be used as a further tool to enable application developers to control changes in their application without slowing down change
  2. While breaking down, consider independent replacement and upgradeability of the new component - component should be rewritten without affecting its collaborators
  3. Keep things that change at the same time in the same module. Parts of a system that changes rarely should be in different services to those that are currently undergoing lots of churns. If you find yourself repeatedly changing two services together, that's a sign that they should be merged.
  4. Putting components into services adds an opportunity for more granular release planning

The difference - Microservices (MSA) vs SOA:

No alt text provided for this image
  • Intent: In both architectures, services can be developed using different technologies, tools and languages which aids in developing technological diversity within teams. Though multiple teams can contribute to development, SOA mandates teams to know about common communication mechanism (ESB). On the contrary, MSA services operate and are deployed independently of other services which help in scalability and maintenance.
  • Methodology: MSA focuses on minimized sharing through the coupling of a component and its data as a single unit with minimal dependencies. This coupling is known as a bounded context. Whereas, SOA encourages sharing of components and relies on multiple services to fulfil a business request. This cases SOA to be slower than MSA based applications.
  • Communication: In SOA, since each service is communicating through ESB, ESB acts as a likely candidate for a single point of failure which might bring the entire application to halt. e.g. if one of the services is slow in responding to requests, the ESB might be clogged with requests for the service. On the contrary, microservices provide better error tolerance. e.g. if one of the services has issues such as slowness, memory failure, then only that microservice would be affected and others would continue to handle requests.
  • Protocols: While SOA allows the use of multiple heterogeneous protocols through its middleware messaging component (ESB), MSA simplifies the same by reducing the choices for integration.

Conclusion: Hence, the purpose of the application determines the best-suited architecture. Where SOA is best suited for larger, complex enterprise application environments that require integration with many other applications. MSA is better suited for smaller and well-partitioned, web-based systems, mobile or web applications.

References: Martin Flower (Article on Microservices), DZone

Note: The Microservice section of the blog may be further shortened which would be done in next cycle.






Gowtham V Bhat

SDE @ MyShubhLife

1 年

Wow, this is so clearly skimmed off from the Martin Fowler's Microservices blog

要查看或添加评论,请登录

Anuj Agarwal的更多文章

社区洞察

其他会员也浏览了