From Monolith to Microservices: Real‑World Lessons and Practical Strategies
This article walks through the evolution of an online supermarket from a simple monolithic website to a fully split microservice architecture, highlighting the pitfalls of ad‑hoc growth, the need for service abstraction, monitoring, tracing, fault tolerance, testing, and the trade‑offs of frameworks versus service mesh.
This article introduces microservice architecture and its related components, explaining what they are and why they are used. It focuses on presenting a global view of microservices without diving into detailed component usage.
Initial Requirements
Several years ago, two founders built an online supermarket with a simple website for browsing and purchasing products and a separate admin backend for managing users, products, and orders.
Website
User registration and login
Product display
Order placement
Admin backend
User management
Product management
Order management
Because the requirements were simple, the initial system was built quickly as a monolith with a shared database.
Business Growth and Emerging Problems
Rapid competition forced the team to add promotions, mobile apps, and data analysis, leading to ad‑hoc code duplication, tangled interfaces, blurred service boundaries, performance bottlenecks, a shared‑database schema that could not be refactored, and cumbersome deployment processes.
Duplicate business logic across web and mobile apps
Inconsistent data sharing (direct DB access vs. API calls)
Services growing beyond their original responsibilities
Performance degradation in the admin backend after adding analytics
Database schema locked by multiple services
Database becoming a single point of failure under load
Complex, error‑prone release cycles
Team friction over ownership of shared functionality
Time for Change
Recognizing these issues, the team abstracted common business capabilities into independent services:
User Service
Product Service
Promotion Service
Order Service
Data‑Analysis Service
Each application now consumes data from these services, eliminating most redundant code.
Even after service separation, a shared database still caused performance and coupling problems.
Database became a performance bottleneck and single point of failure.
Data management grew chaotic as services directly queried each other's data.
Schema changes required coordinated updates across services.
To resolve this, the team split the database, giving each service its own persistence layer and introducing a message‑queue for real‑time communication.
With isolated databases, services could adopt heterogeneous storage technologies, such as a data warehouse for analytics or caches for high‑traffic services.
Monitoring – Detecting Failure Signs
In high‑concurrency distributed systems, failures can appear suddenly. The team built a monitoring stack using Prometheus to scrape metrics from exporters (e.g., RedisExporter, MySQLExporter) and Grafana for dashboards and alerts.
Tracing – Locating Faults
Each request may traverse multiple services. By propagating a traceId, spanId, parentId, and timestamps in HTTP headers, the system can reconstruct call graphs. The team used Zipkin (an open‑source Dapper implementation) and added an interceptor to inject tracing data.
Log Analysis
When log files become massive and distributed, a searchable log platform is essential. The team adopted the ELK stack (Elasticsearch, Logstash, Kibana) to ingest, store, and visualize logs, using file‑beat agents to ship logs to Logstash.
Gateway – Access Control and Service Governance
A gateway sits between callers and services, enforcing authentication and providing a unified API surface. The team chose a coarse‑grained approach: one gateway for external traffic, internal calls remain direct.
Service Discovery and Dynamic Scaling
Instances register themselves with a discovery service (e.g., Zookeeper, Eureka, Consul, Etcd). New instances are deployed without manual load‑balancer updates; the discovery layer handles registration, health checks, and client‑side load balancing.
Circuit Breaker, Service Degradation, and Rate Limiting
Circuit Breaker
If a downstream service fails repeatedly, the circuit breaker opens, returning errors immediately to prevent cascading latency.
Service Degradation
Non‑critical services can be gracefully degraded during outages to keep core functionality alive.
Rate Limiting
To protect services from overload, requests are throttled per time unit, optionally scoped to offending callers.
Testing Strategy
Testing in a microservice world occurs at three levels:
End‑to‑end testing of the whole system (expensive but most reliable).
Service‑level testing of APIs.
Unit testing of individual code units (fastest, but limited scope).
Microservice Framework
To avoid repetitive integration code, the team built a lightweight framework that handles metric exposure, tracing injection, log forwarding, service registration, routing, circuit breaking, and rate limiting. However, framework upgrades can be costly and require coordinated releases across many services.
Service Mesh – An Alternative Path
Instead of embedding logic in each service, a sidecar proxy can handle cross‑cutting concerns (traffic routing, security, observability). The data plane consists of sidecars; the control plane manages their configuration.
Conclusion – The Journey Continues
Microservices are not an end point; future directions include serverless, FaaS, and even a return to monoliths in some cases. The transformation described provides a practical roadmap for teams embarking on similar journeys.
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.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
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.
