【RabbitMQ.Clinet笔记】介绍、安装
消息队列(MQ):
是一种应用程序间通讯方法,不需要程序之间直接建立联系。MQ是用于接收、存储、分发消息的独立应用程序。
常见的MQ
ActiveMQ
:基于JMS
RocketMQ
:阿里巴巴的产品,基于JMS
Kafka
:分布式消息系统,亮点:吞吐量超级高,每秒数十万的并发。
RabbitMQ
:由erlang语言开发,基于AMQP协议,在erlang语言特性的加持下,RabbitMQ稳定性要比其他的MQ产品好一些,而且erlang语言本身是面向高并发的编程的语言,所以RabbitMQ速度也非常快。且它基于AMQP协议,对分布式、微服务更友好。
使用场景:
- 异步处理:比如生成订单需要发送邮件、用户积分、优惠券、客服统计、写日志等操作,这样可以提升主流程响应速度;
- 系统解耦:各系统之间统一交互规则,不需要知道其他系统的地址
- 流量削峰:系统的瓶颈一般在数据库上,比如扣减库存、下单;此时可以考虑使用队列将变更请求暂存入队列
- 延迟队列:比如下单24小时未支付,自动取消。以前可能采用定时查询,现在可以改成使用延迟队列,避免无效数据库查询,减轻数据库压力,设置队列24小时后让消费者消费
- 分布式事务:本地消息表+MQ可实现最终一致性
- 数据同步
- 消息分发
RabbitMQ简介
RabbitMQ特点
- 可靠性:RabbitMQ使用一些机制保证可靠性,如:持久化、发布确认、消费确认
- 灵活的路由:在消息进入队列之前,通过
Exchange
来路由消息的。对于典型的路由功能,RabbitMQ
已经提供了一些内置的Exchange
来实现。针对更复杂的路由功能,可以将多个Exchange
绑定在一起,也通过插件机制实现自己的Exchange
。 - 消息集群:多个
RabbitMQ
服务器可以组成一个集群,形成一个逻辑Broker
- 高可用:队列可以在集群中的机器上进行镜像,使得在部分节点出问题的情况下队列仍然可用
- 多种协议:
RabbitMQ
支持多种消息队列协议,比如STOMP
、MQTT
等等 - 跟踪机制:如果消息异常,
RabbitMQ
提供了消息跟踪机制,使用者可以找出发生了什么 - 插件机制:
RabbitMQ
提供了许多插件,来从多方面进行扩展
RabbitMQ中的概念
- Broker:表示消息队列服务器实体
- vhost:虚拟主机,每个
vhost
本质上就是一个mini
版的RabbitMQ
服务器,拥有自己的队列、交换器、绑定和权限机制。可搭建多环境的RabbitMQ服务器,比如开发、测试、正式 - Connection:表示一个网络连接,简单理解为一个
socket
- Channel:信道,建立在
Connection
之上的虚拟连接,和mq交互的接口,定义和绑定queue
、exchange
等接口都是它。为了避免频繁创建连接,所以引入信道复用连接 - Exchange:交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。可以把交换器理解成一个路由表,路由表中有很多路由规则,这些规则将交换器和队列连接起来
- Binding:绑定,它的作用是把
exchange
和queue
按照路由规则绑定起来。一个绑定就是基于路由键将交换器和队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。 - Queue:队列,消息的载体
- RoutingKey:路由关键字,生产者在将消息发送给Exchange的时候,一般会指定一个
routing key
,来指定这个路由规则,而这个routing key
需要与Exchange Type
与binding key
联合使用才能最终生效。
Exchange
Exchange类型:
- Direct:
消息中的路由键(routing key
)如果和Binding
中的binding key
一致, 交换器就将消息发到对应的队列中。 - Fanout:
每个发到fanout
类型交换器的消息都会分到所有绑定的队列上去。fanout
交换器不处理路由键,只是简单的将队列绑定到交换器上,每个发送到交换器的消息都会被转发到与该交换器绑定的所有队列上。很像子网广播 - Topic(主题)
direct
类型的Exchange
路由规则是完全匹配binding key
与routing key
,但这种严格的匹配方式在很多情况下不能满足实际业务需求。topic
类型的Exchange
在匹配规则上进行了扩展,它与direct
类型的Exchage
相似,也是将消息路由到binding key
与routing key
相匹配的Queue中,它约定:routing key
为一个句点号“.”分隔的字符串(每一段字符串称为一个单词),如“stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit”binding key
与routing key
一样也是句点号“. ”分隔的字符串binding key
中可以存在两种特殊字符*
与#
,用于做模糊匹配,其中*
用于匹配一个单词,#
用于匹配零个或多个单词
- headers
headers
类型的Exchange
不依赖于routing key
与binding key
的匹配规则来路由消息,而是根据发送的消息内容中的headers
属性进行匹配。
在绑定Queue
与Exchange
时指定一组键值对;当消息发送到Exchange
时,RabbitMQ
会取到该消息的headers
(也是一个键值对的形式),对比其中的键值对是否匹配Queue
与Exchange
绑定时指定的键值对;如果匹配则消息会路由到该Queue
,否则不会路由到该Queue
。
Exchange
类型不同发布策略也不同,Fanout
性能最高,其次是Direct
,最后是Topic
和Headers
默认交换器(Default Exchange)
Default Exchange
其实是AMQP
中预先声明的,属于Direct
类型,Default Exchange
的名是空字符串;
当你手动创建一个队列时,MQ会自动将这个队列绑定到Default Exchange
上,绑定时BindingKey
与队列名称相同
默认交换器隐式绑定到每个队列,路由键等于队列名称。不能显式地绑定到默认交换器,也不能从默认交换器解除绑定。它也不能被删除。
// 声明一个 Queue,这个时候test_queue 会和Default Exchange 绑定,此时 bindingKey = test_queue
Queue queue = new Queue("test_queue");
// 向默认交换机发布消息
rabbitTemplate.convertAndSend("", "test_queue", message);
注意:
- RabbitMQ 不允许你绑定一个非坚固(
non-durable
)的交换机和一个durable
的队列。反之亦然。要想成功必须队列和交换机都是durable
的。 - 一旦创建了队列和交换机,就不能修改其标志了。例如,如果创建了一个
non-durable
的队列,然后想把它改变成durable
的,唯一的办法就是删除这个队列然后重现创建。因此最好仔细检查创建的标志。 - 队列、交换机可以持久化,绑定不能设置持久化,如果你绑定了一个
durable
的队列和一个durable
的交换机,RabbitMQ会自动持久化这个绑定。 - Unacked消息怎么处理:未ack的消息状态会变为Unacked,客户端断开连接后,状态会变为Ready
- 建议使用长连接,长连接的基础之上使用多个channel
安装
Docker安装:
- 安装&运行
docker run -d --name rabbitmq3.7.7 -p 5672:5672 -p 15672:15672 -v /data:/var/lib/rabbitmq --hostname myRabbit -e RABBITMQ_DEFAULT_VHOST=my_vhost -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin rabbitmq:3.7.7-management - 访问控制台
http://xx.xx.xx.xx:15672
用户名:admin
密码:admin
Centos安装:
- 安装erlang、安装rabbitmq
rpm -ivh erlang-19.0.4-1.el7.centos.x86_64.rpm
yum install socat --安装依赖socat
rpm -ivh rabbitmq-server-3.6.6-1.el7.noarch.rpm - 添加用户、设置权限、查看用户
/sbin/rabbitmqctl add_user admin admin
rabbitmqctl set_user_tags admin management
rabbitmqctl list_users
RabbitMQ启动、关闭服务:
rabbitmq-server –detached #启动
rabbitmqctl stop #关闭
若单机有多个实例,则在rabbitmqctlh后加–n 指定名称
rabbitmqctl:
rabbitmqctl:是rabbitmq的管理工具,可以管理rabbitmq的方方面面;ui工具可以查看状态
- 常用命令
rabbitmqctl status
rabbitmqctl start_app --启动rabbitmq
rabbitmqctl stop_app --停止rabbitmq
rabbitmqctl reset --格式化rabbitmq,会把队列、交换机等都删掉(需要先关闭rabbitmq)
rabbitmqctl force-reset --无条件格式化 - vhost
rabbitmqctl add_vhost xxx --新建virtual_host
rabbitmqctl delete_vhost xxx --撤销virtual_host - 用户
rabbitmqctl list_users [-p vhost] --查看用户
rabbitmqctl add_user 用户名 密码 --添加用户
rabbitmqctl set_user_tags 用户名 角色 --设置角色,角色可以为 administrator,monitoring, management
rabbimqctl change_password {username} {newpassword} --改密码 - 交换机、绑定、队列
rabbitmqctl list_exchanges [-p vhost] [Exchangeinfoitem] --查看交换机, Exchangeinfoitem有:name,type,durable,auto_delete,internal,arguments.
rabbitmqctl list_bindings [-p vhost] [Bindinginfoitem] --查看绑定,Bindinginfoitem有:source_name,source_kind,destination_name,destination_kind,routing_key,arguments
rabbitmqctl list_queues [-p vhost] [Queueinfoitem] --查看队列,Queueinfoitem可以为:name,durable,auto_delete,arguments,messages_ready,messages_unacknowledged,messages,consumers,memory
rabbitmqctl purge_queue [-p vhost] 队列名 --清空某个队列
rabbitmqctl list_connections [connectioninfoitem ...] --查看连接,Connectioninfoitem有:recv_oct,recv_cnt,send_oct,send_cnt,send_pend等。
rabbitmqctl list_channels [channelinfoitem ...] --查看通道,Channelinfoitem有consumer_count,messages_unacknowledged,messages_uncommitted,acks_uncommitted,messages_unconfirmed, prefetch_count,client_flow_blocked
插件管理:
- 进入容器
docker exec -it rabbitmq3.7.7 /bin/bash - 查看rabbitmq插件:
rabbitmq-plugins list - 开启某个插件:
rabbitmq-plugins enable xxx - 关闭某个插件:
rabbitmq-plugins disable xxx
注意:重启服务器后生效。