CO3404 Distributed Systems
CO3404 - Exam Revision 8 (02-07-2026) - APIs & Documentation
Block 5 β Messaging & Event-Driven PatternsΒΆ
Lectures 9, 11
- Message pattern pros/cons: async decoupling, queueing (RabbitMQ)
- Message vs event β the core distinction (command/intent vs "a fact that happened")
- Event pattern pros/cons: pub/sub, event streams, eventual consistency (RabbitMQ & Kafka)
- Be ready to compare RabbitMQ vs Kafka use-cases if asked
Relevant LecturesΒΆ
Block 5ΒΆ
Asynchronous VS Synchronous JavaScriptΒΆ
JavaScript is single-threaded, meaning it has one call stack and executes one task at a time.
The difference between synchronous and asynchronous code is that synchronous code blocks the execution of subsequent code until the current task finishes, whereas asynchronous code can start a task and continue executing other code without waiting for that task to complete.
Once the asynchronous task completes, its callback or Promise is handled when the call stack is empty.
Inter Microservice CommunicationΒΆ
Asynchronous MessagingΒΆ
Asynchronous Messaging involves microservices posting messages to a queue.
A producer sends a message to a message broker, which stores it in a queue. The producer does not wait for the consumer to process the message and can continue executing immediately.
ExampleΒΆ
graph LR
M1[Microservice 1]
subgraph MSGBroker[Message Broker]
Msg1[MSG5]
Msg2[MSG4]
Msg3[MSG3]
Msg4[MSG2]
Msg5[MSG1]
end
M2[Microservice 2]
M1 --> MSGBroker --> M2 Key FeaturesΒΆ
- M1 and M2 are decoupled the contract is with the queue.
- Dynamic FIFO data structure.
- M1 doesn't need to know if M2 can handle a large amount of messages at once.
- M1 is unaffected if M2 does down.
Message BrokersΒΆ
Message brokers implement the asynchronous message pattern. Some brokers are:
- RabbitMQ - Open Source
- Apache Kafka - Open Source
- Amazon Simple Queue Service (SQS) - AWS
- Azure Message Broker, & Azure Storage Queue (ASQ)
RabbitMQ and Apache Kafka as they are cloud agnostic.
Note
If all-in with a particular cloud provider, their services may be preferential.
Messaging PatternsΒΆ
Producer / ConsumerΒΆ
Asynchronous service to service messaging
One producer and one consumer
Generally, uses push to consumer
Resilience is built-in to avoid SPOF
Implemented using a message broker
graph LR
P[Producer]
subgraph msgbr[Queue]
EM[ ]
EM2[ ]
EM3[ ]
EM4[ ]
MSG4
MSG3
MSG2
MSG1
end
P --> msgbr
msgbr --> C1[Consumer 1]
msgbr --> C2[Consumer 2]
msgbr --> C3[Consumer 3] Publisher / SubscriberΒΆ
Asynchronous service to service messaging
One publisher and many subscribers
Use fan-out for pub/sub - adding a new microservice
Resilience is built-in to avoid SPOF
Implemented using a message broker
graph LR
P[Publisher]
subgraph msgbr1[Msg Broker]
EM1[ ]
EM2[ ]
EM3[ ]
EM4[ ]
MSG4[MSG4]
MSG3[MSG3]
MSG2[MSG2]
MSG1[MSG1]
end
subgraph msgbr2[Msg Broker]
EM4[ ]
EM5[ ]
EM6[ ]
EM7[ ]
MSG5[MSG4]
MSG6[MSG3]
MSG7[MSG2]
MSG8[MSG1]
end
subgraph msgbr3[Msg Broker]
EM8[ ]
EM9[ ]
EM10[ ]
EM11[ ]
MSG9[MSG4]
MSG10[MSG3]
MSG11[MSG2]
MSG12[MSG1]
end
P --> msgbr1 --> S1[Subscriber 1]
P --> msgbr2 --> S2[Subscriber 2]
P --> msgbr3 --> S3[Subscriber 3] RabbitMQΒΆ
Basic InformationΒΆ
RabbitMQ uses the AMQP (Advanced Message Queueing Protocol) standard which is a platform agnostic protocol to transfer information between applications. The source and destination are the Producer and Consumer.
ConnectionΒΆ
This is a network connection between an app and the queue. Similar to a database connection
ChannelΒΆ
Virtual connection inside a connection. Multiple channels can be created within a single connection, allowing for concurrent operations and communication between different parts of a client application
Example
May have one channel for produced messages and another for consuming messages within the same connection to RabbitMQ
QueueΒΆ
A FIFO-based message storage and delivery component βΉ It holds messages sent by producers until they are consumed by consumers
RabbitMQ Docker ContainerΒΆ
It can implement queues and message routing through a message exchange component which can route messages to various queues based on a routing key.
It has a management interface to setup and monitor the queues
Key TermsΒΆ
Producer / PublisherΒΆ
An application that sends a message to the broker. The broker confirms the message is queued.
Consumer / SubscriberΒΆ
Application that consumes the message. Consumer informs rabbitmq that it received the message (acknowledges it) so it can be removed from the queue.
ExchangeΒΆ
Receives messages from producers and routes them to the correct queue based on rules associated with a routing key.
Routing KeyΒΆ
This can be a word, series of words, wildcard. e.g. all messages that contain pr* as a post code are sent to a queue for consumers of Preston based messages e.g. for a survey.
Virtual HostΒΆ
Segregates applications using the same rabbitmq instance. Think of it as separate broker instances each with different permissions and credentials but built into a single instance, e.g. a single container.
Exchange TypesΒΆ
DirectΒΆ
A producer and consumer are using one queue based on the binding key (we use this & default exchange).
TopicΒΆ
A wildcard match between the routing key and the routing pattern determines the queue. Like the earlier example.
FanoutΒΆ
Routes a message to all the queues. E.g. message sent to multiple microservices - pub / sub pattern
graph LR
subgraph Queue
MSG3
MSG2
MSG1
end
P[Publisher] --> E[[Exchange]] --> Queue --> C[Consumer]
C -- Consumer Acknowledges Message --> Queue
E -- Publish Confirmation --> PRabbitMQ Message Broker
CO3404 - Exam Revision 10 (04-07-2026) - Event Patterns & Containersation