Why Polyglot Microservices?

A microservice architecture is not required to facilitate a variety of languages and stacks for service implementation. In fact, the majority of microservice implementations seem to stick with a fairly uniform service framework. Let's be honest, it's a sane strategy. Too much technology sprawl can get complicated quickly. However, this is a brief summary of my thoughts on why you may want to embrace the idea that microservice architecture should encourage (or at least support) polyglot implementation.

Scaling out

Scaling out or scaling horizontally means that increasing performance is achieved by adding replicas of a unit, rather than expanding the capabilities of a single unit - which is commonly labeled scaling up or scaling vertically. Scaling out is a central theme in microservice architecture. But it is not just about scaling services, it is also about scaling out people.

With emphasis on service autonomy and loose coupling, project sub-teams that are aligned with individual microservices can also become less coupled to each other, or even downright disconnected. The idea of detached teams may sound undesirable, like the classic "silo" - we have been trained to recognize this as unhealthy - but maybe not. While it is possible to keep a dozen developers closely aligned and on the same page, scale to a hundred developers, and frequent, thorough communication becomes challenging and creates overhead. Jeff Bezos at Amazon, coined the 'two pizza rule', which states that two pizza's should be enough to feed a developer team. You'll find that this notion is enthusiastically supported by experts, but it is important to remember that it's not just the size of the team, it is how disconnected they can be from each other and still function together effectively.

Again, we come back to the idea of scaling out instead of up. If teams can work on pieces of an application independently without requiring significant inter-team coordination, then organizations can add more teams, rather than augment existing teams. This helps existing teams maintain delivery velocity, and allows new teams some freedom to make independent choices given specific contexts... a different language, perhaps? Hmmm.

Pitfalls

So let's say an organization has a group of Java developers, a handful of DBAs, and some quality assurance engineers. Perfect, right? Three smaller teams, instead of one big one!

Not exactly.

Of course, organizations have been slicing their engineering teams this way for decades, and it can work, but there's something missing. The three teams, in this case, need to work together on just about any deliverable. The problem is, an application is more than likely coupled to its datastore, and integration tests are tightly aligned to application APIs. This is exactly how we create the unhealthy silos referenced earlier. The three teams must work in close coordination with each other. Introducing barriers to inter-team communication is highly disruptive to delivery.

Or how about this... One team is responsible for authorization concerns, and another team is comprised of skilled data modelers. Both of these teams work toward producing Maven artifacts to be imported uniformly by every microservice. This is much closer, right? The two teams are aligned around a domain, and they can work independently.

Better, not optimal.

Consider deployment. Every time there's a change to a model or an authorization technique, every microservice must be rebuilt and released. Those wonderful, small, independent releases just became monolithic. Sure the teams are aligned around technical domains, but the service architecture does not encapsulate those domains with services.

Vertical slices FTW

Microservices generally represent a full technology stack. It can be tempting to segment both services and teams to align with the layers of the stack, e.g. Java developers on one team, DBAs on another, but in reality, in order for services to be loosely coupled, they must be segmented into domains, rather than layers.

So to revisit the authorization pitfall example, perhaps authorization is truly a vertical slice, aligned to a specific business concern, or domain. In the previous example, this was delivered as a Jar with a Java API. It could be a microservice, if it is designed as a full-stack service with an API that is exposed over a network transport like HTTP, for example. With that design in mind, it is possible to align a team with this service. Note that team members would likely include individuals with a variety of skill sets - a couple developers, a DBA, QA resources, etc. Here is the upside: as long as other services that consume the authorization service adhere to the service API, the team can deploy non-contract-breaking changes at any time.

What does this have to do with polyglot?

It's not that a polyglot microservices implementation is going to make things better in and of itself. I see it as more a a litmus test. Could you deploy any one of your microservices with a completely different stack?

I notice an awful lot of organizations creating a "common" library for their microservices, which creates a sense of governance - build the solution once with an approved implementation, and reuse it. This can be an effective strategy, but it complicates the deployment pipeline. When the common library has to change, the whole application must be re-deployed. When services vary in their implementation, the common library approach becomes much less appealing. Each service team is forced to focus on exactly what their service needs, instead of developing a one-size-fits-all solutions to common problems.

Finally, the most important point, though; heavy top-down governance over service implementation squelches developer creativity. If services are truly decoupled from each other, the underlying implementation should not matter. Empowering teams to make unilateral choices about what technologies are most effective in the context of a specific microservice not only leads to efficient services, but also efficient development of services. As a side note, developer morale is easier to stimulate when critical thought is involved in day-to-day work and every problem isn't already "solved" by an architecture committee.

Conclusion

An application composed with microservices certainly does not have to be a collection wildly varied stacks, but it is valid to consider major barriers to polyglot implementation. When many teams are each working on independent components of an application they should be enabled to make unique implementation choices without major coordination and consensus across all teams. Autonomy is not only a desirable characteristic of a microservice itself, but also the team developing the microservice, because autonomy enables horizontal scale and independent life-cycles.

comments powered by Disqus