我想了解如何设计使微服务保持静止的消息传递 弹性和可扩展性。
a.entity.created
下发布事件,包括在消息正文中创建的实体的 id
等信息。a.entity.created
订阅主题 b-consumers
。这会导致 B 实例之间的负载分布。问题:
a.entity.created.{entityId}
下发布事件,导致许多不同的主题。a.entity.created.*
订阅主题 b-consumers
。这会导致 B 实例之间的负载分布。问题:
a.entity.created
和 partition key 下发布事件。a.entity.created
订阅主题 b-consumers
。这会导致 B 的实例之间的负载分布。由于分区键,关于同一实体的事件将按顺序传递。问题:
答案 0 :(得分:4)
您不需要为每个实体设置单独的主题来确保消息的传递顺序。
相反,根据您的实体 ID(或实体的其他不可变标识符)为每条消息分配一个 partition key,以确保有关同一实体的事件始终传递到每个主题的同一分区。
>即使多个生产者实例为同一实体发布消息,分区上消息的时间顺序通常也会保留(例如,如果 A1 和 A2 都发布实体 E1 的消息,则 E1 的分区键将确保所有 E1消息被传送到同一个分区,P1。)。在某些边缘情况下,不会保留排序(例如,生产者失去连接),在这种情况下,您可以查看 enabling idempotence。
你是对的,在任何时候,一个消费者组中最多有一个消费者会订阅一个主题分区,尽管一个消费者可以被分配到多个分区。所以例如消费者 B2 可能会处理来自分区 P1(按顺序)以及来自另一个分区的所有消息。如果一个消费者死亡,那么另一个消费者将被分配到该分区(转换可能需要几秒钟)。
当在消息上提供分区键时,默认情况下,分区分配的消息是基于分区键的散列完成的。在极少数情况下(例如,实体分区键很少),这可能会导致消息在分区上分布不均匀,在这种情况下,如果您发现吞吐量受到不平衡的影响,您可以提供自己的 partitioning strategy。< /p>
基于上述,在 configuring an appropriate number of partitions 对于您的场景之后,您应该能够使用一致的分区键来满足您的设计目标,而根本不需要对 Kafka 进行过多的自定义。