There is a lot of confusion about what microservices are, what service oriented architectures are, and how they relate to each other. Everyone from Martin Fowler to Steve Jones is weighing in on the subject.
What are Microservices?
Microservices are an architectural design pattern. In a microservice architecture, business logic is decomposed into a collection of small, loosely coupled, distributed components that collectively form the larger application. Each component is called a microservice and each microservice performs a single task or function in the collective whole. Each microservice may be called by one or more of the other microservices to perform specific tasks needed by the larger application; this provides a uniform way of handling things like search or displaying images or other tasks that might be needed multiple times and limits the need to develop or maintain multiple versions of the same bit of functionality in different places within the application.
Using a microservice architecture also provides a mechanism to increase the productivity of new developers and decrease the time to market of new features. Each microservice has a limited code base and associated toolset; developers no longer need to understand gigantic, complex systems before becoming productive, they only need to understand the subset pertinent to the microservice they work on. Microservices can be developed quickly because they can use the languages and toolsets best suited to the task at hand without worrying about what existing portions of the application already uses or whether other developers in the larger system know those languages and tools.
To fully take advantage of the speed to market possible from a small team, that team needs autonomy; they have to be able to make decisions quickly and without much oversight. To support this, working teams should include all of the relevant people from product management through release and operations. Because microservice components are loosely coupled and communicate via APIs, a high level of autonomy for most decisions does not affect the function of the application as a whole. As long as the microservice publishes its APIs and performs the function it advertises within those APIs, the system as a whole functions well.
Because there are so many independent components in a microservices architecture, using modern DevOps on an elastic network like a public or private cloud becomes important to ensure smooth operations of the system as a whole in most cases. In particular, things like automated monitoring of health and load in conjunction with automated deployment of additional instances (and to a lesser extend drawdown of underused instances) become vital in many cases.
What is SOA?
SOA, or service-oriented architecture, is a mechanism for integrating multiple larger components, typically applications, together so they form an interoperable suite. Each component typically performs a complete piece of business logic from start to finish, usually involving a variety of specific tasks and functions needed to complete an entire larger action. Components are typically loosely coupled but this is not a requirement of the SOA architecture patterns.
Although not a strict requirement, SOA typically uses some type of centralized governance – a review board, a head architect or architecture council, – to tightly define what each component of the system should do and how it should do it. The same type of functionality may be defined and written separately in multiple components if needed within each and the languages and toolsets used by components may or may not be centrally determined and uniform. SOA can use any type of SDLC, organizational structure, or development model consistent with this type of governance; agile, waterfall, kanban, or some combination are all possible without violating SOA tenets.
Further, while modern DevOps and cloud deployment are certainly useful for SOA, they are not essential requirements given the smaller number of components in use within this type of system. However, some of the larger components in these systems may be sufficiently complex that automation is at best difficult, and completely impractical at worst.
For example, one criteria for an automated deployment might be passing a suite of automated tests at 100%. This ensures that existing functionality still works in the new version (there are no regressions) and that new functionality works as expected. As more and more features interact, the likelihood of accidentally breaking some facet of an existing feature with seemingly unrelated development work increases.
Further, some of the tests might be brittle and fail a small percentage of the time because of environmental or network issues. When there are a hundred tests, having 5% of tests randomly fail 1% of the time isn’t a big impediment to regular releases. When there are many thousands of tests, the same percentages have a much bigger impact, causing at least one random failure a significant portion of the time. Thus, even if nothing is actually wrong with the release candidate it will often fail the criteria for deployment.
Direct Comparison – Building a Shopping Cart
Let’s look at an online shopping site. This site would have a handful of different features – a product catalog, user accounts, and shopping carts to name a few.
A development organization using SOA would typically break the shopping site up into major sets of business logic and develop each as a separate application to be integrated together.
For example, the entire shopping cart and all of its functionality would be one application developed by a large group of people who all need to know how the entire cart works in order to modify it. Within that application is code to do things like display items, add and remove items from the cart, check inventory, handle shipping options, handle tax calculation, handle billing, update the display when something changes, and email the final order details to the user (among other things). The code used to display products within the shopping cart is within the shopping cart application and may be completely different from the code used to display product items within a browse catalog view, resulting in two sets of similar but different code to maintain and also possibly some inconsistencies in the larger application UX.
An organization using a microservices architecture would take that shopping cart and break it up into smaller task-oriented services. Instead of a shopping cart application there might be a tax calculation service, an add/remove item service, a shipping service, a billing service, and a compose final order service. The shopping cart functionality may also use some common services used in a multitude of places within the shopping application such as a display item service, a display product image service, a check inventory service, a user payment preferences service, and an email service – there is no boundary around “shopping cart” vs “product catalog” vs “user account” and common code is encapsulated into various services and used by all of those features as needed.
At some point your company decides to license product images from a central licensing organization. The source of images must be changed and statistics around views must be added to the larger shopping application. In the SOA architecture, both the product catalog application and the shopping cart application must be independently updated to reflect these changes.
Both applications would then need to be retested to ensure the changes didn’t affect any other functionality and then redeployed, a process that may be delayed further (depending on the development processes in place) if other features within either or both applications are in the process of being modified and are not in a releasable state. Once redeployed, it might become apparent that the new mechanism for serving images is slower than the old one and is now a bottleneck.
The slowdown is found by customer complaints and reported to management. Someone makes the decision to solve it by deploying additional instances of the entire product catalog application and of the shopping cart to handle the extra load (this could be automated if proper monitoring and deployment rules are in place). The whole process requires great deal of additional processing power and storage space since the entire applications would need to be scaled up, including a lot of features that were probably functioning just fine without the additional deployments.
In the microservices world, only one change would be necessary – an update to the display product image service. This service can be quickly modified, tested, and deployed on its own without affecting any other portion of the larger system. Further, when the bottleneck is discovered (most likely through automated monitoring), additional instances of this service can be deployed (probably automatically) without deploying more instances of the rest of the services used by the product catalog features or the shopping cart services, limiting the additional resources needed to support the increased deployment.
All of the above assumes you’re trying to launch a larger online store selling a variety of products to a variety of people in a variety of locations. Suppose you just want to sell just one product just to customers within the continental United States using UPS as your only shipper. A lot of the infrastructure and complexity of a real online store is unnecessary.
You still need to track user information, provide a shopping cart and checkout functionality, and have a page with product information, images, and perhaps even a few reviews or testimonials but each of these requires a lot less functionality than their counterparts in a more diverse online store. Gone is the need to categorize products, the need to figure out different shipping options, the need to handle adding and removing skews from the system, and all sorts of other features that a full multi-product store needs.
In this case, using SOA with a shopping cart, user account, and product display components integrated into the rest of your website might make more sense than using a microservices architecture with more granular components as defined above. Not only is each larger component reduced to a manageable level of complexity in this simpler set up, but the number of developers and other staff needed to implement this type of site is small enough to invalidate the need to scale via small, independent teams.
Similar But Different
So microservices and SOA have a lot in common. They are both systems that typically contain sets of loosely coupled distributed components. However, the intention behind the two architectures is very different: SOA is trying to integrate applications and typically uses a central governance model to ensure that applications can interoperate. Microservices is trying to deploy new features and scale development organizations quickly and efficiently. It focuses on decentralization of governance, code reuse, and automation to do this.
Which one is right for your organization? That’s up to you to decide.
On January 27, Datawire will host the Microservices Practitioner Livestream, bringing leading early adopters (developers, architects, and practitioners) together to share their lessons learned and best practices. Speakers include Uber, Yelp, Netflix, Hubspot and more. You can register at www.microservices.com.