Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 卡夫卡消费群体再平衡后的生产者体验_Spring_Apache Kafka_Transactions_Spring Kafka_Kafka Producer Api - Fatal编程技术网

Spring 卡夫卡消费群体再平衡后的生产者体验

Spring 卡夫卡消费群体再平衡后的生产者体验,spring,apache-kafka,transactions,spring-kafka,kafka-producer-api,Spring,Apache Kafka,Transactions,Spring Kafka,Kafka Producer Api,我不能评论类似的话题: 所以我要问一个新问题 用例: 一个主题有两个分区 消费者组“示例消费者组”中并发性为1(默认)的Spring@KafkaListener 同一应用程序的两个实例-都具有相同的“事务id前缀” 1) 我启动第一个应用程序实例(我们称之为“instance1”-即使一切正常-单个消费者订阅两个分区。日志: o.s.k.l.kafkamessagelistenercainer:示例消费者组:分配的分区:[sampleTopic-1,sampleTopic-0] 2) 我启动

我不能评论类似的话题: 所以我要问一个新问题

用例:

  • 一个主题有两个分区
  • 消费者组“示例消费者组”中并发性为1(默认)的Spring@KafkaListener
  • 同一应用程序的两个实例-都具有相同的“事务id前缀”
1) 我启动第一个应用程序实例(我们称之为“instance1”-即使一切正常-单个消费者订阅两个分区。日志:

o.s.k.l.kafkamessagelistenercainer:示例消费者组:分配的分区:[sampleTopic-1,sampleTopic-0]

2) 我启动第二个应用程序实例(instance2)-一切正常-从此实例记录:

o.s.k.l.KafkaMessageListenerContainer:示例消费者组:分配的分区:[sampleTopic-1]

来自“instance1”的日志:

看起来还可以。。。 但是,当我尝试将消息发送到任何其他主题(不是来自任何kafkaListener,而是来自某些@Transactional方法-因此这是仅生产者事务)时,会出现以下错误:

ERROR 4395 --- [roducer-tx-prefix-0] o.a.k.clients.producer.internals.Sender  : [Producer clientId=producer-tx-prefix-0, transactionalId=tx-prefix-0] Aborting producer batches due to fatal error

org.apache.kafka.common.errors.ProducerFencedException: Producer attempted an operation with an old epoch. Either there is a newer producer with the same transactionalId, or the producer's transaction has been expired by the broker.

ERROR 4395 --- [roducer-tx-prefix-0] o.s.k.support.LoggingProducerListener    : Exception thrown when sending a message with key='sync-register' and payload='2020-04-21T13:52:12.148412Z' to topic anotherTopic

那么,对于仅生产者事务,我应该为每个实例使用单独的事务id前缀,这与这个问题有关吗?如果是,当前的状态是什么?如何在不为消费者启动和生产者启动的事务使用单独的kafkaTemplate的情况下实现这一点?

请参阅

如概述中所述,producer factory配置了此属性以生成producer transactional.id属性。在指定此属性时存在一种二分法,即当运行应用程序的多个实例时,在侦听器容器线程上生成记录时,所有实例上的属性必须相同,以满足隔离僵尸(概述中也提到)。但是,当使用不是由侦听器容器启动的事务生成记录时,每个实例上的前缀必须不同。版本2.3使配置更简单,尤其是在Spring引导应用程序中。在以前的版本中,必须创建两个生产者工厂和KafkaTemplate s—一个用于在侦听器容器线程上生成记录,另一个用于由KafkaTemplate.executeInTransaction()或@Transactional方法上的事务拦截器启动的独立事务

现在,您可以在KafkatTemplate和KafkatTransactionManager上覆盖工厂的transactionalIdPrefix

当为侦听器容器使用事务管理器和模板时,您通常会将其默认设置为producer factory的属性。对于所有应用程序实例,此值应相同。对于由模板(或@transaction的事务管理器)启动的事务,应分别在模板和事务管理器上设置属性。此属性在每个应用程序实例上必须具有不同的值


好的,但是文档不够清楚,它声明:“您可以在KafkatTemplate和KafkatTransactionManager上覆盖工厂的transactionalIdPrefix。”。怎么做?是否为仅生产者事务中的每个kafkaTemplate调用手动执行?我是否必须仅在模板上设置它,还是同时在事务管理器上设置它?你能给我一些样品吗?因为我更希望以某种方式配置它一次,这样我就不需要记住为每次调用设置它。同样的kafkaTemplate也可以在消费者启动的事务中使用。您不需要“为每次调用设置它”。它只是工作;当事务管理器启动事务时,模板参与现有事务(使用生产者工厂或TM的transactional.id,如果设置);对于生产者发起的事务,将使用模板本身(如果设置)上配置的
事务ID
。在大多数情况下(一个TM,一个模板),您只需在模板上设置覆盖,以支持同一应用程序中消费者和生产者发起的事务。好的,谢谢。因此,为了使生产者发起的事务在多实例环境中正常工作,我只需在应用程序启动(kafkaTemplate创建)期间调用kafkaTemplate.settransactionIdPrefix方法,并将其设置为每个应用程序实例的某个唯一值?还有一个问题-我在k8s上部署mi服务。正如我正确理解的(从本主题:)-我不能简单地为producer starter事务选择random transactionIdPrefix。它应该是唯一的实例索引吗?但是如果我想减少实例的数量呢?例如,从3到2。来自实例编号“3”的部分事务也永远不会完成?您可以使用随机事务id或索引;没关系;如果实例有序关闭,则事务将完成;如果没有,它将超时。
ERROR 4395 --- [roducer-tx-prefix-0] o.a.k.clients.producer.internals.Sender  : [Producer clientId=producer-tx-prefix-0, transactionalId=tx-prefix-0] Aborting producer batches due to fatal error

org.apache.kafka.common.errors.ProducerFencedException: Producer attempted an operation with an old epoch. Either there is a newer producer with the same transactionalId, or the producer's transaction has been expired by the broker.

ERROR 4395 --- [roducer-tx-prefix-0] o.s.k.support.LoggingProducerListener    : Exception thrown when sending a message with key='sync-register' and payload='2020-04-21T13:52:12.148412Z' to topic anotherTopic