Microservices Dilemma - More is More
Less is greater than More in the Unix world but for the development world, more is more. Are your pipelines ready?
Along with cloud migration, serverless, and Kubernetes, microservices have been garnering attention from technology practitioners and leaders alike. One can argue that the breaking down or decomposing of applications have been going on for decades and is not a monumental shift in computing. There are several definitions of microservices from a purist definition to a definition resembling a movement. When building new applications, having a microservice architecture would be a design goal. Modernizing an application from days gone by you might be fighting an uphill battle to “microservice” an older application. With the technology ecosystem moving forward allowing for more rapid deployments, service discovery, and almost instantly available infrastructure, microservices are more evolutionary than revolutionary today. Microservices can certainly push the limits of your pipelines because of the velocity and independence needed to deploy successfully.
If you saw a microservice, would you know it’s a microservice?
After several sprints building your hard work, you are ready to show off your RESTFul endpoint to the world. This has to be a microservice right? Calling your endpoint by any other name would be mean and not being on the straight and narrow with a modern architecture trend would be shameful. Stringent definitions around microservices could include that your service is message-based aka MOM and communications should be facilitated by messaging patterns. You start to scratch your head about this messaging requirement and no one told you to have a microservice that you had to use messaging. If you took a look at a steller piece by Martin Fowler explaining microservice design patterns, a few of those design patterns start to stick out. The biggest piece for myself is around data governance. For a microservice, the data needs to be independent of other services. Taking that one click down, should not have overlapping data definitions if you make an update to the data structure in your service would not cause structural updates to dependent or calling services. Let’s say you were building in your sprints a weather application where you take in a zip code and give back the city name and weather. Also to make thing interesting need to log the requests for analytics. Your application most likely would not warrant the transactional support that a JAVA Message Service (JMS) provider/implementation provides. With our weather service, we can have a pretty simple schema or document structure. The user logging data can certainly stand alone. When digging into microservices, a going mantra is that to start to build services which are much more granular in scope or accomplish only a singular goal. The quintessential ecommerce microservices example would say that you have a service for your shopping cart, inventory, user management, and so on. Our weather service is starting to smell a lot more like a microservice.The Ravi litmus test would be “can you do this by yourself?”. At some point you will not be there on your project or organization. With the magnificent end point(s) you created, can that be deployed or updated without involving other development teams? Sounds like the weather service is pretty independent and provides a granular functionality to our end clients. Congratulations, you passed the microservice test! Let’s now go and toss everything we have into this new architectural paradigm.
Save me from (certain) hell, microservice!
The big allure of microservices is the flexibility to be freed from dependency hell. On the flip side of microservice architecture is monolithic architecture. Just as the name suggests, a monolith has one deployable unit with all the functionality needed. In the JAVA days, imagine a large WAR to deploy. Going back to an ecommerce example, all functionality such as shopping cart and inventory are deployed with this single ecommerce.WAR. Having to make a change in one functionality would require a deployment of the entire application. This can be risky and over-kill since making a seemingly small change requires the entire application to be re-deployed. Since the exposure for risk is so high, with monolithic architecture teams tend to deploy at a slower frequency. Thus the need for a better way to do deploy. One team who finishes functionality quicker than other teams don’t need to be in lock-step with the deployment. For newer applications most folks will think of ways to design for more independent deployments embracing smaller services.Creating new services are easier than ever. With advancements in how we compute e.g containers to the networking/discoverability stacks such as Service Mesh and API Gateway platforms, spinning up and wiring a service is easier than ever. With the advantages that a microservices design has, why are all of your applications not on the new paradigm?
Why are all my developers not microservicing?
The brass tax with microservices is that as dependency complexity is reduced, deployment complexity is increased. With smaller and more granular services, you will have more services. Thus, the number of deployments will increase. Martin Fowler is also famous for coining The Strangler Pattern where newer parts of the application stack will eventually kill out the older parts. Eventually with the amount of services exploding, would be very hard to keep track. An anti-pattern will start to show called Big Ball of Mud. With the Big Ball of Mud, endpoint hell starts to occur with new services just spinning up with no clear and concise design or management for the services. Several challenges start to pop up. With services being so granular, one service could call several services making several hops which would just be one inside a monolith. Tracing across services pretty hard especially if no one wants to take on state per-se. There has been advances with distributed tracing such as Jaeger. Application infrastructure responsibility starts to shift with microservices. The Full Lifecycle Developer/team model starts to make an appearance as teams start to run soup to nuts what is required for their endpoints to work. Though back to the database; what if your team or endpoint becomes a run-away success? Could you imagine a DBA managed Oracle Cluster per service endpoint? Those would be some really expensive microservices. Expertise in databases might not be your or your team’s forte so application infrastructure expertise starts to shape architecture; you know what you know. Deployment complexity certainly increases with microservices which might be counterintuitive from monolithic architecture. With the monolith, the human complexity is there having multiple teams agree when to deploy. That complexity shifts to systemic complexity with microservices as the number of deployments increase; more services, more deployments. Back to the “Ravi Litmus Test”, can you deploy without involving another team? Hopefully the deployment pipelines are robust enough to handle the increased demand and velocity. The software development teams investing in the new paradigm only to hit a bottleneck when trying to deploy would be a shot in the foot. The going joke would be “container sprawl is the new virtual machine sprawl”. What is driving all of these containers? Your microservices. With microservices you seem to have a lot more copies of application infrastructure. Instead of one database to go along side the monolith, the number of databases seem to explode with the services. More is certainly more in the microservice world.
Don’t be afraid of the microservice with Harness
The microservice journey in your organization is most likely an organic / natural progression. As software engineers the goals of the microservice movement, having more decomposed pieces is not new and have been marching towards this goal for some time. As your number of endpoints start to bloom, Harness is there to help. Your pipeline(s) should not be a bottleneck to teams wanted to create new or decomposed services. With the velocity of new services being created with more teams embracing the microservices mantra, DevOps teams can be overburdened quickly with brittle or non-robust pipelines.Creating new pipelines are extremely easy with Harness. As the the services start to scale at your organization, don’t let what actually deploys the sprints of hard work from getting into the wild be the bottleneck.-Ravi