RabbitMQ是使用erlang语言开发的开源消息队列系统,完整的实现了AMPQ(高级抽象层消息通信协议)。
1.使用Homebrew安装
$ brew install rabbitmq
2.修改 ~/.bash_profile 配置环境变量:
# RabbitMQ Config
export PATH=$PATH:/usr/local/sbin
3.重启配置
$ source ~/.bash_profile
4.启动mq服务(后台启动为rabbitmq-server -detached)
$ rabbitmq-server
Virtual vhosts
virtual vhosts是一个命名空间,可以存在多个exchange和queue。实现了环境(用户,用户组,exchange,queue)隔离,是权限控制的最小粒度。默认的virtual host为/。
Exchange(交换机)
接受producer发送的消息,并根据binding绑定规则转发到对应的队列。默认是无名交换使用空字符串标识。exchange type(交换机类型)包含四种类型:direct,topic,headers,fanout
direct
转发消息到routigKey指定的队列
topic
类似于direct类型,只不过routigKey为一个句点号“.”分隔的字符串
*可以替代一个字。
#可以替换零个或多个单词。
headers
根据发送的消息内容中的headers属性进行匹配。
fanout
将所有收到的消息广播到所有已知的队列。
Queue(消息队列)
queue是mq内部对象,用于存储未被customer消费的消息。相同属性的queue可以重复定义,每个消息都会被投入到一个或多个队列。
Binding(绑定)
binding是将exchange和queue按照路由规则绑定起来。可以理解为binding是exchange和queue之间的关系
Connection(连接)
消息tcp连接
Channel(信道)
每个connection里,可建立多个channel,每个channel代表一个会话任务。做到尽量共用connection
1.Round-robin dispathching循环分发
RabbbitMQ的分发机制非常适合扩展,而且它是专门为并发程序设计的,如果现在load加重,那么只需要创建更多的Consumer来进行任务处理。
2.Message acknowledgment消息确认
为了保证数据不被丢失,RabbitMQ支持消息确认机制,为了保证数据能被正确处理而不仅仅是被Consumer收到,那么我们不能采用no-ack,而应该是在处理完数据之后发送ack.
在处理完数据之后发送ack,就是告诉RabbitMQ数据已经被接收,处理完成,RabbitMQ可以安强调内容全的删除它了.
如果Consumer退出了但是没有发送ack,那么RabbitMQ就会把这个Message发送到下一个Consumer,这样就保证在Consumer异常退出情况下数据也不会丢失.
RabbitMQ它没有用到超时机制.RabbitMQ仅仅通过Consumer的连接中断来确认该Message并没有正确处理,也就是说RabbitMQ给了Consumer足够长的时间做数据处理。
如果忘记ack,那么当Consumer退出时,Mesage会重新分发,然后RabbitMQ会占用越来越多的内存.
RabbitMQ使用ProtoBuf序列化消息,它可作为RabbitMQ的Message的数据格式进行传输,由于是结构化的数据,这样就极大的方便了Consumer的数据高效处理,当然也可以使用XML,与XML相比,ProtoBuf有以下优势:
1.简单
2.size小了3-10倍
3.速度快了20-100倍
4.易于编程
5.减少了语义的歧义.
另外,ProtoBuf具有速度和空间的优势,使得它现在应用非常广泛;
方案一:
Rabbitmq在启动时,为rabbitmq设置一个status,在第一次建立连接的时候将其变为true,rabbitmq client在初始化时启动一个定时器,每隔一段时间开启一个线程,查询当前status的状态,如果status变为false,重新建立连接(包括connection、channel的连接)。
方案二:
Implement shutdown listener,如果rabbitmq断线,在shutdown方法执行相应的重连方法。
首先我们可以确认的是,触发消息重复执行的条件会是很苛刻的! 也就说 在大多数场景下不会触发该条件!!! 一般出在任务超时,或者没有及时返回状态,引起任务重新入队列,重新消费! 在rabbtimq里连接的断开也会触发消息重新入队列。
消费任务类型最好要支持幂等性,这样的好处是 任务执行多少次都没关系,顶多消耗一些性能! 如果不支持幂等,比如发送信息? 那么需要构建一个map来记录任务的执行情况! 不仅仅是成功和失败,还要有心跳!!! 这个map在消费端实现就可以了!!! 这里会出现一个问题,有两个消费者 c1, c2 ,一个任务有可能被c1消费,如果再来一次,被c2执行? 那么如何得知任务的情况? 任务派发! 任务做成hash,固定消费者!
动力节点在线课程涵盖零基础入门,高级进阶,在职提升三大主力内容,覆盖Java从入门到就业提升的全体系学习内容。全部Java视频教程免费观看,相关学习资料免费下载!对于火爆技术,每周一定时更新!如果想了解更多相关技术,可以到动力节点在线免费观看RabbitMQ视频教程学习哦!
提枪策马乘胜追击04-21 20:01
代码小兵92504-17 16:07
代码小兵98804-25 13:57
杨晶珍05-11 14:54