activemq
Java开发的,在内嵌到项目中比较方便
单机吞吐量万级
可以做主从、高可用
可能丢消息
官方维护已经很少
Rabbitmq(非分布式)(支持消息的事务)
在rabbitmq中创建几万的topic是很容易的,所以可以做到每个硬件订阅不同的topic
而kafka的topic在分布式情况下需要同步到其他broker,还需要经过zookeeper
rabbitmq可以通过java程序中调用declareExchange、declareQueue、declareQueue来实现mq的创建
吞吐量到万级,单机几万
Erlang开发,延时很低
有管理界面,适合中小企业管理
社区活跃
国内公司用的多
但,erlang定制开发难度大
在普通集群模式(不是高可用的),元数据是多份的,但是queue数据只有一份,
优点:可以提高吞吐量
缺点:
1、内部大量数据传输
2、只有一份数据,可靠性是没有保证的
镜像集群模式(是高可用的),每个节点都有完整的一份数据
不是分布式的,一个节点上有一份完整的数据,容量达到该机器的容量无法容纳,就挂掉了
Rabbitmq保证数据不丢的方案
生产者confirm模式:开启发送方确认模式:channel.confirmSelect();
//普通confirm模式:channel.waitForConfirms()
异步confirm模式:
生产者发送消息后,rabbitmq收到消息后会回调生产者,需要提供一个正常回调一个失败回调:addConfirmListener(handleAck和handleNack)
异步confirm模式中,通过deliveryTag区分是哪条消息
消费者关闭autoAck模式:
消费者ack删掉消息,消费者nack把消息放回队列
可以开启持久化,未持久化的数据可能丢失
RocketMQ
单机吞吐量上十万
Topic可以有很多
分布式架构
可靠性高
国内的公司开发,万一rocketmq被阿里抛弃,那项目就废了
如果在大型公司,可以投入一组java高级开发研究rocketmq,进行定制开发
Kafka
如果有集群要求,那kafka当仁不让
如果个别Topic消息量非常大,kafka当仁不让(因为rabbitmq和activemq不好解决)
10万级别
Topic从几十个到几百个的时候吞吐量会急剧下降
极低的延时
消息可能被重复消费
最好不要太多的topic
一个partition一个消费者
适合于大数据方面、实时计算、日志处理
分布式:一个topic的每条数据存放在不同的partition上,partition在不同的机器上
0.8版本以后提供副本机制,会选举leader和follower,需要设置副本的数量,类似HadoopFS
Zookeeper中记录partition中的offset,消费者消费完不直接提交,而是定时定期提交
高可用:
生产者配置acks=all(spring.kafka.producer.acks=all),确保所有broker中数据都已写成功后返回,retries=MAX无限次重试
消费者关闭自动提交offset(enable.auto.commit 改成 false )spring.kafka.consumer.enable-auto-commit=false
consumer.commitSync();
@KafkaListener方法中通过Acknowledgment ack注入ack的操作类
通过ack.acknowledge()手动提交偏移量
中小型推荐用RabbitMq
中大型推荐用RocketMq
大数据kafka
MQ的作用
1、解耦:A调用BCD,原来:增加EF调用、减少CD调用都要修改A,而通过MQ后只要增加一个订阅者、去掉一个订阅者既可
2、提高响应速度:数据发往mq后立即返回,后续程序再处理数据
3、削峰、容峰:缓冲突然来的几万个请求
MQ的副作用
系统可用性会降低
系统复杂性会更高
插入两条数据问题(可以在mq之前通过雪花算法的唯一键解决重复消费问题)
每次重启消费者,可能导致多次消费
建议在生产者端使用雪花算法产生唯一键,消费者端用insert or update方法保存数据