Skip to content

Using messages between microservices to achieve an available, partition tolerant, eventually consistent system

License

Notifications You must be signed in to change notification settings

kunal-mandalia/distributed-messaging

Repository files navigation

distributed-messaging CircleCI

Using messages to communicate between microservices to achieve an available, partition tolerant, eventually consistent system

Overview

This app models the canonical online store. It starts small with two domain services; the Order service, and the Inventory service. Each service reacts to events e.g. when an Order is created an order created event is produced, the Inventory service consumes this event and updates the stock as per the order.

What happens if the Inventory service is offline? Or if there isn't enough stock? Designing a system which can tolerate this and eventually recover to handle the flow of the Order is the focus of this project.

There's an emphasis placed on ensuring messages are processed in an idempotent way since we won't guarantee exactly once delivery of messages.

Design Decisions

Martin Fowler categorises the many meanings of "event-driven" architecture. The architecture in this app aligns most closely with what is referred to as "Event Carried State Transfer".

While the "Event Carried State Transfer" pattern shows how services will communicate with each other, what they communicate i.e. the event message payload will be guided by Domain Driven Design (DDD). This means exposing a common set of high level message attributes which allow services to react to Events but not enough for data to bleed across bounded contexts.

Finally a couple of terms from CQRS will be used to help identify the different intent of messages; Commands for when the user makes a state changing request e.g. placing an order, and Events for emitting a notification following a change to a service e.g. inventory updated.

Kafka is at the heart of the system so concepts like topics, partitions,offset, etc. play a key role.

Development

Run the infrastructure:

  • Kafka Broker: yarn start-kafka-broker
  • Persistence: yarn start-persistence

Run individual services:

  • API gateway: yarn start-service-api-gateway
  • Order domain service: yarn start-service-order
  • Inventory domain service: yarn start-service-inventory
  • notification service: yarn start-service-notification

Seed data:

  • Inventory: curl -XPOST http://localhost:8901/automation-testing/seed

Create an order:

  • ORDER_001: yarn post-order-1
  • ORDER_002: yarn post-order-2

Creating an order is idempotent; it'll only be processed once. Therefore ORDER_001 may be placed many times but stock will only adjust the first time.

Test

E2E

  • Run all services: yarn compose-all
  • Run e2e tests: yarn test-e2e-local

About

Using messages between microservices to achieve an available, partition tolerant, eventually consistent system

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published