Many organizations say they are moving to microservices, but Gartner says that by the end of 2019, 90 percent of them will think microservices are too disruptive and switch to other methods, such as miniservices. In the meantime, enterprises are looking at how to transition away from monolithic apps, not knowing that microservices may not – after all – be the answer to all their problems. A lot of people do not truly realize what the move to microservices implies. There is also some confusion around the true definition of microservices: While having APIs is necessary, it is far from enough.
So are microservices are a bad idea? Not necessarily, but like most new technology concepts, a one-size-fits-all approach does not work. For some organizations, microservices are a good fit and enable the agility that modern software development needs. Others may fare better with alternative ways to escape the unwieldy monolith. As well as microservices, both macroservices and miniservices are now on the table, together with hybrid strategies, and all underpinned by DevOps, of course.
Crucial to knowing what route to take is the right approach to adapting the organizational structure, those processes and cultural attitudes that are – as is always the case with new software methodologies – essential to eventual success. More on that later, but first, let’s remind ourselves where we’ve come from and what is possible today.
Back in the day, we only had monolithic structures. These big single systems typically focused on just one application. In a web application, there would be a web server intercepting requests from users, and those requests would be handed off to an application server that wrapped business logic responsible for interacting with a database (usually relational) in the backend. Everything needed for the UI, the business logic, and database access would be contained in the single app.
Monoliths have pros and cons. There are fewer moving parts to worry about; in theory everyone is on the same schedule, and everything is released at the same time. However, making that work well requires a lot of coordination. Releases are slow and one change will ripple throughout the entire app. Agile and DevOps can contribute to better monolithic management, as do technology approaches such as REST APIs, but at some point, teams inevitably wish for a more flexible way of working.
Enter microservices. These are very small parts that each do their own thing, perhaps differently using different technologies, speeds, approaches, languages, and so on. Each microservice does only one thing and it does it very well. In theory, microservices are easy to scale independently.
An example of microservices in action might be an ecommerce app for online checkout, involving pricing, a shipping calculator, and inventory all working together to support that checkout process. Imagine it is the Christmas period and the site is being overwhelmed by inquiries from one zip code. It is relatively simple to spin up a new instance of one microservice to handle that additional load, compared to a monolithic structure where it would be necessary to spin up another instance of the entire application, wasting time and resources. If one microservice fails in production, the others are still running. Microservices can be replaced easily, which is a bonus for when the next better way to build the mousetrap comes along.
On the downside, the degree of coordination effort can rise dramatically. Managing all those moving parts becomes hard, particularly if there are lots of teams involved and they may be geographically dispersed, using different technologies, tools, languages, and processes. Microservices need constant monitoring and seeing the big picture – let alone keeping control of it – is a challenge.
While they exist independently and move at their own pace, using different third-party components, changing their own APIs, those hundreds of microservices make up the same app and so there are dependencies. To work well, one microservice might depend on two or three doing their job well, and in turn, those depend on the efficiency of other microservices. So, when a version changes, there needs to be a way to notify dependent microservice teams, without creating a lock-step situation, which would negate the inherent flexibility of microservices. Furthermore, each microservice will have to support older versions of its interface. This is why service meshes have become popular, as a means to overcome ‘one by one’ prevention of inconsistencies.
Even so, microservices mean disruption on a scale that can lead to chaos, hence the concerns of some industry experts. Plus, a wholesale move to microservices may not be the best approach – or even necessary – for many organizations. There are other options that fall somewhere between the two ends of the spectrum, one of which is macroservices, where some of the functionality in monolithic apps are re-used in other apps.
The benefits of macroservices are that these recycled chunks are already proven to work, they are understood, time-to-market is reduced (compared to microservices), and the risk is lower. On the negative side, macroservices can bring baked-in assumptions. The code may not be easy to read, it could be hard to tease out a usable public API, and testing and scaling is hard. Consider the Strangler pattern (from Martin Fowler, back in 2004) to slowly and safely migrate from a monolith or macroservice to a more granular approach, such as microservices.
Miniservices is another approach, where two or three share the same database (unlike microservices, which each have their own dedicated data storage). While essentially independent, miniservices do need to be coordinated when, for example, upgrading schemas used in data storage. Business value is prioritized over architectural purity, with a reduced culture shock compared to microservices.
The downside to miniservices is the risk of a miniservices ‘creep’. After one service shares a data store with another, teams may be tempted to add more and more. It is also tempting to add APIs and features to existing miniservices, bloating them over time until they resemble macroservices and monoliths. It takes no small measure of discipline to avoid these risks. This is why architects and team leaders should strive to keep miniservices as small and focused as possible, even when it is easier and faster to tack something onto an existing service.
However, regardless of whether adopting macro, micro, or miniservices, the impact on the culture of software development is massive, much more than the effort involved in Agile or DevOps adoption. Rolling out any of them without addressing team structure and responsibilities is a recipe for disaster. Failure might be blamed on microservices, whereas the real culprit is a development software culture that does not fit the new way of working.
If an organization is moving from one hierarchical managed team of a hundred people to 20 teams of 5 people each, that is a very different corporate reporting structure. Making sure that projects are executed efficiently and that it is possible to keep track of everything, compared to being overly prescriptive and forcing teams to use only certain tools, is a big challenge. Top-down understanding and support of that new culture is critical to any chance of success.
Taking a hybrid approach works well. It can be tempting to have one big move away from monolithic to micro/mini/macroservices and get the hard work out of the way. For some organizations, that may be fine, but a more incremental approach is often better. For instance, transitioning the parts of an app that change most frequently and hence will benefit from the additional flexibility. By starting with just a couple of teams, an organization can gain experience and learn what does or does not work before investing more heavily or committing to one direction.
Making sure that the right kind of tools are underpinning the new way of working is another best-practice step. Whether macro-, micro-, or miniservices, the application will likely expose far more public APIs than ever before. This situation cries out for API management. Good API management solutions provide a single point of entry, with security and reporting, policy enforcement, auditing, protocol translation, data transformation, orchestration, analytics, and traffic management. Some people think that microservices means not needing API management, whereas the opposite is true.
As the number of services climbs, the need for consistent security and reporting becomes increasingly important. The last thing an organization needs is every microservice team rolling out its own security. This means choosing a standard API management solution that is shared by all teams is critical for overall mission success. Likewise, teams need to standardize on a scalable version control system and high-level repository structure. Ideally, they would also share at least the same philosophy, if not the same tools, for CI/CD, automated testing, container management, and service monitoring, all of which are the essential tools of a successful agile and DevOps culture.
With dozens or hundreds of services all changing at their own pace, complete DevOps automation is no longer nice to have: it is vital. The more things that are similar across teams, the easier it is to have team members move around, thus improving overall system understanding and organizational resilience. Consider this: what happens when only one team uses an off-the-beaten-path language and toolset, then leaves the company? Rather than enforce a rigid and restrictive set of tools on the team, be prepared to deal with departures and technological dead-ends. Finally, a service mesh solution can do wonders to improve consistency, reliability, security, and monitoring for large microservice deployments.
Addressing these cultural challenges is as important as the supporting toolsets. Multigrain services – whether macro, micro or mini – give organizations far greater flexibility compared to traditional monoliths. The key to successful implementation is to appreciate and address the risks that this flexibility may bring.