重要的知识点,禁止并发消费,加锁这样就不会多线程同时访问一个队列造成无序。
consumer会平均分配queue的数量进行消费的,一个consumer同时可以消费一个队列的多个消息,要保证顺序消费就要加锁的。
一个消费者是一个线程池。
第一步:还原为最简单的代码
第二步:在队头或者队尾部消费只是初次启动第一次有效,第二次重启的时候以后都是按照上一次的消费点往后消费的。
代码:
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
第三个几乎不用。
第三步:负载均衡策略算法。
一个topic有很多的队列,我们要分配到consumer里面去,这需要算法,默认是负载均衡的算法。
consumer.setAllocateMessageQueueStrategy(new AllocateMessageQueueStrategy());
第四步:消费 进度的存储。
consumer消费消息之后要标记下,broker也要标记下的。
消息消费两种形式:集群和广播。
//默认是集群方式,可以更改为广播,但是广播方式不支持重试
consumer.setMessageModel(MessageModel.CLUSTERING);
offset的存储位置,广播模式是本地的,集群的是broker的。
consumer.setPullBatchSize(32);
看下线程池的源码:
第五步:
总结:模式和线程可以调,其他的一般不需要调整的。
------01-------------
知识点1:topic下的quene的数量一般要 大于consumer的数量。最好是偶数倍。
知识点2:什么是消费者组,同一个consumerGroup的消费者。
知识点3:我们做下集群模式的验证看下性能。
消费者组分配到的队列那个消费者只消费消息一次的。
知识点4:我们做下广播模式的验证看下性能。
可知:
每个consumer都会消费消息一次。
------------02---------
consumer消费指定的tag,可以在broker过滤也可以在consumer过滤。
offset也是分为broker和consumer过滤。
测试代码:
订阅关系注意一下。
同一个消费者组订阅的topic和tag必须是一样的。
测试1:
生产者:
消费者:
注意一点:被过滤的消息是被抛弃了,新起一个节点是不会消费了。
sql92的:
这个测试的是broker端过滤。consumer过滤自己写逻辑实现的。
测试2:sql语法。
基础知识点:
第一步:打开控制台,看主要节点的配置,确定是不是开启。
第二步:开启 kill掉broker 编辑broker.conf 注意主从都要改的。
第三步:写代码
生产者:
@RequestMapping("/api/v1/pay_cb")
public Object callback(String tag,String amount) throws Exception {
Message message = new Message(JmsConfig.TOPIC,tag, "",tag.getBytes());
message.putUserProperty("amount",amount);
SendResult sendResult = payProducer.getProducer().send(message);
System.out.printf("发送结果=%s, sendResult=%s \n", sendResult.getSendStatus(), sendResult.toString());
return new HashMap<>();
}
消费者:
consumer.subscribe(JmsConfig.TOPIC, MessageSelector.bySql("amount > 5"));
注意点:
原理:
consumer会携带tag到broker,进行hash运算对比。不匹配则跳过。consunmer用原生的tag匹配。
-------------03----------
之前我们一直用的是pushConsumer,然后消费者进行监听。
在控制台查看是什么机制:
不是长轮询就是1s请求一次。
消费端:
可以看出来是拉模被封装了。
pull的方式:
官方的例子:
----04--------------