参考

http://dl528888.blog.51cto.com/2382721/1864895

http://kaibinyuan.blog.51cto.com/7304008/1610110


原因:

最近有一个异步需要使用消息队列,或许最终会选择阿里的rocketmq


性能

单台TPS基本上是在2000-3000左右


最新rabbitmq版本是3.6.2


yum安装

配置文件

RPM- /etc/rabbitmq/


http://www.cnblogs.com/stormli/p/rabbitmq.html

Broker:简单来说就是消息队列服务器实体。

Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。

Queue:消息队列载体,每个消息都会被投入到一个或多个队列。

Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。

Routing Key:路由关键字,exchange根据这个关键字进行消息投递。

vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。

producer:消息生产者,就是投递消息的程序。

consumer:消息消费者,就是接受消息的程序。

channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务


http://blog.csdn.net/u013142781/article/details/50487028

AMQP当中有四个概念非常重要:虚拟主机(virtual host),交换机(exchange),队列(queue)和绑定(binding)。一个虚拟主机持有一组交换机、队列和绑定。为什么需要多个虚拟主机呢?很简单,RabbitMQ当中,用户只能在虚拟主机的粒度进行权限控制。因此,如果需要禁止A组访问B组的交换机/队列/绑定,必须为A和B分别创建一个虚拟主机。每一个RabbitMQ服务器都有一个默认的虚拟主机“/”。如果这就够了,那现在就可以开始了。


通过 Erlang 的分布式特性(通过 magic cookie 认证节点)进行 RabbitMQ 集群,各 RabbitMQ 服务为对等节点,即每个节点都提供服务给客户端连接,进行消息发送与接收。

这些节点通过 RabbitMQ HA 队列(镜像队列)进行消息队列结构复制。本方案中搭建 3 个节点,并且都是磁盘节点(所有节点状态保持一致,节点完全对等),只要有任何一个节点能够工作,RabbitMQ 集群对外就能提供服务。


Rabbitmq系统架构

RabbitMQ Server: 也叫broker server,是一种传输服务,负责维护一条从Producer到consumer的路线,保证数据能够按照指定的方式进行传输。

Producer,数据的发送方。

Consumer,数据的接收方。

Exchanges 接收消息,转发消息到绑定的队列。主要使用3种类型:direct, topic, fanout。

Queue RabbitMQ内部存储消息的对象。相同属性的queue可以重复定义,但只有第一次定义的有效。

Bindings 绑定Exchanges和Queue之间的路由。

Connection: 就是一个TCP的连接。Producer和consumer都是通过TCP连接到RabbitMQ Server的。

Channel:虚拟连接。它建立在上述的TCP连接中。数据流动都是在Channel中进行的。也就是说,一般情况是程序起始建立TCP连接,第二步就是建立这个Channel。


2.源码安装

红色标记必须做

yum remove rabbitmq-server -y

yum -y install erlang

yum -y install gcc gcc-c++ ncurses-devel

wget http://www.erlang.org/download/otp_src_R16B01.tar.gz

tar xvf otp_src_R16B01.tar.gz

cd otp_src_R16B01

./configure && make && make install

wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.5.1/rabbitmq-server-generic-unix-3.5.1.tar.gz

tar zxvf rabbitmq-server-generic-unix-3.5.1.tar.gz

#ln -svf /usr/local/src/rabbitmq_server-3.4.3 /usr/local/rabbitmq-node1

#mkdir -p /usr/local/rabbitmq-node1

cd /opt/soft && mv rabbitmq_server-3.5.1 /usr/local

cd /usr/local && mv rabbitmq_server-3.5.1 rabbitmq-node1


mv rabbitmq_server-3.5.1 /opt/local/rabbitmq

vim ~/.bash_profile 

PATH=/opt/mysql/bin:$PATH:$HOME/bin:/usr/lib/rabbitmq/bin/:/usr/local/rabbitmq-node1/sbin/:$PATH

source ~/.bash_profile

启用web插件

#rabbitmq-plugins enable rabbitmq_management #启用

关闭web插件

# rabbitmq-plugins disable rabbitmq_management

rabbitmq-plugins enable rabbitmq_management 

rabbitmq-plugins list

rabbitmqctl stop

rabbitmq-server -detached

rabbitmqctl cluster_status

scp -P 8022 .erlang.cookie root@192.168.3.120:/root/

ps -ef | grep rabbitmq | grep -v "grep"

kill -9 54239 

rabbitmqctl join_cluster rabbit@rabbitmq-test2

rabbitmqctl stop_app

rabbitmqctl start_app

rabbitmqctl change_password guest kaibin

cat /usr/local/rabbitmq-node2/ebin/rabbit.app | grep loopback --color

          {loopback_users,[<<"">>]},

(虽然可以以比较猥琐的方式:将ebin目录下rabbit.app中loopback_users里的<<"guest">>删除,或者在配置文件rabbitmq.config中对该项进行配置,

https://my.oschina.net/hncscwc/blog/262246

并重启rabbitmq,可通过任意IP使用guest账号登陆管理控制台

http://kaibinyuan.blog.51cto.com/7304008/1610110

处于安全的考虑,guest这个默认的用户只能通过localhost来登录,其他的IP无法直接使用这个账号为了解决这个问题,需要在rabbitmq的配置文件中将loopback_users配置设置为空

http://dwf07223.blog.51cto.com/8712758/1547226

解决RabbitMQ远程不能访问的问题

注意:rabbitmq从3.3.0开始禁止使用guest/guest权限通过除localhost外的访问。

如果想使用guest/guest通过远程机器访问,需要在rabbitmq配置文件中(/etc/rabbitmq/rabbitmq.config)中设置loopback_users为[]。

/etc/rabbitmq/rabbitmq.config文件完整内容如下(注意后面的半角句号):

[{rabbit, [{loopback_users, []}]}].

rabbitmq的web管理界面默认guest:guest,这样的话,不是很安全,需要更改下

[root@rabbitmq-test1 ~]# rabbitmqctl change_password guest kaibin

Changing password for user "guest" ...

...done.

)

设计镜像队列策略

rabbitmqctl set_policy ha-all '^(?!amq\.).*' '{"ha-mode": "all"}'


#rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'

#沿用3.2的环境,现在我们把名为“hello”的队列设置为同步给所有节点

#rabbitmqctl set_policy  ha-all “hello” ‘{“ha-mode”:”all”}’

ha-all 是同步模式,指同步给所有节点,还有另外两种模式ha-exactly表示在指定个数的节点上进行镜像,节点的个数由ha-params指定,ha-nodes表示在指定的节点上进行镜像,节点名称通过ha-params指定;

hello 是同步的队列名,可以用正则表达式匹配;

{“ha-mode”:”all”} 表示同步给所有,同步模式的不同,此参数也不同。

执行上面命令后,可以在web管理界面查看queue 页面,里面hello队列的node节点后会出现+2标签,表示有2个从节点,而主节点则是当前显示的node(xf7021是测试用的名字,按4-2应该为rabbitmq(1-3))。

镜像模式:消息实体会主动在各节点之间同步,而不是在消费者获取时才同步。降低系统性能消耗带宽


设置ha模式

rabbitmqctl set_policy [-p <vhostpath>] [--priority <priority>] [--apply-to <apply-to>] <name> <pattern> <definition>  

name 策略名称

pattern 正则表达式,用来匹配资源,符合的就会应用设置的策略

definition 是json格式设置的策略。

apply-to 表示策略应用到什么类型的地方,一般有queues,exchange和all,默认是all

priority 是个整数优先级

其中ha-mode有三种模式:

all: 同步至所有的.

exactly: 同步最多N个机器. 当现有集群机器数小于N时,同步所有,大于等于N时则不进行同步. N需要额外通过ha-params来指定.

nodes: 只同步至符合指定名称的nodes. N需要额外通过ha-params来指定.# 这里设置的是同步全部的queue, 可以按需自己选择指定的queue

 rabbitmqctl set_policy ha-all '.*' '{"ha-mode":"all"}'


线上操作

rabbitmq有主从之分,谁先启动,就是主

rabbitmq-server -detached

rabbitmqctl cluster_status

不需要再rabbitmqctl start_app


命令详细介绍

https://my.oschina.net/guol/blog/186445

stop_app   

#停止erlang node上的rabbitmq的应用,但是erlang node还是会继续运行的

要在生产上使用,以下几点,有几点有可能用的上

注意的地方:

0.修改集群cluster_node_type

[root@rabbitmq-test1 rabbitmq]# rabbitmqctl stop_app

Stopping node 'rabbit@rabbitmq-test1' ...

...done.

[root@rabbitmq-test1 rabbitmq]# rabbitmqctl change_cluster_node_type  ram

Turning 'rabbit@rabbitmq-test1' into a ram node ...

...done.

[root@rabbitmq-test1 ~]# rabbitmqctl cluster_status

Cluster status of node 'rabbit@rabbitmq-test1' ...

[{nodes,[{disc,['rabbit@rabbitmq-test2']},{ram,['rabbit@rabbitmq-test1']}]},

 {running_nodes,['rabbit@rabbitmq-test2','rabbit@rabbitmq-test1']},

 {partitions,[]}]

...done.

关于节点类型(ram |disk)

ram节点的状态保存在内存中,disk节点保存在磁盘中被加入的节点为disk,如本例中rabbit@host2为ram节点,rabbit@host1,rabbit@host3为ram节点,可以通过rabbitmqctl cluster命令改变加入的集群以及节点类型该命令后可以加多个节点名称,指定的节点就会变成disk节点

1.[root@rabbitmq-node1 ~]# cat /etc/rabbitmq/rabbitmq-env.conf 

RABBITMQ_MNESIA_BASE=/var/lib/rabbitmq///需要使用的MNESIA数据库的路径

RABBITMQ_LOG_BASE=/var/log/rabbitmq///log的路径

RABBITMQ_PLUGINS_DIR=/usr/lib/rabbitmq/lib/rabbitmq_server-2.8.6/plugins//插件的路径

2.自动配置集群

vi /etc/rabbitmq/rabbitmq.config

添加以下内容

[{rabbit,

  [{cluster_nodes, {['rabbit@r1', 'rabbit@r2'], disc}}]}].

之后启动集群

在r1和r2上执行

rabbitmq-server -detached

然后查看集群状态

rabbitmqctl cluster_status

3.高可用

安装并配置 HAProxy

在 192.168.1.4 上安装 HAProxy,然后修改 /etc/haproxy/haproxy.cfg:

listen rabbitmq_cluster 0.0.0.0:5672

mode tcp

balance roundrobin

server   node1 192.168.1.1:5672 check inter 2000 rise 2 fall 3  

server   node2 192.168.1.2:5672 check inter 2000 rise 2 fall 3

server   node2 192.168.1.3:5672 check inter 2000 rise 2 fall 3

4.用户与权限

在正式应用之前,我们先在RabbitMQ里创建一个vhost,加一个用户,并设置该用户的权限。使用rabbitmqctl客户端工具,在根目录下创建”/mq_test”这个vhost:

rabbitmqctl add_vhost /mq_test

创建一个用户名”test”,设置密码”test123″:

rabbitmqctl add_user test test123

设置pyh用户对/pyhtest这个vhost拥有全部权限:

rabbitmqctl set_permissions -p /mq_test test “.*” “.*” “.*”、

后面三个”*”代表pyh用户拥有对/pyhtest的配置、写、读全部权限

conn = amqp.Connection(host='localhost',userid='test',password='123456',ssl=False,virtual_host='test_host')

# rabbitmq-plugins enable rabbitmq_management

# rabbitmq-plugins list

# rabbitmqctl add_user admin admin

# rabbitmqctl set_user_tags admin administrator

RABBITMQ创建帐户

如果是集群的话,只要在一台主机设置即可,其它会自动同步。

#rabbitmqctl add_user iom 123456  –iom为新建的用户,123456为密码

#rabbitmqctl  set_user_tags iom administrator –将用户设置为管理员角色

#rabbitmqctl set_permissions -p / iom “.*” “.*” “.*”

–在 / 虚拟主机里设置iom用户配置权限,写权限,读权限。.*是正则表达式里用法。rabbitmq的权限是根据不同的虚拟主机(virtual hosts)配置的,同用户在不同的虚拟主机(virtual hosts)里可能不一样。

5.rabbit_hosts=192.168.8.180:5672,192.168.8.53:5672,192.168.8.87:5672

测试rabbitmq的haproxy下的lb

将之前的测试代码中的

mq_servers = ['10.22.129.57', '10.22.129.58', '10.22.129.59']

改成

mq_servers = ['10.22.129.53', '10.22.129.53', '10.22.129.53']

执行测试代码,发现三个消息均发送成功,然后即使手动关闭其中一台mq,消息依然发送成功,通过rabbitctl list_queues也依然可以看到消息是成功收到3条的.

至此,可以看到rabbitmq-server成功的解除了single-point状态。

6.使用service方式启动rabbitmq-server报错erlexec: HOME must be set

解决办法:

在启动脚本中使用export指定HOME变量

export HOME=/opt/data/rabbitmq/

7.最常用的命令

查看所有队列信息

[root@rabbitmq-test1 ~]# rabbitmqctl list_queues

Listing queues ...

...done.

清除所有队列

rabbitmqctl reset

8.关于端口

rabbimq  55672 15672 为监控插件端口

rabbitmq  5672为数据端口

9.一些特别应该注意的东西

§ cookie在所有节点上必须完全一样,同步时一定要注意。

§ erlang是通过主机名来连接服务,必须保证各个主机名之间可以ping通。可以通过编辑/etc/hosts来手工添加主机名和IP对应关系。如果主机名ping不通,rabbitmq服务启动会失败。

§ 如果queue是非持久化queue,则如果创建queue的那个节点失败,发送方和接收方可以创建同样的queue继续运作。但如果是持久化queue,则只能等创建queue的那个节点恢复后才能继续服务。

§ 在集群元数据有变动的时候需要有disk node在线,但是在节点加入或退出的时候所有的disk node必须全部在线。如果没有正确退出disk node,集群会认为这个节点当掉了,在这个节点恢复之前不要加入其它节点。