13 | Java生产者是如何管理TCP连接的?
该思维导图由 AI 生成,仅供参考
为何采用 TCP?
- 深入了解
- 翻译
- 解释
- 总结
Kafka的Java生产者是如何管理TCP连接的?本文深入探讨了Kafka的通信基于TCP协议的原因以及Java生产者程序的概览。文章首先解释了Kafka选择TCP作为通信协议的主要原因,强调了TCP提供的高级功能和相对简陋的HTTP库在多种编程语言中的限制。随后,文章详细介绍了Kafka的Java生产者API,包括构造生产者对象所需的参数对象、创建KafkaProducer对象实例、使用send方法发送消息以及关闭生产者的步骤。进一步探讨了Kafka的Producer客户端是如何管理TCP连接的,包括TCP连接的创建和关闭时机。文章指出,TCP连接是在创建KafkaProducer实例时建立的,并可能在更新元数据后或消息发送时创建。此外,还讨论了TCP连接的关闭方式,包括用户主动关闭和Kafka自动关闭,以及与connections.max.idle.ms参数相关的设置。最后,文章提出了对Kafka生产者端管理TCP连接方式的挑战,并欢迎读者参与讨论和分享。整体而言,本文深入浅出地解释了Kafka的Java生产者如何管理TCP连接,为读者提供了全面的技术视角和思考空间。
《Kafka 核心技术与实战》,新⼈⾸单¥68
全部留言(87)
- 最新
- 精选
- 注定非凡Apache Kafka的所有通信都是基于TCP的,而不是于HTTP或其他协议的 1 为什采用TCP? (1)TCP拥有一些高级功能,如多路复用请求和同时轮询多个连接的能力。 (2)很多编程语言的HTTP库功能相对的比较简陋。 名词解释: 多路复用请求:multiplexing request,是将两个或多个数据合并到底层—物理连接中的过程。TCP的多路复用请求会在一条物理连接上创建若干个虚拟连接,每个虚拟连接负责流转各自对应的数据流。严格讲:TCP并不能多路复用,只是提供可靠的消息交付语义保证,如自动重传丢失的报文。 2 何时创建TCP连接? (1)在创建KafkaProducer实例时, A:生产者应用会在后台创建并启动一个名为Sender的线程,该Sender线程开始运行时,首先会创建与Broker的连接。 B:此时不知道要连接哪个Broker,kafka会通过METADATA请求获取集群的元数据,连接所有的Broker。 (2)还可能在更新元数据后,或在消息发送时 3 何时关闭TCP连接 (1)Producer端关闭TCP连接的方式有两种:用户主动关闭,或kafka自动关闭。 A:用户主动关闭,通过调用producer.close()方关闭,也包括kill -9暴力关闭。 B:Kafka自动关闭,这与Producer端参数connection.max.idles.ms的值有关,默认为9分钟,9分钟内没有任何请求流过,就会被自动关闭。这个参数可以调整。 C:第二种方式中,TCP连接是在Broker端被关闭的,但这个连接请求是客户端发起的,对TCP而言这是被动的关闭,被动关闭会产生大量的CLOSE_WAIT连接。
作者回复: 总结得相当强:)
2019-10-31649 - 旭杰Producer 通过 metadata.max.age.ms定期更新元数据,在连接多个broker的情况下,producer是如何决定向哪个broker发起该请求?
作者回复: 向它认为当前负载最少的节点发送请求,所谓负载最少就是指未完成请求数最少的broker
2019-07-23427 - 小马老师有个问题请教下: Producer 通过 metadata.max.age.ms 参数定期地去更新元数据信息,默认5分钟更新元数据,如果没建立TCP连接则会创建,而connections.max.idle.ms默认9分钟不使用该连接就会关闭。那岂不是会循环往复地不断地在创建关闭TCP连接了吗?
作者回复: 如果你的producer长时间没有消息需要发送,TCP连接确实会定期关闭再重建的
2020-01-09220 - Frank最近在使用kafka Connector做数据同步服务,在kafka中创建了许多topic,目前对kafka了解还不够深入,不知道这个对性能有什么影响?topic的数量多大范围比较合适?
作者回复: topic数量只要不是太多,通常没有什么影响。如果单台broker上分区数超过2k,那么可能要关注是否会出现性能问题了。
2019-07-1017 - 你好旅行者老师好,看了今天的文章我有几个问题: 1.Kafka的元数据信息是存储在zookeeper中的,而Producer是通过broker来获取元数据信息的,那么这个过程是否是这样的,Producer向Broker发送一个获取元数据的请求给Broker,之后Broker再向zookeeper请求这个信息返回给Producer? 2.如果Producer在获取完元数据信息之后要和所有的Broker建立连接,那么假设一个Kafka集群中有1000台Broker,对于一个只需要与5台Broker交互的Producer,它连接池中的链接数量是不是从1000->5->1000->5?这样不是显得非常得浪费连接池资源?
作者回复: 1. 集群元数据持久化在ZooKeeper中,同时也缓存在每台Broker的内存中,因此不需要请求ZooKeeper 2. 就我个人认为,的确有一些不高效。所以我说这里有优化的空间的。
2019-07-02415 - 蓝魔丶老师,如果Broker端被动关闭,会导致client端产生close_wait状态,这个状态持续一段时间之后,client端不是应该发生FIN完成TCP断开的正常四次握手吗?怎么感觉老师讲的这个FIN就不会再发了,导致了僵尸连接的产生?
作者回复: 问题在于客户端有可能一直hold住这个连接导致状态一直是CLOSE_WAIT。事实上,这是非常正确的做法,至少符合TCP协议的设计。当然,如果客户端关闭了连接,就像你说的,OS会发起FIN给远端
2019-08-04813 - kursk.ye试想一下,在一个有着 1000 台 Broker 的集群中,你的 Producer 可能只会与其中的 3~5 台 Broker 长期通信,但是 Producer 启动后依次创建与这 1000 台 Broker 的 TCP 连接。一段时间之后,大约有 995 个 TCP 连接又被强制关闭。这难道不是一种资源浪费吗?很显然,这里是有改善和优化的空间的。 这段不敢苟同。作为消息服务器中国,连接应该是种必要资源,所以部署时就该充分给予,而且创建连接会消耗CPU,用到时再创建不合适,我甚至觉得Kafka应该有连接池的设计。 另外最后一部分关于TCP关闭第二种情况,客户端到服务端没有关闭,只是服务端到客户端关闭了,tcp是四次断开,可以单方向关闭,另一方向继续保持连接
作者回复: 嗯嗯,欢迎不同意见。Kafka对于创建连接没有做任何限制。如果一开始就创建所有TCP连接,之后因为超时的缘故又关闭这些连接,当真正使用时再次创建,那么为什么不把创建时机后延到真正需要的时候呢?实际场景中将TCP连接设置为长连接的情形并不多见,因此我说这种设计是可以改进的。
2019-07-021211 - 半瓶醋胡夕老师,Kafka集群的元数据信息是保存在哪里的呢,以CDH集群为例,我比较菜:)
作者回复: 最权威的数据保存在ZooKeeper中,Controller会从ZooKeeper中读取并保存在它自己的内存中,然后同步部分元数据给集群所有Broker
2020-05-1328 - yzh老是您好,咨询两个问题。 1. Producer实例创建和维护的tcp连接在底层是否是多个Producer实例共享的,还是Jvm内,多个Producer实例会各自独立创建和所有broker的tcp连接 2.Producer实例会和所有broker维持连接,这里的所有,是指和topic下各个分区leader副本所在的broker进行连接的,还是所有的broker,即使该broker下的所有topic分区都是flower
作者回复: 1. 这些TCP连接只会被Producer实例下的Sender线程使用。多个Producer实例会创建各自的TCP连接 2. 从长期来看,只和需要交互的Broker有连接
2019-08-208 - 电光火石谢谢老师。有几个问题请教一下: 1. producer连接是每个broker一个连接,跟topic没有关系是吗?(consumer也是这样是吗?) 2. 我们运维在所有的broker之前放了一个F5做负载均衡,但其实应该也没用,他会自动去获取kafka所有的broker,绕过这个F5,不知道我的理解是否正确? 3. 在线上我们有个kafka集群,大概200个topic,数据不是很均衡,有的一天才十几m,有的一天500G,我们是想consumer读取所有的topic,然后后面做分发,但是consumer会卡死在哪,也没有报错,也没有日志输出,不知道老师有没有思路可能是什么原因? 谢谢了!
作者回复: 1. 也不能说没有关系。客户端需要和topic下各个分区leader副本所在的broker进行连接的 2. 嗯嗯,目前客户端是直连broker的 3. 光看描述想不出具体的原因。有可能是频繁rebalance、long GC、消息corrupted或干脆就是一个已知的bug
2019-07-075