kafka用了好久,被一个问题给问住了,不知如何回答。

我家的大花猫 发表于: 2019-12-02   最后更新时间: 2019-12-02 13:34:05   1,773 游览
  1. 我这边用kafka做系统之间的通知,用了好久,突然有人问我,kafka通知代码是否要在本地事物中?这个我不知道如何回答。
  2. 然后我就想,把kafka通知代码放到事物里面,不知道kafka同步发送过程,是否就一定能拿到确定的结果?会不会有超时未决的情况?
  3. 这种系统之间的通知一般,如何处理比较好?
发表于 2019-12-02
¥1.0

你这个问题我懵懂吧,kafka不要涉及到业务,kafka消费者客户端保证把这条消息发给业务层,就结束了,不要牵扯到业务。

如果是生产者,如果发送失败,本身就会等待,除非超时过了一定时间,比如超过10分钟,积压等等。这个时候系统会把错误报错打印出来。错误可以通过异步callback()获得,但无法放事物,同步.get()可以放事物,也可以捕获到异常,但效率就低了。

恩 我说的 场景是 我们作为生产者。我想问的是,我们是否要把发送kafka消息的方法,嵌入到本地事物代码的方法中。如果成功的话,事物就提交了,如果失败的话可以抛出异常,事物进行回滚。这样做是否是可行的。
另外我想问的是,我们使用同步.get()是否就可以获得准确的结果,有没有可能同步.get()超时了,我们的代码也不知道消息有没有发送成功?假设我们把发送kafka消息的方法嵌入到本地事物方法中,有没有这种可能在同步.get()时,本地事物超时了?
其实我想问问您这边的方案(一个系统在提交本地事物的过程中,需要把发消息通知其他的系统)。您这边的建议是,我们把发送kafka的代码放到事物的外面,还是放到事物的里面?
通过您之前的回复,我感觉您是比较倾向于,把发送kafka的代码,放到事物外面。不知道我理解是否有偏差,希望大神可以指明方向,谢谢啦。

放到外面,大家很习惯把场景考虑的非常周全,但是,往往是把系统的搞得异常复杂,从来不出问题的客户端,反而因为改动变得复杂,并且导致的结果反而更大的灾难。系统要解耦,事务绑定kafka,量大了最终会堵死你的线程(你.get()同步的时候,你把网络断了,kafka会等待)。

我推荐的是:

  1. 如果失败,把错误打到日志里,业务告警扫到异常日志之后告警人工干预(这种简单,一般业务失败kafka的消息你根本不会在乎了,我们用了4、5年了,从来没处理过)
  2. 当消息失败后,丢到队列里,或者错误表中,有个定时任务扫描,有错误就告警或者重新丢到kafka里(这种算是闭环)

感谢您的回复,谢谢啦

你的答案

查看kafka相关的其他问题或提一个您自己的问题