我正试图用幂等生产者& amp;其中一家银行使用的交易。
我创建了这样的制作人:
String topicName = "exonce";
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("acks", "all");
props.put("retries", 1);
props.put("batch.size", 16384);
props.put("linger.ms", 1);
props.put("buffer.memory", 33554432);
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("enable.idempotence", "true");
props.put("transactional.id", "1");
props.put("acks", "all");
props.put("transaction.timeout.ms","160000");
Thread.currentThread().setContextClassLoader(null);
Producer<String, String> producer = new KafkaProducer
<String, String>(props);
producer.initTransactions();
producer.beginTransaction();
producer.send(new ProducerRecord<String, String>(topicName, "val_"));
producer.commitTransaction();
System.out.println("Message sent successfully");
producer.close();
但我无法在消费者方面得到任何东西。我也没看到sysout:&#34;消息发送成功&#34;至少sysout应该来/显示。
程序没有结束它等待发生的事情(没有错误/异常)。在等待:producer.initTransactions();线
这是日志:
17/07/12 08:46:36 INFO producer.ProducerConfig:ProducerConfig值: acks = all
batch.size = 16384
bootstrap.servers = [localhost:9092]
buffer.memory = 33554432
client.id =
compression.type = none
connections.max.idle.ms = 540000
enable.idempotence = true
interceptor.classes = null
key.serializer = class org.apache.kafka.common.serialization.StringSerializer
linger.ms = 1
max.block.ms = 60000
max.in.flight.requests.per.connection = 5
max.request.size = 1048576
metadata.max.age.ms = 300000
metric.reporters = []
metrics.num.samples = 2
metrics.recording.level = INFO
metrics.sample.window.ms = 30000
partitioner.class = class org.apache.kafka.clients.producer.internals.DefaultPartitioner
receive.buffer.bytes = 32768
reconnect.backoff.max.ms = 1000
reconnect.backoff.ms = 50
request.timeout.ms = 30000
retries = 1
retry.backoff.ms = 100
transaction.timeout.ms = 160000
transactional.id = 1
value.serializer = class org.apache.kafka.common.serialization.StringSerializer
17/07/12 08:46:36 INFO producer.KafkaProducer:实例化一个事务生产者。
17/07/12 08:46:36 INFO producer.KafkaProducer:由于启用了idempontence,所以将默认的max.in.flight.requests.per.connection覆盖为1。
17/07/12 08:46:37 INFO utils.AppInfoParser:Kafka版本:0.11.0.0
17/07/12 08:46:37 INFO utils.AppInfoParser:Kafka commitId:cb8625948210849f
17/07/12 08:46:37 INFO internals.TransactionManager:[TransactionalId 1] ProducerId设置为-1,epoch -1
我不确定我在这里犯了什么错误。
我正在使用kafka-0.11.0.0
如果您需要更多信息,请告诉我。
感谢您的帮助&amp;支持。
由于
拉吉
答案 0 :(得分:2)
这是单节点安装吗?你能检查一下server.log是否正确创建了__transaction_state
主题吗?它需要3个副本才能创建,并且只在第一个initTransactions
请求中创建。因此,如果您没有足够的代理,主题的创建将失败,initTransactions
请求可能会永久阻止。
答案 1 :(得分:1)
这是我在遵循提示默认情况下需要3个经纪人的提示之后发现的。此外,默认情况下,事务需要同步2个副本。
在我基于Docker的环境中,我因此减少了我的经纪人的这两个设置:
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
这些设置对应于https://kafka.apache.org/0110/documentation.html#brokerconfigs
中记录的设置transaction.state.log.min.isr
transaction.state.log.replication.factor
注意:ISR代表同步副本
还有一个:如果您使用的是汇合的默认平台设置(而不是泊坞窗容器),这些设置已经预先配置好了。
答案 2 :(得分:-1)
尝试在javadoc中运行示例的更新答案,作为使用0.11客户端协议正确配置代理0.11的测试
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("transactional.id", "my-transactional-id");
Producer<String, String> producer = new KafkaProducer<>(props, new StringSerializer(), new StringSerializer());
producer.initTransactions();
try {
producer.beginTransaction();
for (int i = 0; i < 100; i++)
producer.send(new ProducerRecord<>("my-topic", Integer.toString(i), Integer.toString(i)));
producer.commitTransaction();
} catch (ProducerFencedException | OutOfOrderSequenceException | AuthorizationException e) {
// We can't recover from these exceptions, so our only option is to close the producer and exit.
producer.close();
} catch (KafkaException e) {
// For all other exceptions, just abort the transaction and try again.
producer.abortTransaction();
}
producer.close();