rocketmq概念总结

一、RocketMQ是一款分布式、队列模型的消息中间件,单机支持1万以上的持久化队列,前提是足够的内存、硬盘空间。

消息队列主要的应用场景:异步处理,应用解耦,流量削峰,消息通讯。

天然支持负载均衡,消费者组里的消费者实例平均分摊消费消息。activemq是通过取模来均衡,但是动态加载集群节点时,还需要重新调整取模方法。

如果服务器内存不够,可以修改runserver.sh脚本(mqnamesrv文件中通过runserver.sh脚本调用Name Server的主函数com.alibaba.rocketmq.namesrv.NamesrvStartup启动Name Server)中的JAVA_OPT参数

调整优化后的配置:

# JVM Configuration
#===========================================================================================
JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn512m -XX:PermSize=128m -XX:MaxPermSize=320m"


二、RMQ的结构分为四个部分:生产者、消费者、nameserver、brokerserver
nameserver:nameserver接收broker的请求,注册broker路由信息;
brokerserver:消息的接收和推送;
生产者:发送消息,将消息推送给brokerserver;
消费者:接收消息,从brokerserver上获取消息。
一定要保证先启动消费端,再启动provider,否则消费者集群会导致消息的重复消费。

三、Broker 消息中转角色,负责存储消息,转收消息,一般也称为 Server,可以把它理解为mq本身。
Broker集群有多种配置方式:
1,单Master,可以忽略
2,多master,这种方式可以应用于大多数系统的生产环境,只要不是涉及到钱的业务,也就是说对消息的实时性没有要求且容许丢失少量消息,对于丢失的消息,可以通过消息的唯一键持久化到数据库,定时再做一次处理
3,多Master多Slave,这种方式可以保证消息的实时消费,保证消息不会丢失。集群可以采用异步复制和同步双写方式,这两种方式是针对主从关系而言的,异步复制性能较高,但是可能数据丢失,同步双写可能阻塞,性能比异步集群略低
Master与Slave通过指定相同的brokerName参数来配对,Master的BrokerId必须是0,Slave的BrokerId必须是大于0的数。一个Master下面可以挂载多个Slave,同一Master下的多个Slave通过指定不同的BrokerId来区分

 

四、一个应用尽可能用一个 Topic,消息子类型用 tags 来标识,tags 可以由应用自由设置。只有收送消息设置了tags,消费方在订阅消息时,才可以利用 tags 在 broker 做消息过滤。 
服务器会为每个消息创建索引(哈希索引),应用可以通过 topic,key 来查询返回消息内容,以及消息被谁消费。
在rocketmq里,consumer被分为2类:MQPullConsumer和MQPushConsumer,其实本质都是拉模式(pull),即consumer轮询从broker拉取消息。
send 消息方法,只要不抛异常,就代表发送成功。

五、Producer 向一些队列轮流发送消息,队列集合称为 Topic,Consumer 如果做广播消费,则一个 consumer实例消费这个 Topic 对应的所有队列,如果做集群消费,则多个 Consumer 实例平均消费这个 topic 对应的队列集合。 

六、所谓消息队列,无外乎两次RPC加一次转储。
消息转储,是在更合适的时间点投递,或者通过一系列手段辅助消息最终能送达消费机。说白了,mq所做的就是把一次RPC做成两次RPC,即发送者把消息投递到服务端,服务端再将消息转发一手到接收端。既然是RPC,就必然牵扯出一系列话题:负载均衡、服务发现、通信协议、序列化协议等等,这些可以直接利用公司现有的框架,比如dubbo、Thrift等。
其实所有的高可用,是依赖于RPC和存储的高可用来做的。
存储可以做成很多方式。比如存储在内存里,存储在分布式KV里,存储在磁盘里,存储在数据库里等等。但归结起来,主要有持久化和非持久化两种。理论上,从速度来看,文件系统>分布式KV(持久化)>分布式文件系统>数据库,而可靠性却截然相反。


能不能保证完全不丢消息,答案是肯定的,但是可能会出现消息重复,原因是:对于各种不确定(超时、down机、消息没有送达、送达后数据没落地、数据落地了回复没收到),其实对于发送方来说,都是一件事情,就是消息没有送达。所以重复消息是不可能100%避免的,除非可以允许丢失,那么,顺序消息能否100%满足呢?答案是可以,但条件更为苛刻:允许消息丢失。
一般来讲,对于mq来讲,应该是不丢消息的前提下,尽量减少重复消息,不保证消息的投递顺序。每一个消息应该有它的唯一身份,如果有地方记录这个MessageId,消息到来是能够进行比对就能完成重复的鉴定。

什么是事务型消息?
银行转账的扣钱和加钱需要事务保证,但下单和生成短信却不需要事务,前者即为事务型消息,对事务的使用应尽量低成本、透明化,可以依托于现有的成熟框架,如spring的声明式事务做扩展,只需使用 @Transaction

七、pull 与 push对比
慢消费无疑是push模型最大的致命伤,如果消费者的速度比发送者的速度慢很多,势必造成消息在broker的堆积。假设这些消息都是有用的无法丢弃的,消息就要一直在broker端保存。当然这还不是最致命的,最致命的是broker给consumer推送一堆consumer无法处理的消息,consumer不是reject就是error,然后来回踢皮球。

反观pull模式,consumer可以按需消费,不用担心自己处理不了的消息来骚扰自己,而broker堆积消息也会相对简单,无需记录每一个要发送消息的状态,只需要维护所有消息的队列和偏移量就可以了。在阿里的RocketMq里,有一种优化的做法-长轮询,来平衡推拉模型各自的缺点。但海量的长连接block对系统的开销还是不容小觑的,还是要合理的评估时间间隔,给wait加一个时间上限比较好~

二者区别是:
push方式里,consumer把轮询过程封装了,并注册MessageListener监听器,取到消息后,唤醒MessageListener的consumeMessage()来消费,对用户而言,感觉消息是被推送过来的。
pull方式里,取消息的过程需要用户自己写,首先通过打算消费的Topic拿到MessageQueue的集合,遍历MessageQueue集合,然后针对每个MessageQueue批量取消息,一次取完后,记录该队列下一次要取的开始offset,直到取完了,再换另一个MessageQueue。

八、rocketmq强大的地方在于消息重试、顺序消费以及事务消费,除此之外,并发处理以及消息堆积的能力也是很强大的

消息重试:重试有两种:provider端的重试,默认是重试3次,consumer端的重试会一直进行下去,只不过第三次开始越来越慢,消费端可以通过getReconsumeTimes获取消息重试的次数,消息的重复消费是无法避免的,如果业务对重复非常敏感,需要在业务逻辑上处理,(幂等)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值