`
wxl24life
  • 浏览: 293306 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

故障:Kafka异步发送致使所有相关线程阻塞

阅读更多

这个故障在我们前段时间线上服务碰到过,具体的问题描述跟KAFKA-1415里提及的完全一样。

简单概括就是,正常情况下,使用kafka异步producer.send()发送消息时,会在后台创建一个守护线程,通过jstack查看jvm线程堆栈信息会找到这个线程,默认名称:ProducerSendThread-。ProducerSendThread驻留在后台,负责将待发送的消息批量往kafka topic转移。

"ProducerSendThread-" prio=10 tid=0x00007f6b3c01c800 nid=0x40fa waiting on condition [0x00007f6b90510000]   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00007f6bc6d53cd8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
        at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:424)
        at kafka.producer.async.ProducerSendThread$$anonfun$processEvents$1.apply(ProducerSendThread.scala:66)
        at kafka.producer.async.ProducerSendThread$$anonfun$processEvents$1.apply(ProducerSendThread.scala:66)
        at scala.collection.immutable.Stream$.continually(Stream.scala:1104)
        at scala.collection.immutable.Stream$$anonfun$continually$1.apply(Stream.scala:1104)
        at scala.collection.immutable.Stream$$anonfun$continually$1.apply(Stream.scala:1104)

在我们的故障发生时,ProducerSendThread线程莫名其妙死掉了(具体原因未知-_-||),致使调用producer.send() 的所有线程全部阻塞。这是因为,当后台发送线程不工作,消息会在内存不断积压,当达到queue.buffering.max.messages(默认值10000)设定的queue消息数上限,调用producer.send() API发送消息的线程就会一直阻塞。可见此次故障还是很严重的,而我们之所以选择异步发送方式,初衷是不妨碍主业务线程的运行,但是却发现如此隐患,确实有点措手不及。

 

KAFKA-1415 评论里有人给出了一种临时解决方案,将queue.enqueue.timeout.ms设置成某个正数值,作为send超时时长,达到此超时时长后,会抛QueueFullException,消息会被丢弃掉。由于这种方式需要丢弃消息,对于一些应用可能并不合适。另外,在kafka 0.8之后的版本里,queue.enqueue.timeout.ms的默认值是-1,表示后台消息queue积压到上限后将一直等待,直到queue空间释放。在更早的版本里,这个值的默认值是0,表示达到queue上限后,立即抛弃消息,虽然send线程不会block,但是很容易丢消息,尤其是当queue短暂积满的情况,关于默认值的讨论可以参考 KAFKA-709

 

故障引发的思考:

1. 结合故障看,后台守护线程只启动一个,这本身就是一个很大的隐患。需要思考的是,为何只设置一个线程?能否提升线程数?

2. 后台线程怎么就莫名其妙死掉了?

 

其他参考链接:

1. [Kafka-users] Issues with Kafka async producer's enqueue timeout

分享到:
评论
1 楼 DEMONU 2016-12-23  
楼主找到撒原因了吗

相关推荐

Global site tag (gtag.js) - Google Analytics