We have 2 to 3 dozen microservices that serve our customers. These services are deployed in a Kubernetes cluster, and they're only accessible to the outside world through 3 or 4 API gateways.
We found that sometimes the same data is needed by two or more microservices, so we evaluated a couple of strategies to solve this problem and have implemented a solution in pieces. Like any design, we are not 100% sure if we're using the right approach, and whether we're missing potential pitfalls in the design.
Case 1:
When a service of lesser business importance ServiceL
needs data from a service of higher business importance ServiceH
, then
ServiceL
calls ServiceH
directly to get the necessary data.
Case 2:
When a service of lesser business importance ServiceL
needs data from many important services ServiceH1
, ServiceH2
, etc), then
ServiceH1
, ServiceH2
publish messages with that data to RabbitMQ.
The publishing of messages is fire-and-forget, so the services are not blocked.
ServiceL
subscribes to these messages and stores the data in its own data store.
We are okay with the delay in the data becoming available to ServiceL
.
Case 3:
When a service of higher business importance ServiceH
needs data from a less-important service ServiceL
, then ServiceL
publishes a message with that data to RabbitMQ via a fire-and-forget or blocking mechanism, depending on urgency of syncing the data.
ServiceH
consumes the message and stores it in its data store.
Often the data is needed by ServiceH
for reports and summary, and we are okay with the summary not being perfectly up to date at all times (eventually consistent) .
Case 4: When data is needed by two services and both of them not only read data but also modify it, then we believe the domain identification is wrong in which case we redesign them, often merging these two microservices into one.
Additional Info for Case 2 & 3: Now when we use a messaging framework like RabbitMQ for syncing data across services, over a period of time we observed data is getting out of sync between services. When data gets out of sync, we could see the statistics from RabbitMQ and replay messages, but we believe this brings in unnecessary complexity. We've ended up running jobs once a day to sync the data from the source service to the destination service, where the data is retrieved from the applicable services and not directly from their data stores.
Is this a good approach to sync data between microservices? Are there any pitfalls?