This post is the second in a multipart series exploring the basics of microservices. Check back each Monday for additional installments.
Cloud-native microservices are a truly exciting architectural evolution, especially when it comes to building, deploying and managing complex distributed solutions. Most of the talk around microservices, however, goes straight to the technology: continuous integration and deployment, containers, orchestrators and so on. Important stuff, but there’s something else to consider as well:
Once your organization has made the decision that microservices are the right architecture for your project, those with experience implementing them emphasize that it’s just as important to ask: Are we the right organization for a microservices architecture?
You Must Be This Tall to Ride Microservices
Evaluating cloud-native microservices for enterprise adoption has less to do with a company’s size, sector, or even the actual technology than with the enterprise itself, experts say.
Jamie Dobson, co-founder and CEO of Container Solutions, believes that successful implementation of the architecture depends, to a surprising degree, upon an enterprise’s culture and internal processes. “Clients come to us looking to use microservices as a solution to a technological problem,” he said. “In reality, it is often a technological solution to an organizational problem.”
The fundamental complexity of microservices, he went on to explain, is in the architecture itself, not the computers. And not every company is in the right place to make the move. “The enterprises are full of intelligent and creative executives who are keen to go to microservices, in part because Google and Netflix and all are doing it. And the benefits are real. But it’s just difficult to get your head around microservices themselves, as well as the organizational shift a cloud migration requires,” he said. “Bringing in that understanding is when a good professional services company — focused on cloud migration and vendor neutral — becomes invaluable.”
There are some scenarios that can indicate a company may face particular challenges when contemplating a microservices move. Not that adopting the architecture becomes impossible, experts stress — just that the process will be lengthier or more complicated.
So when might an enterprise not be a good fit for microservices?
- Sector sensitivities: Certain industries, for example, financial services and healthcare, face legal, reporting and compliance requirements that need to be reconciled with newer technology — or simply may not yet have caught up at all.
- The venerability factor: A global company in business for decades, especially one with an average workforce retention of ten-plus years, will very likely have a harder time navigating the seismic shift to a completely new architecture than will a younger, more compact, or simply more agile organization.
- “Stuck” companies: Dobson described a “stuck” company culture i.e., risk-averse, with a long decision-making chain and rigid hierarchy. Ultimately an organization not well suited, and possibly even resistant, to the rapid adaptation required when adopting a new and responsive microservices paradigm.
“An enterprise’s inherent structure and organization will significantly influence the choices made, and hence the ability to transform into a microservices-favorable environment,” Dobson said.
Are Microservices Indeed the Best Fit?
Once your company is ready to roll, how can you assess whether your particular application will indeed actively benefit from the many advantages of microservices?
Currently CTO at Netlify, David Calavera previously worked with microservices architecture at Docker and GitHub and is as close as one can get to being a veteran with such a new technology. According to Calavera, the first step is to evaluate how many responsibilities the application has, or will have. Next comes determining how interconnected these responsibilities are with each other.
“The best metric to evaluate how interconnected your application’s components are is called Connascence,” said Calavera. Two or more components are said to be connascent if, when you change one of them, you also have to change the other.
“With this relationship in mind, you can better evaluate if it’s worth having different microservices, or you should keep your monolith architecture,” Calavera explained. Additionally, he said, teams must bear in mind that separating these components into microservices will introduce a network connection between them — which inevitably adds complexity to the system.
“You don’t want to end up adding unnecessary complexity at the cost of an ideal architecture,” cautioned Calavera, pointing to the wisdom of his colleague Dave Cheney:
Microservices, for when function calls are too reliable.
— Dave Cheney (@davecheney) February 25, 2018
Ready, Steady… Go?
Having determined that your organization itself is a good fit for the shift to microservices, and that your project or service will benefit from the architecture, one question is left: how do you determine whether you are actively equipped to build applications this way?
The critical question to consider, according to Calavera, is whether your team is ready to handle the extra complexity of having several services running in production, rather than only one. “This complexity will affect all of the processes your team is used to — from the way you organize your code in your favorite version control system, to the way you deploy your application, to the way you observe and monitor its behavior in production,” he said.
Once you have identified and assessed each one of the processes involved in the development, testing and maintenance of your production service and have specific answers prepared for adapting or replacing them, Calavera concluded, “You can start to consider yourself ready.”
Preparation for Takeoff
The best transition possible is the one that is never noticed by users. Beyond an honest assessment of existing capabilities, what else can a team do to best prepare for the smoothest possible progress to a successful migration?
Ultimately, not all that much, experts agree: there are simply too many variables.
“Unfortunately, it’s very hard to be ready for all possible scenarios. This is especially true when we talk about distributed systems interconnected through a network,” said Calavera. Thus, microservices migrations are always planned to take place in stages.
“For safety and security reasons, it’s never advisable to jump all the way in to microservices — when transitioning to a different architecture, always remember that keeping the full service up and running is your first priority,” said Calavera.
The best approach to this transition is to find a balance between the safety and the effectiveness of this migration. This is also known as the efficiency–thoroughness trade-off (or ETTO ) principle.
“On one hand, we need to ensure that the transition is completely safe. Mistakes during the migration can be the source of terrible outages,” said Calavera. “On the other hand, no matter how much you plan this migration, the only way to know if it works is to expose it to the complexities of production.”
Fortunately, previous pilgrims have helped prepare the path, chief among them Martin Fowler. There are several microservices architecture patterns, that combined together, help create a smooth process. Very briefly, these are:
The Circuit Breaker pattern: Circuit Breakers are very useful to abort code execution when something unexpected happens, for example when the network goes down and two microservices cannot communicate with each other.
“This pattern forces us to think about what to do in that scenario, and there are several libraries that implement this pattern in different languages,” said Calavera.
The Branch by Abstraction pattern: A technique for gradually undertaking a large-scale change to a software system, Branch by Abstraction allows you to release the system regularly while the change is still in-progress.
“This helps introduce alternative logic to perform an operation,” explained Calavera. ”In this case, the alternative logic could be to send a message to a microservice rather than using our current application’s logic.” There are several libraries that implement this pattern in different languages, including Go and Ruby.
The Feature Flag pattern: Also known as feature toggles, these give the ability to change the execution path within an application in real time. “We can implement a flag that allows us to send some traffic to our new microservice, but not all of it,” said Calavera. Again, multiple libraries exist that implement this pattern in different languages.
In order to observe the behavior of the system during transition, he added, “all the previously mentioned libraries have some kind of support to emit events, logs and metrics that we can feed to our favorite monitoring system.”
Best of all, the patterns can be combined to create a system that provides significant control over the transition to a microservice architecture. For example: by combining Branch by Abstraction with a Circuit Breaker, it becomes possible to implement a change that allows directing traffic to the new microservice — but if the circuit breaker gets tripped by an unexpected error, the system falls back to the old application logic.
The path is made by walking.
Next up: Time to roll up the sleeves and get to work. Part 3 of The New Stack’s Getting Started With Microservices series will get down to details on, well, getting started!