From Monolith to Microservices: A Small Team’s Cloud‑Native Evolution
This article chronicles a SaaS startup’s transition from a simple monolithic Java application to a fully containerized microservice architecture, detailing the motivations, design principles, CI/CD pipelines, Spring Cloud and Kubernetes integration, automated deployment, tracing, and operational monitoring practices adopted along the way.
Monolith Era
The early product started as a two‑person team building a single‑page application with a clear front‑end/back‑end separation, served by Nginx proxying requests to a Java server on port 8080.
Interface Definition
APIs were designed following standard RESTful conventions: versioned under /api/v2, resource‑centric URLs using plural nouns, avoiding verbs, and supporting standard HTTP methods (POST, PUT, DELETE, GET). The team distinguished between full updates (PUT) and partial updates (PATCH), ultimately treating PUT as a partial update by ignoring empty fields. Swagger generated documentation for front‑end consumption.
Continuous Integration (CI)
Leveraging prior experience in large teams, the group introduced integration testing that exercised APIs, databases, and message queues, providing realistic production‑like validation. Jenkins automated builds, test execution, and report generation, with code reviews following successful tests.
Microservice Era
As business complexity grew, the monolith was split into over ten microservices, complemented by a Spark‑based BI platform. Service boundaries were defined by low data coupling and domain‑driven design, though the latter’s full implementation proved challenging.
Framework Choice
Spring Boot’s existing codebase led to the adoption of Spring Cloud for service registration, discovery, load balancing, and circuit breaking (Zuul, Eureka, Ribbon, Feign). The team noted performance limitations of Zuul and considered Spring Cloud Gateway or Nginx‑based solutions.
Architecture Refactoring
The migration introduced Docker images for each service, containerized database upgrade tools, and replaced Eureka with Kubernetes native Service discovery in production. Configuration toggles allowed seamless switching between Spring Cloud and Kubernetes mechanisms.
CI Enhancements
CI pipelines were extended to build Docker images and push them to Harbor. Database migrations moved from in‑process Flyway to isolated Docker‑based tools, enabling controlled, single‑process upgrades and supporting future sharding strategies.
Automated Deployment
Jenkins pipelines orchestrated deployment order based on service dependencies, using Ansible to transfer artifacts to jump hosts and then deploying containers via Kubernetes.
Link Tracing
The team implemented lightweight request tracing by generating a RequestId at the gateway and a hierarchical TraceId for downstream calls, propagating these identifiers via HTTP headers or message headers. ThreadLocal stored context within a service, and logs were filtered by these IDs for rapid troubleshooting.
Operations Monitoring
Before containerization, monitoring relied on Telegraf collecting JVM, system, and MySQL metrics, storing them in InfluxDB, and visualizing via Grafana. Spring Boot Actuator and Jolokia exposed additional endpoints without code changes.
Conclusion
The evolution from monolith to microservices required coordinated development, testing, and operations efforts, emphasizing service decomposition, automated pipelines, and observability. The small team avoided unnecessary hype, adopting cloud‑native practices that balanced technical debt with business needs.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
