因为项目比较大,做了分布式系统,所有远程服务调用请求都是同步执行经常出问题,所以引入了mq
作用 描述
解耦 系统耦合度降低,没有强依赖关系
异步 不需要同步执行的远程调用可以有效提高响应时间
削峰 请求达到峰值后,后端service还可以保持固定消费速率消费,不会被压垮
答:
国内采用的MQ有:ActiveMQ、Kafka、RabbitMQ、RocketMQ,但现在ActiveMQ用的越来越少了。主要做其他三种的调研。
kafka:
1、开发语言: Scala开发
2、性能、吞吐量: 吞吐量所有MQ里最优秀,QPS十万级、性能毫秒级、支持集群部署
3、功能: 功能单一
4、缺点: 丢数据, 因为数据先写入磁盘缓冲区,未直接落盘。机器故障会造成数据丢失
5、应用场景: 适当丢失数据没有关系、吞吐量要求高、不需要太多的高级功能的场景,比如大数据场景。
RabbitMQ:
1、开发语言: Erlang开发
2、性能、吞吐量: 吞吐量比较低,QPS几万级、性能u秒级、主从架构
3、功能: 功能单一
4、缺点: Erlang小众语言开发,吞吐量低,集群扩展麻烦
5、应用场景: 中小公司对并发和吞吐量要求不高的场景。
RocketMQ:
1、开发语言: java开发
2、性能、吞吐量: 吞吐量高,QPS十万级、性能毫秒级、支持集群部署
3、功能: 支持各种高级功能,比如说 延迟消息、事务消息、消息回溯、死信队列、消息积压等等
4、缺点: 官方文档相对简单可能是RocketMQ目前唯一的缺点
5、应用场景: 适当丢失数据没有关系、吞吐量要求高、不需要太多的高级功能的场景,比如大数据场景。
不会,每条消息都会持久化到CommitLog中,每个Consumer连接到Broker后会维持消费进度信息,当有消息消费后只是当前Consumer的消费进度(CommitLog的offset)更新了。
追问:那么消息会堆积吗?什么时候清理过期消息?
4.6版本默认48小时后会删除不再使用的CommitLog文件
消费模型由Consumer决定,消费维度为Topic。
集群消费
1.一条消息只会被同Group中的一个Consumer消费
2.多个Group同时消费一个Topic时,每个Group都会有一个Consumer消费到数据
3.负载均衡模式消费
//ssm
consumer.setMessageModel(MessageModel.CLUSTERING);
//springboot
@RocketMQMessageListener(topic = "topic",consumerGroup = "消费者组名",messageModel = MessageModel.CLUSTERING )
广播消费
1.消息将对一 个Consumer Group 下的各个 Consumer 实例都消费一遍。即即使这些 Consumer 属于同一个Consumer Group ,消息也会被 Consumer Group 中的每个 Consumer 都消费一次。
2.广播模式消费
//ssm
consumer.setMessageModel(MessageModel.BROADCASTING);
//springboot
@RocketMQMessageListener(topic = "topic",consumerGroup = "消费者组名",messageModel = MessageModel.BROADCASTING )
消费消息是push还是pull?
RocketMQ没有真正意义的push,都是pull,虽然有push类,但实际底层实现采用的是长轮询机制,即拉取方式
broker端属性 longPollingEnable 标记是否开启长轮询。默认开启
源码如下:
// {@link org.apache.rocketmq.client.impl.consumer.DefaultMQPushConsumerImpl#pullMessage()}
// 看到没,这是一只披着羊皮的狼,名字叫PushConsumerImpl,实际干的确是pull的活。
// 拉取消息,结果放到pullCallback里
this.pullAPIWrapper.pullKernelImpl(pullCallback);
补充:
push和pull模式
push模式:客户端与服务端建立连接后,当服务端有消息时,将消息推送到客户端。
pull模式:客户端不断的轮询请求服务端,来获取新的消息。
区别:
Push方式里,consumer把轮询过程封装了,并注册MessageListener监听器,取到消息后,唤醒Messag