先介绍下背景,这个是公司当前的项目云管理,自动化部署的一个功能。需要通过服务器批量下发命令到虚拟机。每台虚拟机都装有客户端,可以接收RabbitMQ的消息和向MQ发送消息。服务器的主要功能也是从RabbitMQ发送和接收消息。工作流程是这样的,通过服务器,将命令下发到以主机Id(虚拟机的唯一标识)命名的queue里,虚拟机客户端从对应主机Id获取消息,执行完命令后将结果返回。服务器获取执行结果。
安装RabbitMQ,服务器的操作系统是CentOS。在装之前,先得装Python和Erlang,装的过程就不细讲了,可以在网上搜。装完之后,进入安装目录,安装web插件管理界面:rabbitmq-plugins enable rabbitmq_management。添加用户rabbitmqctl add_user <Username> <Password>。给用户设置管理者权限 :rabbitmqctl set_user_tags user administrator。添加新用户,并设置完用户权限后,远程通过这个用户还是无法创建队列,得用默认账户(guest,guest)登上去Web页面之后,在名为Admin的Tab页给新设置的用户赋权限(也可以用命令给其设置权限)。可以在安装目录用rabbitmqctl -h查看命令详细信息。RabbitMQ还提供了一个工具rabbitmqadmin,可以在你web页面的访问路径http://server-name:15672/cli/下载rabbitmqadmin.txt,将后缀去掉,就可以用了。由于在本地命令用的少,也没有多去了解。之前在网上看到一个删除全部队列的方法的命令$ rabbitmqadmin -f tsv -q list connections name | while read conn ;do rabbitmqadmin -q close connection name=${conn} ; done 。还可以通过http://server-name:15672/api/查看相应的的JAVA接口。
Java调用RabbitMQ接口。由于相对于RabbitMQ都是一对一的接收和发送消息,所以调用也比较简单
ConnectionFactory factory = newConnectionFactory();
factory.setHost("");//MQ的IP
factory.setPort();//MQ端口
factory.setUsername("");//MQ用户名
factory.setPassword("");//MQ密码
Connection connection =factory.newConnection();
Channel channel =connection.createChannel();
/*创建消息队列,并且发送消息*/
channel.queueDeclare(QUEUE_NAME,false, false, false, null);
上面第一个参数是队列名字,第二个是队列是否持久化(重启后队列是否还在),第三个参数是该队列是否受限于此连接,第四个参数是连接不在时是否删除队列。
服务器端:
channel.basicPublish("",QUEUE_NAME, null, message.getBytes());
客户端:
/*创建消费者对象,用于读取消息*/
QueueingConsumerconsumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE_NAME,true, consumer);
遇到的问题,由于连接的connection太多,file descriptors爆满,查了资料,是由于服务器的文件打开数限制,在rabbitmq-server里添加ulimit-n 10400可以解决问题。
流程示意图: