我有一个正在使用future进行异步执行的应用程序 我在get方法上设置了参数,该线程应该在10秒后被杀死,当它没有得到响应时:
Future<RecordMetadata> meta = producer.send(record, new ProducerCallBack());
RecordMetadata data = meta.get(10, TimeUnit.SECONDS);
但该线程在60秒后被杀死:
java.util.concurrent.ExecutionException: org.apache.kafka.common.errors.TimeoutException: Failed to update metadata after 60000 ms.
at org.apache.kafka.clients.producer.KafkaProducer$FutureFailure.<init>(KafkaProducer.java:1124)
at org.apache.kafka.clients.producer.KafkaProducer.doSend(KafkaProducer.java:823)
at org.apache.kafka.clients.producer.KafkaProducer.send(KafkaProducer.java:760)
at io.khinkali.KafkaProducerClient.main(KafkaProducerClient.java:49)
Caused by: org.apache.kafka.common.errors.TimeoutException: Failed to update metadata after 60000 ms.
我做错了什么?
答案 0 :(得分:2)
来自docs:
阻止时间的阈值由max.block.ms确定 它会抛出一个TimeoutException。
在logback.xml中检查Kafka Appender配置,查找:
<producerConfig>max.block.ms=60000</producerConfig>
答案 1 :(得分:1)
我在get方法上设置了参数,该线程应该在10秒后被杀死,当它没有得到响应时:
如果我们谈论的是Future.get(...)
,那么就没有任何事情可以解决这个问题。线程根本。引用javadocs,Future.get(...)
方法:
如果需要,最多等待计算完成的给定时间,然后检索其结果(如果可用)。
如果get(...)
方法超时则会抛出TimeoutException
,但您的线程可以继续运行。如果你想阻止线程运行,那么你需要捕获TimeoutException
,然后调用meta.cancel(true)
,但即使这样也不能保证该线程将被杀死#&#34} 34 ;.这会导致线程被中断,这意味着certain methods will throw InterruptedException
或线程需要检查Thread.currentThread().isInterrupted()
。
java.util.concurrent.ExecutionException:org.apache.kafka.common.errors.TimeoutException:60000毫秒后无法更新元数据。
是的,此超时与Future.get(...)
超时无关。