2021 Toolbox for developing micro services

Praveen Manvi
11 min readAug 12, 2021

--

This document discusses the technology options available to build microservices in JVM eco system and azure environment. It follows the method of architecture decision record (ADR) that captures an important architecture decision made along with its context and consequences on various options available.

Framework

In JVM space there are many options for developing micro services. Considering maturity background and people involved around this, following 3 are strong contenders, Spring Boot (old, mature, boring but still thriving), Quarkus (A Kubernetes Native Java stack tailored for OpenJDK HotSpot and GraalVM from RedHat) and micronaut (Memory and startup time optimised framework by Oracle(now)). The last 2 technologies are new designed for serverless, reactive, and docker friendly services (that requires low memory foot print and faster startup time) basically trying to cover the java/spring gaps which is heavily dependent on reflection technique and not AOT. Personally micronaut appeals to me compare to others, ktor from Jetbrains for only Kotlin use case. Microframeworks like javalin, spark, flask are not considered as their USP is normally do with little to no dependencies to external libraries and do not provide complete solution which is good for quick targeted solution.

Good support cloud native domain concerns i.e. horizontally scalable, small startup time i.e. allowing to run on k8s and micro-services and cluster is running on spot AWS spot instances OR Azure spot VMs with auto scale, light weight threads with reactive paradigms for optimal resource consumption, off the shelf libraries and online literature, community support for solving common use cases, support for serverless are the driving factors for picking the tool sets.

Spring Boot with reactive paradigm

To be fair to Spring boot, its catching up with the reactive paradigm (webflux) and building of graalvm native friendly images. Spring cloud is suit of technologies that provide the complete package to implement the domain concerns of micro services. Azure spring cloud in collaboration with pivotal has come up with comprehensive well defined architecture. Spring Cloud API Gateway can be thought as enhanced reverse proxy with advanced capabilities like programmatic orchestration, discover service integration, security and monitoring capabilities. The newer version has been enhanced to work with reactive model of spring compared to earlier version based on NetflixOSS zuul.

Going by recent report spring ecosystem captures 62% java mindshare and is the most popular framework with solutions for almost all web application development needs.

If azure is PaaS provider, spring cloud is safe option to build micro-services. MS Azure quality of support for Java is amazing.

Spring cloud provides the wrappers for implementing microservice domain concerns quickly, but we do have to make choices, Here are my choices for ex: configuration management (redis) , service discovery (consul), circuit breakers (resiliance4j) , intelligent routing (SpringCloud gateway) , control bus(kafka) , security (stateless, JWT) , global locks , Cluster wide Singletons (Redis) , Load Balancer(Gateway, Ribbon) andInterprocess communication (WebClient). Azure spring cloud offers fully managed service built on AKS. The out of box services include autoscale, all kubernetes goodies support, bind apps to Azure services like Cosmos DB, Azure Database for MySQL, Azure Cache for Redis… and more importantly automatically wire up spring boot apps with Spring Cloud infrastructure.

Azure Spring Cloud

API First design

API Governance (Security, Routing, Deployment, Throttling, Open API, Discoverable, Performant, Cloud Native,Reliable,Observable, Resilience, Load Balancing) , API Documentation (Dev Portal, Dev Exp, Quick Adoption, Up sell, Cross sell, Best practices and SDKs), API Life cycle (Onboarding, Provisioning, Versioning, Compatibility, Billing).

Open API specification specified from code is more scalable. Product team need to get familiar with checking in documentation directly into the code. with Kotlin spring support for swagger makes it super easy to document through annotations. Word document OR providing swagger yaml/json files to developers is just not scalable option.

redoc is a quite decent option to publish the docs. It also has commercial support with developer portal. Having great DX (Developer Experience) is essential for SaaS products to scale and succeed.

Language

JVM has Kotlin, Groovy and Scala and of course grand old Java as implementation languages as option to develop micro services. Jython (python), JRuby (ruby), Clojure (Lisp) aren’t supported by frameworks and there is not much of traction in this space & they don’t fall into better Java model. As we go by recent report by redmonk, says “Java, as noted above, has shown no signs of riding off into the sunset, and in fact managed to grow its share this run after two quarters unlike Go, Kotlin and Rust which stayed where they are

Kotlin

Here is 60+ slides arguing merits. In Aug 2021, Kotlin is 10 years old now and mature. Having prior experience of using groovy(grails), scala and falling back to java again, I think kotlin has eco system to thrive and more importantly functional friendly code (co routines, suspend) makes it natural fit for writing code that is reactive paradigm enabled. Kotlin is quite ambitious that IntelliJ is pushing this as ubiquitous (native, javascript, mobile, desktop, server side…) language and is worrying part as it can become jack of all and master in none. Of all the the options available. Kotlin remains the decent option to develop micro services and work best with java side by side compared to any other option and hence the safe bet.

Event Driven Architecture

Event-driven micro services allow for real-time communication, enabling data to be consumed in the form of events before they’re even requested. Having real-time database (kafka) to drive decisions. For any organisation, developing consumer facing applications and where scale is a feature this architecture model is de-facto standard.

Confluent has the mature and possibly innovative eco system to build event driven architecture. The ability to create materialised views with CQRS pattern is probably most important part of microservices. It allows to pick the data stores having the sweet spots for given use case. The cost of adopting and throwing away becomes easier and plays important role in moving fast. The velocity of technologies becoming legacy is high and is likely to increase in coming years and the this trend unstoppable. Continuously extract the data from existing services and databases by importing them as streams into Kafka via connectors/streams and change data capture (CDC) makes it super easy to achieve this. Debezium is probably the excellent technology in this space.

Here is best explanation about building event driven architecture with CDC. Each datastore having sweet spots, having support for polyglot data stores and building materialised views with speed with cost effectiveness is the most important aspect of data pipeline architecture.

Data pipeline architecture

For most of use cases, the need to have complex orchestration tools (apache airflow, Spring data flow, zeebe) is not required. The workflow definition can be naturally managed with topic message propagation (batch) and while dealing with streams(event).

Observability

As I discussed in length in my previous blog, Elastic suit of products are the best bet for building observability with JVM eco system driving all 3 pillars of observability.

Large systems can survive only on ability to “continuous checks on the veracity of data and durability of services” Springboot eco system comes with tools and metrics collection that makes it easy debug runtime.

Automating tests, building infrastructure as code, verification of environments, business metrics all should be embedded as part of services rather than as another external task “Efficiency inversely proportional to manual intervention.”

Its important to observe all parts of the system including CI/CD and elastic comes with robust solution monitoring jenkins.

Search

Elastic AppSearch makes life lot simpler to build search UI experience with generating UI and a facade search centric API layer over elastic APIs making building search solution easy.There are other competing products in this space. This looks decent solution to adopt. Reference React UI that it generates by default is a big win for starting up quickly.

Serverless

In theory server less is best option to develop services with ability to create scalable and cost-effective applications without the overhead of managing servers. Having spent time on developing AWS lambda (probably the best eco system), I am of the opinion Developers and Development cost is important metric & it can cancel out the benefits. This is also contextual (experience and skills) and situational (when to deliver and how long to deliver). So far I found https://www.http4k.org/ is quite impressive, will revisit this space to make this as default methodology for developing micro services from looking into azure functions.

Deployment

It’s always safe bet to run on broad shoulder of cloud vendor like azure spring cloud. Apparently building/managing container with K8s becomes transparent with this with all heavy lifting done by these folks, so far it looks great. (Will revisit this) Ref. Gradle, JDK 11 (or JDK 17 LTE) are well supported by cloud vendor.

Auto scaling is transparently managed, As scaling happens with individual microservices the need for auto scale becomes less for important with multi-az enabled deployments. The reactive apps should be able to cater most of the micro services as by their definition they are catering a particular domain.

Azure Spring Cloud makes it easy to deploy Spring Boot–based microservice applications to Azure with zero code changes. Spring Cloud manages your application infrastructure so that you can focus on application code and business logic. Take advantage of built-in core features like Eureka, Config Server, Service Registry Server, VMware Tanzu Build Service and blue-green deployment. Bind your applications with other Azure services, such as Azure Cosmos DB, Azure Database for MySQL and Azure Cache for Redis.

User Interface

Web (Internal)

This is controversial topic, For internal applications vaadin looks to be the best option to build UIs in JVM eco system. It’s easy and makes development of progressive web apps easier with SpringBoot eco system doing all heavy lifting job magically. The progressive web apps allows users to deploy in desktop and mobile applications. In order to have web-scale capabilities horizontal scaling aspects to make it de-facto standard. But from development experience its a breeze.

Web (External)

React is better option compared to other framework. These decisions should be driven by the availability and familiarity from developers.

Mobile

Kotlin/KMM looks promising and having investment will bring rich dividends with code re-use both in letter and spirit.

Job Scheduling

Distributed Java Background Job Scheduler · JobRunr is good option for scheduling and managing the jobs. Its simple, integrates well with spring boot framework. This Job scheduling library uses lambdas for fire-and-forget, delayed and recurring jobs. Guarantees execution by single scheduler instance using optimistic locking. Persistence (including elasticsearch), dashboard monitor support with minimal dependencies makes it awesome and embeddable into existing spring boot micro services.

Continuous verification

For micro services ‘scale is a feature’ and as latency is new downtime and not actual service going down. gatling provides better code friendly approach to assert the API performance (as compared to JMeter) and hence preferred.

The tools like Testcontainers it’s more productive to combine the integration and performance to avoid duplicate efforts. Building of test suit with real world matching content is probably as huge as an effort like developing services itself, the investment in building robust suit will provide compound interest over the time. JFaker is a decent solution to generate the sample data, comes with decent defaults and can be extended for newer data types as well. Developing of test suits with JUnit 5 should be part of service building rather than as an afterthought.

Summary

The above eco system allows multicore aware, cpu efficient, observable, strong library and cloud native eco system, best in class developer productivity experience, reliable at scale and future proof micro services that can work for next 10 years.

FAQ

Why Micro-services?

micro-services are organised around business capabilities and are independently deployable and scalable. The proven methodology is that if the velocity of changes are largely isolated, stakeholders with domain skills can work independently micro services allows to parallelise the workforce which drives the scale of features and engineers. Cost of change becomes manageable because of bounded contexts and isolated verification efforts.

Following characteristics should drive the decision to go with microservices OR not, The code base is (or going to be) medium to large (& > 30K) with large teams and is adding new features at rapid rate. (P.S. splitting up into logical services from a small codebase which inherently homogeneous is overkill). Team develops deep expertise over the time. Domain knowledge is valuable over the time & there is no contextual switch. It’s also important that operational team is comfortable architecture.

Why Reactive?

The ability to serve large number of users, with minimal resources, minimum time, and highest velocity is the requirement, reactive is viable pattern. With micro services architecture, advent of reactive protocols (rSocket), its a must to use reactive paradigm that helps to optimise resource utilisation to have higher throughput.

Why not python?

Relatively slow, limited OR no multicore (global interpreter lock) support, no strong type check feature and library eco system is limited in this space (API servers OR cloud native applications). Kotlin is expanding (mobile, web, native, server side, data science) everywhere but python is not expanding (few sweet spots with data science etc…). Kotlin has more forward momentum and the syntax is closer to java and designed with developer’s productivity in the mind

Why Not Go?

Go supports advanced performance without the need for any additional frameworks 👍, Also P.S. Go makes various concessions in the name of speed and simplicity. Golang doesn’t possess the history, notoriety, or complexity of Java in long running processes and large development teams, but it is optimized for performance and simplicity for micro services.

The personal anecdotal evidence that I have is some customer facing apps moved from go to JVM eco system back in India. Lack of experienced developers, production experience is driving factor.

Kotlin is a clever choice, especially if you already have JVM eco system (mobile, server, pipeline, big data). Not only will it be familiar and easy to learn, being OOP and using the JVM, but it runs like JVM observability eco system with fewer lines of code. Then, there’s the added benefit of functional programming and the fact you can express ideas in functional manner in Kotlin. I used look at Netflix folks on how they have designed/solved for particular problem domain, now I look in Kotlin library space. Best minds that I have been following have been drifting towards this.

References

Learning a language from language that you already know is quickest way. Here examples for python and TypeScript developers.

https://github.com/Khan/kotlin-for-python-developers

https://kotlin-for-python.readthedocs.io/en/latest/about.html /

https://gi-no.github.io/kotlin-is-like-typescript/

Nice way to get familiar with syntax with Kotlin by working with examples.

--

--

Praveen Manvi

Senior (Architect, Director, VP) Software Engineer. Building web scale SaaS/Multi-Tenant Solutions in Cloud (AWS,GCP,Azure). Ex-Yahoo, Ex-Oracle, Ex-{startups}.