Strategies for Decoupling Microservices: Asynchronous Calls, Message Middleware, Event‑Driven Architecture, and CQRS
The article explores how enterprises can reduce tight coupling in microservice architectures by converting synchronous calls to asynchronous messaging, adopting message‑oriented middleware, applying event‑driven analysis, and leveraging CQRS patterns, while also offering practical refactoring tactics for overly coupled services.
Before diving into decoupling techniques, the author references a previous article on reasonable microservice granularity and outlines five principles for module division, emphasizing fewer than ten modules, strong data coupling avoidance, data‑driven aggregation, vertical‑to‑horizontal design shift, and high cohesion with loose coupling.
Microservice adoption introduces cross‑domain API calls and distributed transactions, increasing system complexity and creating avalanche effects when a downstream service fails.
The first technical solution is to replace synchronous calls with asynchronous messaging using reliable message middleware (e.g., RabbitMQ, Kafka, WebLogic JMS), which provides time, space, and flow decoupling and supports retry mechanisms.
Message middleware use cases include notification, asynchronous integration, peak‑shaving, publish‑subscribe, and high‑reliability scenarios.
Event‑Driven Architecture (EDA) shifts analysis from process‑driven to event‑driven, requiring identification of business events from use‑case triggers, state changes, and event chains, and supports features such as broadcast, real‑time, asynchronous, fine‑grained, complex event processing, parallel execution, and non‑blocking behavior.
Transitioning from EDA to CQRS separates command (CUD) and query (R) responsibilities; commands generate domain events stored in an event store and propagated via an event bus, while queries read from dedicated read models, enabling read‑write separation and scalability.
Additional decoupling tactics include local message caching for failed synchronous calls, local query caching (e.g., memcached) to reduce reliance on upstream services, and selective data persistence for infrequently changing data.
When strong coupling already exists, refactoring options are presented: merging overly granular services, extracting common functionality into shared services, migrating mis‑placed units to appropriate services, and converting fine‑grained services into coarse‑grained domain services to limit unnecessary CRUD‑style interactions.
Promotional notice about a collection of architecture‑related e‑books and a discount offer.
Architects' Tech Alliance
Sharing project experiences, insights into cutting-edge architectures, focusing on cloud computing, microservices, big data, hyper-convergence, storage, data protection, artificial intelligence, industry practices and solutions.
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.