为了进行集成测试,我正在创建一个非常简单的单节点 Kafka 部署:
- 1x Zookeeper
- 1 个 Kafka
- 1x Kafka 客户端(例如 AdminClient,创建主题)
(所有内容均干净地部署在全新的 Docker 容器中。)
我发现客户端与 Kafka 之间的连接时常出现故障,但每当我尝试再次连接时,连接都会正常。我在 Kafka 客户端上启用了调试日志记录,以下是我在第一次连接时看到的内容:
客户端可以正常连接到其配置的引导服务器:
[main] DEBUG o.a.k.c.a.i.AdminMetadataManager - [AdminClient clientId=adminclient-1] Setting bootstrap cluster metadata Cluster(id = null, nodes = [kafka:9092 (id: -1 rack: null)], partitions = [], controller = null). [...] [kafka-admin-client-thread | adminclient-1] DEBUG o.apache.kafka.clients.NetworkClient - [AdminClient clientId=adminclient-1] Completed connection to node -1. Fetching API versions.
百行显示请求集群中的节点不会产生任何条目:
[kafka-admin-client-thread | adminclient-1] DEBUG o.a.k.c.a.i.AdminMetadataManager - [AdminClient clientId=adminclient-1] Updating cluster metadata to Cluster(id = q7XgghZqQUW_o5W2-Nn5Qw, nodes = [], partitions = [], controller = null)
nodes = []
请特别注意这里的部分。这种情况至少会持续几秒钟,有时甚至 30 秒!我似乎无法理解为什么 Kafka 服务器无法将自己列为节点。
在一个不幸的情况下,达到了超时,我看到臭名昭著的异常被抛出:
Exception in thread "main" java.util.concurrent.ExecutionException: org.apache.kafka.common.errors.TimeoutException: Timed out waiting for a node assignment.
在幸运的情况下,过了一会儿,它就会自行列出并且可以正常连接:
[kafka-admin-client-thread | adminclient-1] DEBUG o.a.k.c.a.i.AdminMetadataManager - [AdminClient clientId=adminclient-1] Updating cluster metadata to Cluster(id = q7XgghZqQUW_o5W2-Nn5Qw, nodes = [kafka:9092 (id: 0 rack: null)], partitions = [], controller = kafka:9092 (id: 0 rack: null)) [kafka-admin-client-thread | adminclient-1] DEBUG o.apache.kafka.clients.NetworkClient - [AdminClient clientId=adminclient-1] Initiating connection to node kafka:9092 (id: 0 rack: null) using address kafka/xxxxx
注意这里的存在
nodes = [kafka:9092 (id: 0 rack: null)]
。
我的问题是 1 和 2 之间的时间差异很大。我不明白为什么不立即为客户端分配一个节点(在本例中是它自己!)。这不仅减慢了我的自动化测试速度,而且还影响了滚动查看充满超时故障的日志,因为它经常无法在默认超时窗口内连接。然而,等待足够长的时间后,任何后续尝试都会立即成功连接,而不会出现任何奇怪的现象......
Kafka 客户端 + 服务器版本:2.1.0,在 Kubernetes 上运行。Kafka 服务器日志未显示任何特殊信息,在客户端尝试连接前几秒内,所有信息都已静默,直到建立连接后(如果有的话)。
我在这里错过了什么?我是否正在查看随机压力回退,还是必须告诉 Zookeeper/Kafka 可以自行运行,而不必等待其他节点?
我读过了这篇关于监听器配置的臭名昭著的博客文章,但这与我的情况无关:我的 Kafka 一段时间内不会通告节点,直到它通告节点,尽管它有一个通告主机列表。之后,它就可以正常连接了 - 那些在通告监听器方面有问题的人根本无法连接。