Microservices Tech Stack with Spring and Vert.X

It’s been awhile since my last blog post, and it’s been for several reasons. The primary, is that our team has been challenged to implement a Microservice Architecture (MSA) that fit’s my current company's needs. It’s been a process defining the stack, learning the new stack and providing tooling/components for developers to innovate.

Building New Software with Legacy in Mind
We have a slightly archaic way of deploying products that differ dramatically from our premises and cloud environments. In the cloud we have freedom to utilize cloud tools, popular devops infrastructure like docker, AWS, and Spring Cloud. Unfortunately, the products we deliver can be shipped on premises with no interaction with cloud infrastructure. Being able to support both avenues (as well as hybrid) required us to build out our own tooling to support an MSA in both environments. Leveraging existing open source software such as Spring Boot, Vert.X and NetflixOSS was crucial to our success.

Why Microservices Architecture?

Currently many of our systems have shipped the same products in cloud and premises environments on completely separate code bases. There is a long story as to why this happened, but was something we needed to avoid on future development. Also, many of our products have similar functionality having many implementations scattered across solutions. A microservices architecture also eased our pains with deployment on premises. Scaling is simpler with service discovery as we can do both horizontal and vertical scaling of our infrastructure. It saves costs on VMs and hardware as we don’t scale the entire monolith when scaling a single feature function.

Key Reasons:

  1. Cloud and Premises Capable
  2. Scalable, Reusable Services
  3. Consolidate common features developed by multiple teams and products
  4. Disposable Services
  5. Support for Hybrid Environments
  6. Transparency across teams and forced communication between areas that may have been lacking before.
  7. Quickly adapt to customer demand and requirements

MSA Tech Stack

We wanted to make development rapid and scalability painless, and our company is most familiar with JVM languages like groovy and Java. Spring Boot for business services with NetflixOSS for high availability and fault tolerance were clear winners and a natural fit. Without these tools, an MSA architecture would be difficult to implement with our business requirements.

Tech Stack Breakdown

This diagram images the stack as it’s used today.

  • Spring Boot
    • Business Microservices managing validation logic, service to service integration's, and REST HATEOAS based  interfaces.
    • Spring Security authorization of services and users.
  • Spring Data REST
    • Data services exposing entities as REST resources.
    • Enables simple scaling of data back ends and simplified interactions with large business domains with many services.
    • Simplified configuration of bring your own database requirements on premises.
  • NetflixOSS
    • RxNetty, Archaius, Ribbon, Hystrix and all the other goodies for client load balancing, HA, and fault tolerance.
  • Vert.X
    • Build and design custom fixed APIs for clients. Aggregate and transaction data across services. Enable clients to connect via HTTP or other means like websockets without burdening the business services.
  • Zookeeper
    • Service Discovery storage and clustering. Exposed via a Spring Boot REST application.
  • Rabbit AMQP
    • Exchange and manage data across services that foreign key other systems.

MSA Architecture

Vert.X API Gateway
Defines client API’s and proxies calls to the back end services. Modularity enables packaging of API’s at build time.

Registry Gateway
This is a spring boot microservice that places a REST interface on zookeeper for service registration and discovery. We would have opted for Eureka, but wanted to own this piece for cloud and premises capable deployments.

Resource Discovery Vs. Service Discovery

We bought into the HATEOAS pieces of REST early in our adoption of microservices. We quickly found that discovering resources was much more agile than discovering services and just their base URI. So instead, a service will register itself and a list of root resources into their service. So to discover a service, you would actually ask for the links to a resource.


Dynamic discovery of HATEOAS APIs at the API Gateway.
We were able to quickly develop a verticle in Vert.X that exposed all resource routes in the system as resources at the root of the API gateway. That meant, for clients that did not need custom API’s, they could discover the back end APIs and their documentation straight from the root of our microservices system. The vertical was able to proxy requests to and from services on the back end as clients transparently traversed the entire system's API. This was amazingly powerful.

Common language for integration
With a common language for integration, we were quickly able to develop tooling for load balanced resource traversal of HATEOAS APIs and near eliminated the need for a client library per business domain or microservice. Integrating between systems simplified as they all talk the same language.

There is much more to cover around the architecture and tech stack but figured I'd hold off on a full detailed description for now. This is a basic interpretation of the tech and not and exact representation. There may be more topics around different components in the future, and my thoughts on certain layers advantages/disadvantages.


Popular posts from this blog

Ruby RSpec: Mocks, Doubles, and Spies with Constructor Injection