Есть отдельный, но достаточно частый класс задач: нужно обрабатывать сообщения параллельно, но, если они относятся к одной сущности, то последовательно.
Можно ввести термин “ключ параллельности”: если он задан, то сообщения с одним ключом должны обрабатываться последовательно.
Некоторые системы очередей поддерживают это из коробки:
- Микрософт называет это https://docs.microsoft.com/en-us/azure/architecture/patterns/sequential-convoy и показывает как реализовать на в облаке Azure
- В ActiveMQ это называется http://activemq.apache.org/message-groups.html
Akka Actors по сути так же являются решением этой проблемы, но в них не разбирался.
В Kafka подобное решается через partition: выбирается какой-то partition key (например “user:1234”, который и определяет ключ параллельности – просто он шире, чем мог бы быть), затем он хешируется и через хеш выбирается одна из партиций. Т.к. внутри партиции определен порядок сообщений и партицию обрабатывает только 1 потребитель, то таким образом гарантируется последовательная обработка сообщений с одним ключом параллельности.
Аналогичный Kafka подход может использоваться и в других очередях с партициями, например NATS.
Понятно, что партиции – это ограничение параллелизации (не может быть больше обработчиков, чем партиций и количество партиций нельзя поменять динамически), но обычно удается выбрать их правильное количество.