Microservices: Organizational practices
In a cloud environment microservices are often the architectural style of choice. This is primarily due to the many benefits associated with microservices as compared to a more traditional monolithic architecture. In this article we will firstly look at the primary benefits of deploying microservices. In the second part of the article we will familiarize ourselves with the Westrum culture model and learn how the culture of a company itself may impose significant challenges on any technical transition undertaken as part of a modernization drive. Lastly, we will show how to use Conway’s law to our advantage, when transforming the monolith towards the use of finer grained services. We roundup the article with a recommendation on how changes in the deployment of DevOps can have a significant impact on process improvement.
The (many) benefits of microservices
Moving forward, it is important to keep in mind that the use of microservices is no silver bullet — in fact — many companies have struggled when trying to rework their applications towards the use of microservices.
Independent release cycle
Firstly, microservices (as individual parts of our software) have an independent lifecycle. This means that each and every service is improved upon and released (in a backward compatible manner) without extensive communication between teams. Fortunately, due to the nature of microservices there is a guarantee that the majority of changes will not negatively affect other components across the system. This is possible because microservices always communicate through an API — and if the existing API does not change, the change is compatible with all other existing clients.
From a time-to-market standpoint this implies reduced mean time to delivery, because multiple unrelated changes in multiple modules do not need to wait for one big (and risky) deployment, each change can be deployed individually as part of the continuous delivery process. Utilization of microservices also reduces the mean time to recovery, as (if there is a bug in the solution) the team is able to deploy a new version swiftly, with only testing of the affected component being required.
Seamless horizontal scaling
Secondly, microservices can be easily scaled horizontally, because they are (generally) stateless — there is no state (cache, session) bound to an individual instance. Adding capacity to the pool is usually as simple as adding a new microservice instance behind your Load Balancer or queue.
The benefits of such a flexible deployment are quite clear: in the case that there is a surge in requests, the application can be easily automated to scale up. If the application is not utilized enough, it can scale down (and therefore reduce operating costs).
Team scaling
In many cases what is more important than the horizontal scaling of components is the scaling of the company itself. That means an increase in the number of teams that can work independently. An increase in the number of teams working on a component cannot be done easily with monolithic architecture as its quite hard for a new programmers to be brought up to speed, because they must grapple with complex modules, tangled by years of development.
Microservices, on the other hand, are designed to be rather small (for one dedicated team) and targeted at one business concept (such as user management). With this type of product it is quite easy to onboard a new member, as he needs to gain experience only in a limited subdomain of the service itself. The new team member is able to get acquainted with the complexities of the system gradually.
Also, there is no longer the obligation to use the same technology throughout the entire system, as the modules are isolated by APIs. Technically speaking the system may be written using a variety of frameworks or languages (which may ease the spinning up of new teams). Nevertheless, this approach should be taken with caution, as the utilization of additional technologies also means that the company needs to have either more universal/polyglot programmers or simply more experts in general. Of course, there are also crosscutting concerns such as logging, security, and deployment, which require additional attention and implementation if there are various frameworks or languages used across the system.
Resiliency
Microservice architecture, when implemented correctly, is very resilient to hardware malfunctions. This is a very important quality, as microservices are usually deployed on cheap commodity hardware — and when an installation contains 30 microservices, each deployed in 3 instances, it is very probable that the underlying hardware will fail from time to time.
Running on hardware which is likely to fail may not seem beneficial at first glance, but it is! It’s much cheaper to buy capacity on commodity hardware in the cloud (and to be able to handle it) than to try to achieve four nines availability with ones own DC running on high-end machines.
Work culture & organization
Now that we have been introduced to the benefit of microservices in the cloud let’s dive into the next topic — company culture. The importance of the organization of the work itself cannot be overstated, as it often predetermines if any change will be successful or not. On the other hand, if we are able to address possible issues before we start, we can improve our chances of success quite significantly.
Westrum culture model
First of all, let’s get acquainted with the Westrum culture model. While the model is not specific to the development of microservices, understanding the state of the company is very helpful when implementing any change. According to an excellent book Accelerate (Forsgren et al.) the Westrum Culture model can be used to predict software delivery performance of the team.
(Source: Accelerate)
Implications for microservice transition
If we apply the Westrum model to changes in the architecture and our shift towards the use of microservices, we do not want to be in a company with a Pathological Culture, because one thing is certain — there will be major challenges along the way. If this is the case, then it is likely that negativity within the team will lead to apathy or staff attrition (people will stop trying, or will quit). There is no real advice that can be provided in this situation, but if change is required and the company culture falls within the realm of Pathological, the team should have a dedicated stakeholder who is able to shield it from the rest of the company …and protection will be needed. Generally speaking, a pathological work environment is not suitable for any change (let alone a major shift in architectural design), as there is a significant chance that it will be a painful experience for everyone involved, if not an outright failure.
On a positive note, if the company has a Generative Culture, we can be sure that when the team will hit the wall (and it will happen, many times), the company will be capable of helping the team to overcome the hurdle and move forward. The only consequence will be new knowledge and experience.
If the company has a Bureaucratic Culture, we can mitigate some of the issues through the application of the Inverse Conway’s maneuver.
Conway’s law
Let’s first discuss Conway’s law, which is an observation published in 1967 by Melvin Conway. It states that:
Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure.
This basically means that the architecture of our system will always resemble the organizational structure of our company. The reasoning behind this is quite simply the result of the fact that when a team is assigned a task to implement a component of the software, it needs to cooperate with other teams. As an example — whenever the team reaches the boundary of some other component maintained by another team, the engineers need to agree on a stable communication protocol between these components and they create APIs.
We can also use other side of the law, the so called Inverse Conway maneuver. When employing this technique, we restructure the company in a way that stimulates the creation of the desired communication channels.
In our case we want to strengthen the communication between engineers working on the same business features (from database to APIs), hence we put these engineers in the same team. Within the restructured team strong communication occurs internally, there are no longer strong APIs on the technological level (between business logic and database for example), instead these APIs will appear on the boundary of the team. So we end up with REST (or similar) APIs encapsulating the business subdomain. Which are, coincidentally, microservices.
We want the team to be responsible for the full release cycle, as this bolsters the shared responsibility for the component. It is no longer possible to say that “it was developed/tested/deployed incorrectly”, when the whole team owns all these activities. There is now no need to find the culprit, now it’s more important to find the root cause.
Taking the next step
These implication of restructuring the team and improving internal communication not only lead to the development of well designed and tested microservices, they also lead us to the logical outcome that the strongest cross-functional team conforms to the DevOps model.
Why DevOps is important for microservices
Apart from the improvement of communication channels, cross-functional teams are also far more effective when it comes to the software development lifecycle. Here, it is important to remember that in the world of microservices, this cycle does not happen only once, it happens dozens of times (each time a new service is introduced). For teams with a traditional layout, where developers only do the programming work, it is common that they need to create a support ticket to:
- Create a Git repository
- Create a pipeline in continuous integration system
- Create a project in bug tracker
- Provision machines for testing
- Create a deployment pipeline
- Deploy a new version to production
With this modus operandi the team can easily spend more time waiting for others than actually working.
Implementing DevOps
Dev-Ops axis
DevOps teams mitigate this issue by being able to act as both development and operations teams at once. One way to augment a traditional team is (if development and operations are separate entities) by inserting one operations engineer into each development team. This dedicated engineer should support the team during the setup phase (points 1–5) and supports the team with the deployment of automation (continuous delivery) and monitoring of the system in production. While initially there is limited overlap between the work done by developers and the operations engineer, the ultimate goal should be to create some redundancy of knowledge in the team. This means that each member of the team should eventually be able to set up a new project and maintain the service in production, while the operations engineer should be able to work on features with developers.
This does not mean that everyone in the team will be top-class developers or top-class operations engineers — on the other hand the developers will be able to spin up new projects and they will know how to to maintain the production environment (and debug issues, if things go sour). In this scenario the skilled operations engineer will be able to provide feedback to code during development, making sure that potential issues are cleaned from the code early on.
Vertical axis
These newly created teams should be given responsibility for some subdomain (vertical cut) of the product. This may be, depending on your product, something like Customer Management, Parcels or Delivery scheduling. Being responsible for the vertical cut puts your development team in the position of being domain experts in the subdomain and stimulates the creation of microservices.
Conclusion
In this article we have described the advantages of microservices from the point of view of the organization: fast releases, reduced mean time to recovery, resources/costs savings (using autoscaling and cheaper hardware), as well as easier growth and onboarding within the company itself. We have also shown how we can use the inverse Conway maneuver to stimulate proper communication channels within the company — those which lead to fine grained and reliable services. While ensuring that all processes are managed by self-sufficient DevOps teams.