kafka的consumer.poll(Long)和consumer.poll(Duration.ofMillis(2000)) 的区别
项目中用到了kafka,没用Streaming,只是用了个简单的kafka连接
最初的使用的是consumer.poll(10) 这样拉取得数据,
发现这样得拉取数据得方式当连接不上kafka时或者连接不正确,或者broker失败,总而言之就是连接不上kafka,会使得程序一直在运行停不下来.
解决办法:使用consumer.poll(Duration.ofMillis(2000)) //此处笔者设置的超时时间为2s ,超过2s没拉到数据就断开。
顺便说一下如何判断自己连接上了Kafka吧
这个问题,我当时时无语了,是网络通信问题,还是其他问题,经理还要证明自己怎么没连接上,百度查也是无果。没连接上就是没数据呗,这样不行。集群地址正确,各种地址都正确,就是拉不到数据,读到的size为0
记住一个吐血的经验:用kafka工具去看,consumer里有没有创建出来消费者,消费者只要没出来,就是没连接上,代码中打印消费者地址无效的,可以打印出来也不代表你连接上了,还有即使你kafka工具连接上了集群,也不代表你项目就连接上了,笔者就出现过这种情况。如果集群地址正确,让人家测测kafka的端口号通了没,这样的情况也是有的,还有host地址配了没,运维的环境地址也得配,都碰到过,哎,说不完的心塞路程。
下面科普下网上查到的不能用poll(Long)原因:
在poll(0) 中consumer会一直阻塞直到它成功获取了所需的元数据信息,之后它才会发起fetch请求去获取数据。虽然poll可以指定超时时间,但这个超时时间只适用于后面的消息获取,前面更新元数据信息不计入这个超时时间。poll(Duration)这个版本修改了这样的设计,会把元数据获取也计入整个超时时间。由于本例中使用的是0,即瞬时超时,因此consumer根本无法在这么短的时间内连接上coordinator,所以只能赶在超时前返回一个空集合。这就是为什么使用不同版本的poll命令assignment不同的原因。
仔细想想为什么社区要做这样的变更?poll(0)这种设计的一个问题在于如果远端的broker不可用了, 那么consumer程序会被无限阻塞下去。用户指定了超时时间但却被无限阻塞,显然这样的设计时有欠缺的。特别是对于Kafka Streams而言,这个设计可能导致的问题在于Stream Thread无法正常关闭。目前源代码中依然有一些无限阻塞的场景,比如之前处理的initTransaction,commitTransaction和abortTransaction也是无限等待。看来后面社区还是需要慢慢地将它们都替换掉,毕竟在分布式系统中没有什么场景是需要绝对地等待的。