一、MQ遵循投递消息先进先出原则
1.为什么MQ会产生消息顺序的问题?
1.消费者集群
;。
2. MQ服务端如果是集群;
单个消费者:
单个消费者情况下,MQ的队列会根据先进先出的原则,消费的顺序是不会打乱的、。I
当消费者集群:
mq消费者订阅到同一个队列情况时,消费者会做均摊消费
或者是公平消费
。
有可能出现一下情况:
单个消费者情况下,MQ的队列会根据先进先出的原则,消费的顺序是不会打乱的。
2.队列原则:
先进先出
3.MQ消息顺序的行为产生的背景:
1.当我们往MQ中同一个队列投递消息行为不统一的情况 消费者在消费的时候就会产生先后顺序问题
注意:单台消费者是不存在消息的顺序的问题,但是单机版本的消费吞吐比较低,所以一般消费者肯定要集群
。
在多个消费者消费同一个队列中的消息时候,有可能产生消息顺序行为错乱的问题。
三、MQ顺序消息产生的背景有那些
不同broker,相当于不同的服务器,不确定消费者先拿到哪一个服务器 的消息。
四、MQ如何保证消息的顺序性
@RequestMapping("/getOrderKafka")
public String getOrderKafka() {
String orderId = System.currentTimeMillis() + "";
// // 发送insertmsg
sendMsg(getSqlMsg("insert", orderId));
// 发送Updatemsg
sendMsg(getSqlMsg("update", orderId));
// 发送deletemsg
sendMsg(getSqlMsg("delete", orderId));
return "success";
private void sendMsg(String data) {
// topic 名称 key data 消息数据
kafkaTemplate.send("mayikt-topic", data);
}
public String getSqlMsg(String type, String orderId) {
JSONObject dataObject = new JSONObject();
dataObject.put("type", type);
dataObject.put("orderId", orderId);
return dataObject.toJSONString();
}
运行结果:
不同分区 ,单个消费者获取消息的顺序 会不确定。
broke集群,单个消费者,消费消息的顺序会打乱。
五、解决MQ消息顺序的问题核心思路
1、为什么我们的MQ服务器端集群的话,单个消费者消费消息顺序会被打乱?
因为我们的投递消息分别存放到多个不同的Broker存放,单个消费者获取所有的Broker建
立长连接,获取顺序可能是随机的。
参数多了key
orderId作为key, key相同hash值就会相同,则会被分到同一个broker中。一个消费者,必定会按照 存放 先进先出的顺序来消费。
@RequestMapping("/getOrderKafka")
public String getOrderKafka() {
String orderId = System.currentTimeMillis() + "";
send(orderId, getSqlMsg("insert", orderId));
// 发送Updatemsg
send(orderId, getSqlMsg("update", orderId));
// 发送deletemsg
send(orderId, getSqlMsg("delete", orderId));
return "success";
}
/**
* 发送消息的方法
*
* @param key 推送数据的key
* @param data 推送数据的data
*/
private void send(String key, String data) {
// topic 名称 key data 消息数据
kafkaTemplate.send("mayikt-topic", key, data);
}
运行结果:顺序没有被打乱
2、在什么样的情况下,消费者获取消息顺序不会打乱
(同一个 Broker、同一个消费者)。
3、如何解决kafka或者rocketmq消息顺序的问题?
答案:对相同业务逻辑设置相同的消息key,存放到同一个broker,最终对应一个消费者实
现消费。。
六、解决MQ消息顺序的问题总结
1.MQ如何保证消息的顺序的问题?
1.如果我们的生产者往我们的MQ投递消息行为不一样,可能会产生消息顺序的问题,。
如果我们的投递的消息到同一个队列中行为是一样的情况下,没有必要在意消息顺序的问
题。。
2.我们的 MQ存放消息默认的情况下本身就是有一定顺序,遵循先进先出的原则(单个MQ
情况下)。
3. 如果我们有多个消费者订阅同一个队列的情况下,可能会产生消费者顺序会被打乱
4.如果我们的Broker是集群的情况下,因为不同的消息可能会存放多个不同的Broker中,
单个消费者在获取消息的时候顺序可能会被打乱
2.解决消息顺序的核心思路:
保证我们的消息存放到同一个Broker中,对应只有一个消费者实现消费;。
备注: kafka对我们的消息设置相同的key, key 可以根据业务来定。。
但是我们的单个消费者消费消息吞吐非常低,可以采用消费者批量获取我们的消息,让后采
用内存队列实现存放。(也会根据消息都key计算相同的key存放到同一个内存队列中),
每个内存队列只会对应的一个线程实现处理。
3.多个内存队列,等同于 消费者集群。没有解决问题。
kafka严格解决消息顺序问题,只能是 一个消费者来消费
七、kafka的消费者分组的概念设计
1、当所有消费者在同一个分组,有3个分区:
有3个分区,2个消费者时:一定会有一个消费者消费2个分区。
此处演示的是 消费者1 分区0、分区1;消费者2只消费 分区2。保证严格按照顺序来消费。
当有3个消费者时,消费者1会消费 分区1,消费者2会消费 分区2,消费者3会消费 分区3.
1.1、当有2个消费者:
该消费者1只消费 分区0、分区1
该消费者2只消费 分区2
1.2、当有3个消费者:
2、当2个消费者不在同一个组:
消费者1:
消费者2:
不在同一个组,可以重复消费。
3、Kafka的分组的特性:
1.如果多个消费者在同一个组内,最终只会有一个消费者实现消费消息;
2.Kafka分组默认消费者与Broker一对一;
八、为什么kafka吞吐高的原因
1、Kafka吞吐量为什么比较高原因:
- 使用顺序写的形式存储我们的数据。
2.生产者和消费者都支持的批量处理
采用异步形式+缓存区投递消息
缺点:数据可能会产生丢失。
3.数据的零拷贝 NI0支持。
4.实 现对我们的topic分区存放。
5.对我们数据实现压缩、减少带宽传输。。
数据的零拷贝: