RabbitMQ使用https/web-stomp

JS连接RabbitMQ在上篇中就已经实现了,但是发现在生产环境中无法使用,主要问题是通过https访问网站的话web-stomp也得支持ssl的安全访问,不支持ssl的话会因为安全问题无法进行访问。现将实现步骤记录一下。

  1. 首先得有ssl证书,可以去阿里云或者腾讯云申请免费的证书
  2. 申请好后将ssl证书下载下来,处理一下,下载下来是两个文件(pem证书和key文件),但是RabbitMQ中用到的是3个文件,需要把一个pem证书拆分为两个文件:ca证书文件和签发出来的域名pem,一般pem文件下面的密钥为ca证书文件。将处理好的3个文件上传到服务器中等待配置。
  3. 然后进入安装RabbitMQ的机器并进入配置文件目录

    cd /etc/rabbitmq/

    vi rabbitmq.conf

    在文件中输入web_stomp.ssl.port       = 15673

    web_stomp.ssl.backlog    = 1024

    web_stomp.ssl.cacertfile = /ssl/ca.pem

    web_stomp.ssl.certfile   = /ssl/xxx.com.pem

    web_stomp.ssl.keyfile    = /ssl/xxx.com.key

    保存即可

  4. 然后最重要的需要重启rabbitmq-server服务,如果有防火墙,得放开15673端口
  5. 然后使用js连接的时候访问这个地址
    wss://rabbitmq.xxx.com:15673/ws
  6. 以上就能使用https/web-stomp了

JS实现连接RabbitMQ

首先需要启动RabbitMQ服务端相关的stomp插件rabbitmq_web_stomp

命令如下:rabbitmq-plugins enable rabbitmq_management rabbitmq_web_stomp rabbitmq_stomp

是通过端口15674以websocket的方式来进行连接的

实现代码如下:载入stomp.js和sockjs-0.3.js

 

<!DOCTYPE html>
<html>  
    <head>  
        <title>WebSocket</title>  
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
    </head>  
    <body>  
    <div id="main">  
        <div id="message"></div>  
    </div>  
    </body> 
	<script src="jquery-1.10.2.min.js"></script>
	<!-- stomp协议的客户端脚本 -->
	<script src="stomp.js"></script>
	<!-- SockJS的客户端脚本 -->
	<script src="sockjs-0.3.js"></script>	
    <script type="text/javascript"> 
 
	var ws = new WebSocket('ws://192.168.10.182:15674/ws');
	// 获得Stomp client对象
	var client = Stomp.over(ws);
 
	// SockJS does not support heart-beat: disable heart-beats
	//client.heartbeat.outgoing = 0;
	//client.heartbeat.incoming = 0;
 
	// 定义连接成功回调函数
	var on_connect = function(x) {
		//data.body是接收到的数据
                
          client.subscribe("/exchange/test", function(data) {  
			var msg = data.body;
			$("#message").append("收到数据:" + msg);
		});
	};
 
	// 定义错误时回调函数
	var on_error =  function(err) {
		console.log(err);
	};
 
	// 连接RabbitMQ
	client.connect('admin', 'admin', on_connect, on_error, 'vhosttest');
	console.log(">>>连接上http://192.168.10.182:15674");
	
	</script>  
 </html>

如此就能收到发送到exchange为test的消息了

用到的js文件可在此下载rabbitmq-stomp

 

RabbitMQ集群搭建

1.首先在各个目标机器上安装RabbitMQ,这个地址上有各平台的安装步骤http://www.rabbitmq.com/download.html

因为我的服务器是Centos,所以选择http://www.rabbitmq.com/install-rpm.html

1.1 Install Erlang 安装Erlang   

       各版本RabbitMQ所要求的erlang版本一览 http://www.rabbitmq.com/which-erlang.html

    运行 yum install erlang

       但是发现erlang 安装的是   R16B-03.18.el7 ,无法满足RabbitMQ 3.7.6 最低erlang19.3的版本要求。

       因此需要更换一下安装方式,推荐使用此方式进行安装,这也是RabbitMQ官方推荐的 https://www.erlang-solutions.com/resources/download.html

wget https://packages.erlang-solutions.com/erlang-solutions-1.0-1.noarch.rpm
rpm -Uvh erlang-solutions-1.0-1.noarch.rpm
sudo yum install erlang

 

1.2安装RabbitMQ 

    下载rabbitmq 

wget https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.7/rabbitmq-server-3.7.7-1.el7.noarch.rpm

以下使用‘root’运行

rpm --import https://dl.bintray.com/rabbitmq/Keys/rabbitmq-release-signing-key.asc
# this example assumes the CentOS 7 version of the package
yum install rabbitmq-server-3.7.7-1.el7.noarch.rpm

一些常用的命令

$ sudo chkconfig rabbitmq-server on # 添加开机启动RabbitMQ服务

$ sudo /sbin/service rabbitmq-server start # 启动服务

$ sudo /sbin/service rabbitmq-server status # 查看服务状态

$ sudo /sbin/service rabbitmq-server stop # 停止服务

# 查看当前所有用户 $ sudo rabbitmqctl list_users

# 查看默认guest用户的权限 $ sudo rabbitmqctl list_user_permissions guest

# 由于RabbitMQ默认的账号用户名和密码都是guest。为了安全起见, 先删掉默认用户 $ sudo rabbitmqctl delete_user guest

# 添加新用户 $ sudo rabbitmqctl add_user username password

# 设置用户tag $ sudo rabbitmqctl set_user_tags username administrator

# 赋予用户默认vhost的全部操作权限 $ sudo rabbitmqctl set_permissions -p / username ".*" ".*" ".*"

# 查看用户的权限 $ sudo rabbitmqctl list_user_permissions username

 

开启管理后台

sudo rabbitmq-plugins enable rabbitmq_management

开启成功后可以在浏览器中访问http://xx.xx.xx.xx:15672 使用刚才插入的用户名密码进行管理。

 

其它插件的处理 http://www.rabbitmq.com/plugins.html

#查看插件列表  

rabbitmq-plugins list

#enble插件 

rabbitmq-plugins enable plugin-name 

#disable插件

rabbitmq-plugins disable plugin-name  

根据自己所需开启插件

 

2.在各机器上安装好RabbitMQ后,构建集群

首先在每台/etc/hosts 中增加所有的机器  ip 机器名称,并保证能够相互PING通

如 10.0.0.2 A   (注:A为登录服务器显示的root@A)

    10.0.0.3 B

    ...

查看并修改各服务器中/var/lib/rabbitmq/.erlang.cookie的值,把所有的都修改成相同的值。

在B中运行 rabbitmqctl stop_app 停止运行

运行 rabbitmqctl join_cluster --ram rabbit@A 作为内存节点 或者吧ram 换为 disc 节点

加入成功后 rabbitmqctl start_app 

即可在管理后台看见B节点

 

RabbitMQ莫名关闭,且启动失败处理过程

    今日登陆RabbitMQ管理后台,发现一台节点不在运行,顿时很懵,心想一直运行的好好的为啥就出问题了呢?很尴尬。。。

    登陆节点服务器后发现磁盘容量已满,这就更尴尬了。。。没有收到任何告警短信。。。无语中。。。

   1.先把log日志给清一清,腾出空间,因为RabbitMQ节点是 Disk 节点。

   2.启动RabbitMQ  service rabbitmq-server start,显示成功了,但是加入到集群中就显示nodedown,证明rabbitmq server 没有启动成功,去查看一下日志,发现了问题所在

error 日志中显示

Crash dump was written to: erl_crash.dump

init terminating in do_boot ()

log日志中有详细的错误

Error description:
   {could_not_start,rabbit,
       {{badmatch,
            {error,
                {{{badmatch,
                      {error,
                          {not_a_dets_file,
                              "/var/lib/rabbitmq/mnesia/rabbit@p1fu4aql/recovery.dets"}}},
                  [{rabbit_recovery_terms,open_table,0,[]},
                   {rabbit_recovery_terms,init,1,[]},
                   {gen_server,init_it,6,[{file,"gen_server.erl"},{line,306}]},
                   {proc_lib,init_p_do_apply,3,
                       [{file,"proc_lib.erl"},{line,237}]}]},
                 {child,undefined,rabbit_recovery_terms,
                     {rabbit_recovery_terms,start_link,[]},
                     transient,4294967295,worker,
                     [rabbit_recovery_terms]}}}},
        [{rabbit_queue_index,start,1,[]},
         {rabbit_variable_queue,start,1,[]},
         {rabbit_priority_queue,start,1,[]},
         {rabbit_amqqueue,recover,0,[]},
         {rabbit,recover,0,[]},
         {rabbit,'-run_step/2-lc$^1/1-1-',1,[]},
         {rabbit,run_step,2,[]},
         {rabbit,'-run_boot_steps/1-lc$^0/1-0-',1,[]}]}}

Log files (may contain more information):
   /var/log/rabbitmq/rabbit@p1fu4aql.log
   /var/log/rabbitmq/rabbit@p1fu4aql-sasl.log
 

 

从日志中看出 这个/var/lib/rabbitmq/mnesia/rabbit@p1fu4aql/recovery.dets 文件出错

我们找到这个文件并删除它

启动RabbitMQ    service rabbitmq-server start  成功

加入集群   rabbitmqctl start_app  成功

至此问题处理完成。