RabbitMQ 入门
安装
一、通过 docker 方式快速安装
# 最新的 RabbitMQ 3.10 docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.10-management
然后浏览器打开链接
http://localhost:15672
默认账号密码都为 guest,安全起见,最好进行修改,而且这个默认的账户只作用于本地,推荐的做法是:删除默认用户、使用新的安全凭证创建新的用户
添加新账户的方式:
1. 通过 web 管理界面
2. 命令行
# 添加用户 rabbitmqctl add_user {username} {password} rabbitmqctl add_user admin 123456 #修改用户密码 rabbitmqctl change_password {username} {newpassword} rabbitmqctl change_password admin 123456 #验证用户密码 rabbitmqctl authenticate_user admin 123456 #删除用户 rabbitmqctl delete_user admin #列出用户 rabbitmqctl list_users # 给用户设置标签 none management monitoring administrator 多个用,分隔 #rabbitmqctl set_user_tags {username} {tag ...} rabbitmqctl set_user_tags admin administrator
给用户授权
#rabbitmqctl set_permissions [-p host] {user} {conf} {write} {read} #vhost 授予用户访问权限的vhost名称 默认 / #user 可以访问指定vhost的用户名 #conf 一个用于匹配用户在那些资源上拥有可配置的正则表达式 #write 一个用于匹配用户在那些资源上拥有可写的正则表达式 #read 一个用于匹配用户在那些资源上拥有可读的正则表达式 #授予admin用户可访问虚拟主机testhost,并在所有的资源上具备可配置、可写及可读的权限 rabbitmqctl set_permissions -p /testhost admin ".*" ".*" ".*" #授予admin用户可访问虚拟主机testhost1,在以queue开头的资源上具备可配置权限、并在所有的资源上可写及可读的权限 rabbitmqctl set_permissions -p /testhost1 admin "^queue.*" ".*" ".*" #清除权限 rabbitmqctl clear_permissions -p /testhost admin #虚拟主机的权限 rabbitmqctl list_permissions -p /testhost #用户权限 rabbitmqctl list_user_permissions admin
vhost操作
#添加vhost rabbitmqctl add_vhost /testhost #列出vhost rabbitmqctl list_vhosts #删除vhost rabbitmqctl delete_vhost /testhost
二、MAC OS 安装
在 Mac 下安装RabbitMQ是非常简单的,一般默认 RabbitMQ 服务器依赖的 Erlang 已经安装,只需要用下面两个命令就可以完成 RabbitMQ 的安装(前提是 homebrew 已经被安装):
brew update
brew install rabbitmq
安装完成后需要将/usr/local/sbin添加到$PATH,可以将下面这两行加到~/.bash_profile:
vim ~/.bash_profile
# RabbitMQ Config
export PATH=$PATH:/usr/local/sbin
保留后执行
source ~/.bash_profile
启动服务后,就可以跟上面一样输入 localhost:15672 去访问了
rabbitmq-server
后台运行
rabbitmq-server -detached
什么是AMQP?
AMQP:即Advanced Message Queuing Protocol,是一个应用层标准高级消息队列协议,提供统一消息服务。是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品、不同的开发语言等条件的限制。
使用场景
几个基础概念:交换器 exchange、绑定 bindings、队列 queue
-
direct 根据路由键进行完全匹配
-
fanout 广播的方式同时被传送给所有绑定的队列
-
topic 路由key为一个表达式,routingKey表达式必须使用点隔开的任意多个英文单词,:表示一个英文单词位置,#:表示任意多个单词文字,如:“delete.” 表示有两个单词,以delete开始的匹配
vhost 虚拟主机
vhost 之间是逻辑上的隔离,同时也避免迁移的同名问题,类型程序里面的命名空间,是一种多租户模式
消息持久化:
-
消息的 Delivery mode 设置为 2
-
发送到持久化的 exchange(设置 Durability 为 Durable)
-
到达持久化的 queue(设置 Durability 为 Durable)
持久化日志的缺点:性能降低10倍
RabbitMQ 和 Redis 队列的区别
Redis 是一个Key-Value的NoSQL数据库,开发维护很活跃,虽然它是一个Key-Value数据库存储系统,但它本身支持MQ功能,所以完全可以当做一个轻量级的队列服务来使用。对于RabbitMQ和Redis的入队和出队操作,各执行100万次,每10万次记录一次执行时间。测试数据分为128Bytes、512Bytes、1K和10K四个不同大小的数据。实验表明:入队时,当数据比较小时Redis的性能要高于RabbitMQ,而如果数据大小超过了10K,Redis则慢的无法忍受;出队时,无论数据大小,Redis都表现出非常好的性能,而RabbitMQ的出队性能则远低于Redis。
RabbitMQ和Redis都可以做队列,但是他们还是有区别的。比如,Redis的消息队列,如果在从队列pop出去的时候,worker处理失败的话,数据不会回到队列中,需要从业务中手动把失败的处理数据push到队列中;而RabbitMQ可以自动处理失败的worker使数据不丢失;RabbitMQ还可以保证数据在传输过程中持久化,在通道和队列中的数据可以设置为持久化。首先Redis严格来说并不是消息队列,它是一个内存数据库,不过因为其某些特性适合用来充当队列,所以也多被用于做简单的mq, Redis之父倒是开发了个真正的消息队列disque,有兴趣可以看看。
相比起Redis,RabbitMQ有更加完善的MQ机制,这里我们仅讨论消息的durable(持久性),后续一系列其他机制有时间再交流。
RabbitMQ有一个消息确认机制来保证消息的不丢失:客户端从队列中取出消息之后,可能需要一段时间才能处理完成,如果在这个过程中,客户端出错了,异常退出了,而数据还没有处理完成,那么非常不幸,这段数据就丢失了,因为RabbitMQ默认会把此消息标记为已完成,然后从队列中移除,消息确认是客户端从RabbitMQ中取出消息,并处理完成之后,会发送一个ack告诉RabbitMQ,消息处理完成,当RabbitMQ收到客户端的获取消息请求之后,或标记为处理中,当再次收到ack之后,才会标记为已完成,然后从队列中删除。当RabbitMQ检测到客户端和自己断开链接之后,还没收到ack,则会重新将消息放回消息队列,交给下一个客户端处理,保证消息不丢失,也就是说,RabbitMQ给了客户端足够长的时间来做数据处理。
常见的MQ产品
- RabbitMQ
- ActiveMQ
- RocketMQ
- Kafka
一、RabbitMQ
优点:
1. 由于 erlang 语言的特性,mq 性能较好,高并发;
2. 健壮稳定、易用、跨平台、支持多种语言、文档齐全;
3. 有消息确认机制和持久化机制,可靠性高;
4. 高度可定制的路由;
5. 管理界面较丰富,在互联网公司也有较大规模的应用;
6. 社区活跃度高;
缺点:
1. 尽管结合 erlang 语言本身的并发优势,性能较好,但是不利于做二次开发和维护;
二、ActiveMQ
ActiveMQ是由Apache出品,ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现。它非常快速,支持多种语言的客户端和协议,而且可以非常容易的嵌入到企业的应用环境中,并有许多高级功能。
优点:
1. 跨平台(JAVA编写与平台无关有,ActiveMQ几乎可以运行在任何的JVM上)
2. 可以用JDBC:可以将数据持久化到数据库。虽然使用JDBC会降低ActiveMQ的性能,但是数据库一直都是开发人员最熟悉的存储介质。将消息存到数据库,看得见摸得着。而且公司有专门的DBA去对数据库进行调优,主从分离;
3. 支持JMS :支持JMS的统一接口;
4. 支持自动重连;
5. 有安全机制:支持基于shiro,jaas等多种安全配置机制,可以对Queue/Topic进行认证和授权。
6. 监控完善:拥有完善的监控,包括Web Console,JMX,Shell命令行,Jolokia的REST API;
7. 界面友善:提供的Web Console可以满足大部分情况,还有很多第三方的组件可以使用,如hawtio;
缺点:
1. 社区活跃度不及RabbitMQ高;
2. 根据其他用户反馈,会出莫名其妙的问题,会丢失消息;
3. 目前重心放到activemq6.0产品-apollo,对5.x的维护较少;
4. 不适合用于上千个队列的应用场景;
三、RocketMQ
RocketMQ 是一个分布式消息和流数据平台,具有低延迟、高性能、高可靠性、万亿级容量和灵活的可扩展性。RocketMQ是2012年阿里巴巴开源的第三代分布式消息中间件,2016年11月21日,阿里巴巴向Apache软件基金会捐赠了RocketMQ;第二年2月20日,Apache软件基金会宣布Apache RocketMQ成为顶级项目。
优点:
- 单机支持 1 万以上持久化队列
- RocketMQ 的所有消息都是持久化的,先写入系统 PAGECACHE,然后刷盘,可以保证内存与磁盘都有一份数据,
- 访问时,直接从内存读取。
- 模型简单,接口易用(JMS 的接口很多场合并不太实用);
- 性能非常好,可以大量堆积消息在broker中;
- 支持多种消费,包括集群消费、广播消费等。
- 各个环节分布式扩展设计,主从HA;
- 开发度较活跃,版本更新很快。
缺点:
- 支持的客户端语言不多,目前是java及c++,其中c++不成熟;
- RocketMQ社区关注度及成熟度也不及前两者;
- 没有web管理界面,提供了一个CLI(命令行界面)管理工具带来查询、管理和诊断各种问题;
- 没有在 mq 核心中去实现JMS等接口;
四、Kafka
Kafka是最初由Linkedin公司开发,是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志、访问日志,消息服务等等,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。
主要应用场景是:日志收集系统和消息系统。
- 以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间的访问性能。
- 高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒100K条消息的传输。
- 支持Kafka Server间的消息分区,及分布式消费,同时保证每个partition内的消息顺序传输。
- 同时支持离线数据处理和实时数据处理。
- Scale out:支持在线水平扩展
缺点:
- Kafka单机超过64个队列/分区,Load会发生明显的飙高现象,队列越多,load越高,发送消息响应时间变长
- 使用短轮询方式,实时性取决于轮询间隔时间;
- 消费失败不支持重试;
- 支持消息顺序,但是一台代理宕机后,就会产生消息乱序;
- 社区更新较慢;
总结:
Kafka在于分布式架构,RabbitMQ基于AMQP协议来实现,RocketMQ/思路来源于kafka,改成了主从结构,在事务性可靠性方面做了优化。广泛来说,电商、金融等对事务性要求很高的,可以考虑RabbitMQ和RocketMQ,对性能要求高的可考虑Kafka。
官方文档:
https://www.rabbitmq.com/download.html
参考链接: