|
| 1 | +--- |
| 2 | +layout: default |
| 3 | +title: Queues and topics |
| 4 | +parent: Abstractions |
| 5 | +nav_order: 12 |
| 6 | +permalink: /abstractions/queues-and-topics |
| 7 | +--- |
| 8 | + |
| 9 | +# Queues and topics |
| 10 | + |
| 11 | +Imagine that we have a service-based architecture, where a number of services (A and B) produce messages, |
| 12 | +and a number of other services (C & D) consume messages. |
| 13 | +A common way to diagram such an architecture is like this: |
| 14 | + |
| 15 | +[](/images/queues-and-topics/1.png) |
| 16 | + |
| 17 | +From some points of view, this diagram is a true and accurate representation of the architecture. |
| 18 | +Services A and B are sending messages to an intermediary, which is forwarding those messages on to services C and D. |
| 19 | +The problem is that the "hub and spoke" nature of this diagram tends to obscure the real story, where a |
| 20 | +degree of coupling may exist between the message producers and consumers. |
| 21 | + |
| 22 | +## Point-to-point |
| 23 | + |
| 24 | +The problem here is being caused by us representing the message bus as a C4 container, which arguably isn't correct. |
| 25 | +A better approach is to think about each separate queue and topic as being a "data store". |
| 26 | +A message queue is essentially a data store - it's a bucket for storing data (messages), |
| 27 | +with producers adding data, and consumers taking it away. |
| 28 | +The implication here is that the queues and topics are C4 containers, rather than the message bus itself. |
| 29 | + |
| 30 | +[](/images/queues-and-topics/2.png) |
| 31 | + |
| 32 | +In this example, we can clearly see there's a coupling between services A and C via a queue named X, |
| 33 | +and there's a similar point-to-point coupling between services B and D via a queue named Y. |
| 34 | + |
| 35 | +Modelling queues and topics as C4 containers also provides a way to think about them independently of their |
| 36 | +deployment topology. At development time, you might have all queues and topics running on a single instance of a message |
| 37 | +bus to save resources on your laptop. The live deployment topology might see individual queues and topics deployed |
| 38 | +to separate message buses, brokers, or clusters for performance, scalability, or security reasons. |
| 39 | + |
| 40 | +If you genuinely have a point-to-point coupling via a queue, you could further simplify this diagram by omitting |
| 41 | +the queues, and moving the queue names to the arrows instead. |
| 42 | + |
| 43 | +[](/images/queues-and-topics/3.png) |
| 44 | + |
| 45 | +The result is a visually simpler and less cluttered diagram, but the queues are no |
| 46 | +longer as explicitly evident on the diagram. Since the C4 model is notation independent, you could additionally use a |
| 47 | +different line style (solid vs dashed) or colour to highlight message-based relationships. |
| 48 | +Neither version of the diagrams is "better" than the other, they are just telling the same story in a different way. |
| 49 | +It's all trade-offs. |
| 50 | + |
| 51 | +## Pub/sub |
| 52 | + |
| 53 | +You'll notice that all diagrams have shown messages flowing from the left of the diagram to the right, |
| 54 | +with the arrows labelled as "Sends messages to". Although this works well, particularly for point-to-point and |
| 55 | +queue-based architectures, you can also change the arrow directions to better highlight something |
| 56 | +more pub/sub or topic-based. |
| 57 | + |
| 58 | +[](/images/queues-and-topics/4.png) |
| 59 | + |
| 60 | +This version of the diagram better shows the roles of the message publishers and subscribers. Again, it's just a |
| 61 | +different way of telling the same story. |
| 62 | + |
| 63 | +## Summary |
| 64 | + |
| 65 | +There are a number of ways to diagram message-based architectures, with the latter two of the following being "correct": |
| 66 | + |
| 67 | +- Incorrect: Model the message bus as a C4 container. |
| 68 | +- Correct: Explicitly model queues and topics as C4 containers. |
| 69 | +- Correct: Implicitly model message-based interactions using a "via" notation on relationships. |
| 70 | + |
| 71 | +## Further considerations |
| 72 | + |
| 73 | +The examples presented have assumed that a single software system is comprised from a number of services communicating |
| 74 | +via queues and topics. In other words, everything on the diagram sits "inside" the software system boundary, and is |
| 75 | +"owned" by that single software system. |
| 76 | + |
| 77 | +If you've read the [microservices](/abstractions/microservices) recommendations and you're modelling each |
| 78 | +service as a separate software system, you additionally need to consider who "owns" the queues and topics. |
| 79 | +If service A (a software system) has a point-to-point relationship with service B (also a software system) |
| 80 | +via a queue named X (a container) ... who owns the container? Does service A own the definition of the message format |
| 81 | +and operation of the queue, or is it service B? Or perhaps it's jointly owned, or owned by somebody else entirely. |
| 82 | +Ownership will impact the diagrams. |
0 commit comments