Dead-Letter Topic Partition Selection

默认情况下,记录使用与原始记录相同的分区发布到 Dead-Letter 主题。这意味着 Dead-Letter 主题必须至少与原始记录有相同数量的分区。

By default, records are published to the Dead-Letter topic using the same partition as the original record. This means the Dead-Letter topic must have at least as many partitions as the original record.

要更改此行为,请将 DlqPartitionFunction 实现作为 @Bean 添加到应用程序上下文中。只能存在一个此类 bean。该函数随消费组、失败的 ConsumerRecord 和异常一起提供。例如,如果你希望始终路由到分区 0,则可以使用:

To change this behavior, add a DlqPartitionFunction implementation as a @Bean to the application context. Only one such bean can be present. The function is provided with the consumer group, the failed ConsumerRecord and the exception. For example, if you always want to route to partition 0, you might use:

@Bean
public DlqPartitionFunction partitionFunction() {
    return (group, record, ex) -> 0;
}

如果您将消费者绑定的 dlqPartitions 属性设置为 1(并且黏合剂的 minPartitionCount 等于 1),则无需提供 DlqPartitionFunction;框架将始终使用分区 0。如果您将消费者绑定的 dlqPartitions 属性设置为大于 1 的值(或者黏合剂的 minPartitionCount 大于 1),则即使分区计数与原始主题相同,您 must 也会提供一个 DlqPartitionFunction Bean。

If you set a consumer binding’s dlqPartitions property to 1 (and the binder’s minPartitionCount is equal to 1), there is no need to supply a DlqPartitionFunction; the framework will always use partition 0. If you set a consumer binding’s dlqPartitions property to a value greater than 1 (or the binder’s minPartitionCount is greater than 1), you must provide a DlqPartitionFunction bean, even if the partition count is the same as the original topic’s.

也可以为 DLQ 主题定义自定义名称。为此,请将 DlqDestinationResolver 实现作为 @Bean 创建到应用程序上下文中。当绑定检测到此类 bean 时,它将优先,否则它将使用 dlqName 属性。如果未找到其中任何一个,它将默认为 error.<destination>.<group>。下面是 DlqDestinationResolver@Bean 示例。

It is also possible to define a custom name for the DLQ topic. In order to do so, create an implementation of DlqDestinationResolver as a @Bean to the application context. When the binder detects such a bean, that takes precedence, otherwise it will use the dlqName property. If neither of these are found, it will default to error.<destination>.<group>. Here is an example of DlqDestinationResolver as a @Bean.

@Bean
public DlqDestinationResolver dlqDestinationResolver() {
    return (rec, ex) -> {
        if (rec.topic().equals("word1")) {
            return "topic1-dlq";
        }
        else {
            return "topic2-dlq";
        }
    };
}

在提供 DlqDestinationResolver 的实现时需要记住的一件重要事情是,绑定中的供应者不会为应用程序自动创建主题。这是因为绑定无法推断出实现可能发送到的所有 DLQ 主题的名称。因此,如果你使用此策略提供了 DLQ 名称,则应用程序有责任确保事先创建了那些主题。

One important thing to keep in mind when providing an implementation for DlqDestinationResolver is that the provisioner in the binder will not auto create topics for the application. This is because there is no way for the binder to infer the names of all the DLQ topics the implementation might send to. Therefore, if you provide DLQ names using this strategy, it is the application’s responsibility to ensure that those topics are created beforehand.