[英]ConnectException when one Kafka broker of cluster is down
我有兩個Kafka代理:server1:9092和server2:9092我正在使用Java客戶端向該集群發送消息,這是代碼:
@Test
public void sendRecordToTopic() throws InterruptedException, ExecutionException {
//See at http://kafka.apache.org/documentation.html#newproducerconfigs
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,
"server1:9092,server2:9092");
props.put(ProducerConfig.ACKS_CONFIG, "1");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> producer = new KafkaProducer<String, String>(props);
ProducerRecord<String, String> myRecord =
new ProducerRecord<String, String>("my-replicated-topic", "test", "someValue");
boolean syncSend = true;
if (syncSend) {
//Synchronously send
producer.send(myRecord).get();
} else {
//Asynchronously send
producer.send(myRecord);
}
producer.close();
}
當其中一個代理關閉時,在某些情況下,測試會引發此異常(在此異常示例中,“ server1”已關閉):
2015-11-02 17:59:29,138警告[org.apache.kafka.common.network.Selector]使用server1 / 40.35.250.227 java.net.ConnectException的I / O錯誤:連接被拒絕:在星期日沒有更多信息。位於org.apache.kafka.common.network.Selector.poll(Selector.java:238)處的sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717)處的nio.ch.SocketChannelImpl.checkConnect(本機方法) org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:192)位於org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:191),位於org.apache.kafka.clients。 producer.internals.Sender.run(Sender.java:122)在java.lang.Thread.run(Thread.java:745)
這是我解決問題的方法:
至少需要3個ZooKeeper節點,我必須再配置一個。 這是因為ZK確定領導者的方式需要50%以上的節點才能正常運行。
將此參數添加到ZooKeeper屬性文件:
tickTime = 200
要使用這些其他參數,此參數是必需的:
initLimit=5
syncLimit=2
在生產者中添加此屬性:
props.setProperty(ProducerConfig.RECONNECT_BACKOFF_MS_CONFIG,“ 10000”);
通過"RECONNECT_BACKOFF_MS_CONFIG"
屬性,僅拋出一次WARN(不是無限循環),然后發送消息
我遇到了這個確切的問題,結果是原因是對新配置屬性之一的誤解。
從以前的生產者API遷移時,我尋找了與“ topic.metadata.refresh.interval.ms”等效的東西,並確定了ProducerConfig.METADATA_FETCH_TIMEOUT_CONFIG。 但是,在嘗試訪問元數據被視為失敗之前,這是超時,並且由於我將其設置為幾分鍾,因此可以防止發生故障轉移。
將此值設置為較低的值(我選擇了500ms)似乎已經解決了我的問題。
我相信我最初尋找的值是ProducerConfig.METADATA_MAX_AGE_CONFIG作為刷新元數據之前的超時,無論是否發生故障
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.