kafka consumer不能消费消息及其处理办法
来源:互联网 发布:老巴黎西洋家具淘宝网 编辑:程序博客网 时间:2024/04/30 06:18
我这里的Kafka Consumer代码是拷贝网上的,就是开一个线程监听kafka topic,一有消息就处理。开始的代码是这样的:
public void kafkaStart() { final String topic = hipchatAction.properties.getProperty("kafka.hipchat.topic"); final int partitionNum = Integer.valueOf(hipchatAction.properties.getProperty("kafka.hipchat.topic.partitionNum")); log.debug("Comes to kafkaStart() with topic : " + topic + ", partitionNum : " + partitionNum); Map<String, Integer> topicCountMap = new HashMap<>(); topicCountMap.put(topic, partitionNum); Map<String, List<KafkaStream<byte[], byte[]>>> streams = connector.createMessageStreams(topicCountMap); List<KafkaStream<byte[], byte[]>> partitions = streams.get(topic); ExecutorService executor = Executors.newFixedThreadPool(partitionNum * 2); for (KafkaStream<byte[], byte[]> partition : partitions) { /** * Here also it is an unknown issue, if use anonymous inner class, then the thread seems died, must have * a named inner class! */ executor.execute(new MessageRunner(partition)); } } class MessageRunner implements Runnable { private KafkaStream<byte[], byte[]> partition; MessageRunner(KafkaStream<byte[], byte[]> partition) { this.partition = partition; } public void run() { ConsumerIterator<byte[], byte[]> it = partition.iterator(); while (it.hasNext()) { MessageAndMetadata<byte[], byte[]> msgMeta = it.next(); /** * In order to consume Chinese message, here should use charset. */ String jsonStr = new String(msgMeta.message(), StandardCharsets.UTF_8); log.debug("********* Message to be consumed in UTF-8 is :: " + jsonStr); KafkaMsgVO msg = new Gson().fromJson(jsonStr, KafkaMsgVO.class); hipchatAction.sendMessageToRoom(msg.getRoomName(), msg.getToken(), msg.getMsgText()); } } }
方法kafkaStart()会在Spring容器启动的时候执行。
对于 KafkaMsgVO msg = new Gson().fromJson(jsonStr, KafkaMsgVO.class); 这行,因为我的程序对消息要求是一个对象名为 KafkaMsgVO 的JSON格式数据,但是测试的时候测试人员就随便发了一条消息,没有进行对象的属性赋值并组装成 JSON 数据,所以抛出 JSONSyntaxException。问题就出在这,因为一旦抛出异常,这个线程就被破坏了,没办法进行后续消息的消费,尽管 kafka consumer 仍然能感知到 topic 里面有新的消息到来。
解决办法:
为了不让异常破坏 consumer 线程,我进行了出错代码的位置转移,将得到的消息直接通过 Apache AKKA 进行转发,然后由 AKKA 的 onReceive() 对消息进行处理,也就是出错代码移到 onReceive() 里面,这样就保证了 consumer 线程的健壮性。代码如下:
class MessageRunner implements Runnable { private KafkaStream<byte[], byte[]> partition; MessageRunner(KafkaStream<byte[], byte[]> partition) { this.partition = partition; } public void run() { ConsumerIterator<byte[], byte[]> it = partition.iterator(); while (it.hasNext()) { MessageAndMetadata<byte[], byte[]> msgMeta = it.next(); /** * In order to consume Chinese message, here should use charset. */ String jsonStr = new String(msgMeta.message(), StandardCharsets.UTF_8); log.debug("********* Message to be consumed in UTF-8 is :: " + jsonStr); ActorRef sender = akkaSystem.getMsgConductor(); sender.tell(new AkkaAdaptor(jsonStr, hipchatAction), sender); } } }
一旦消息被 AKKA 转发后,对消息的处理代码就放在了AKKA 的 Actor 里面了:
} else if (message instanceof AkkaAdaptor) {AkkaAdaptor akkaAdaptor = (AkkaAdaptor)message;String textMessage = akkaAdaptor.getTextMessage();KafkaMsgVO msg = null;try {msg = new Gson().fromJson(textMessage, KafkaMsgVO.class);} catch (Exception e) {log.debug(textMessage + " is malformed, it may miss some important property (value).");return;}HipchatAction hipchatAction = akkaAdaptor.getHipchatAction();log.debug("Kafka message sent by AKKA is :: " + msg.getMsgText());hipchatAction.sendMessageToRoom(msg.getRoomName(), msg.getToken(), msg.getMsgText());}
0 0
- kafka consumer不能消费消息及其处理办法
- Kafka消费组(consumer group)
- Kafka消费组(consumer group)
- Kafka接收消息(Consumer)
- Kafka Consumer机制优化-保证每条消息至少消费一次
- kafka的消息消费机制、consumer的负载均衡、文件存储机制
- kafka单机不能发送信息和消费消息
- kafka无法消费消息
- Kafka消费组(consumer group)(转)
- 总结kafka的consumer消费能力很低的情况下的处理方案
- 总结kafka的consumer消费能力很低的情况下的处理方案
- 总结kafka的consumer消费能力很低的情况下的处理方案
- .net Kafka.Client多个Consumer Group对Topic消费不能完全覆盖研究总结(二)
- .net Kafka.Client多个Consumer Group对Topic消费不能完全覆盖研究总结(一)
- 本地Consumer和Producer无法使用远程Kafka服务器的处理办法
- 本地Consumer和Producer无法使用远程Kafka服务器的处理办法
- kafka消息发送-消费流程
- RocketMQ原理解析-consumer 5.push消费-顺序消费消息
- 0136 Spring的七大模块简介
- Apache Thrift 中篇
- MapReduce工作原理图文详解
- Spring事务管理—aop:pointcut expression解析
- codeforce 343div2 C dp好题
- kafka consumer不能消费消息及其处理办法
- EditText在启动Activity时不自动获取焦点
- Qt之QTableView添加复选框(QAbstractItemDelegate)
- docker安装
- 关于background-size各个参数详解
- Java系统调优:内存管理与垃圾回收
- js加减乘除运算重写
- Apache Thrift 下篇(1)
- fragment管理