Microservice Decoupling Strategies: From Synchronous Calls to Asynchronous Messaging, Event‑Driven Architecture, and CQRS
The article analyzes common coupling problems in microservice architectures and presents practical decoupling techniques—including asynchronous messaging, event‑driven design, local caching, data landing, and CQRS—while also offering refactoring guidelines for tightly coupled services.
Author: 人月神话 (source: https://www.toutiao.com/i6851016633579028996/). The article explains that many issues in microservice systems stem from poor initial module partitioning and introduces five principles for proper service division, such as limiting the number of services to fewer than ten and avoiding splitting strongly data‑related modules.
Problem Overview
Adoption of microservices, containerization, and DevOps has increased system complexity, turning internal calls and transactions into cross‑service API calls and distributed transactions, which can cause avalanche effects when a single service fails.
Synchronous Calls → Asynchronous Calls
Using message middleware to convert synchronous interactions into asynchronous ones is a primary decoupling method. Messages are sent to a highly available broker, which then forwards them to target systems with retry support.
Message Middleware Adoption
Message‑oriented middleware (MOM) enables time, space, and flow decoupling between publishers and subscribers. It supports both AMQP‑based solutions (e.g., RabbitMQ, Kafka) and JMS‑based products (e.g., WebLogic JMS, IBM MQ). Typical use cases include notifications, asynchronous integration, load‑spike mitigation, publish/subscribe, and high‑reliability scenarios.
Event‑Driven Business Analysis
Shifting from traditional process‑driven analysis to event‑driven analysis (EDA) requires identifying business events, their triggers, and state changes. EDA characteristics include broadcast communication, real‑time delivery, asynchrony, fine‑grained events, complex event processing, parallel execution, and non‑blocking behavior.
From EDA to CQRS
CQRS (Command Query Responsibility Segregation) separates write (CUD) operations from read (R) operations. Commands generate domain events stored in an Event Store and dispatched via an Event Bus, while queries directly read from a dedicated query database, enabling read/write separation and better scalability.
Local Message Cache for Synchronous Interfaces
If a synchronous call to an external system fails, the request can be stored locally and retried later via scheduled tasks, decoupling the business function from immediate success.
Local Cache for Query Data
Using distributed caches such as Memcached to store relatively static reference data allows services to fall back to the cache when the upstream source is unavailable, reducing latency and dependency.
Consider Data Landing
For infrequently changing data, persisting a copy within the microservice reduces reliance on remote services, improving availability while maintaining real‑time consistency for critical data.
Refactoring Existing Tight Coupling
When services are already tightly coupled, possible remedies include merging overly granular services, extracting common functionality into a shared service, migrating mis‑placed modules to the appropriate service, and converting fine‑grained services into coarse‑grained domain services.
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.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
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.
