一、RabbitMQ概览
1.什么是消息队列?
“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。
2.为什么要使用消息队列?
主要是由于在高并发环境下,由于来不及同步处理,请求往往会发生堵塞。如:大量的insert,update等请求同时到达数据库,导致无数的行锁表锁,因请求会堆积过多,而触发too many connections错误。通过使用消息队列,我们可以异步处理请求,从而缓解系统的压力。
3.RabbitMQ
RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现。(官网:http://www.rabbitmq.com/)
RabbitMQ是一个消息代理:它接受并转发消息。
4.RabbitMQ的安装(windows平台)
1)先决条件:下载erlang语言环境。version:20.1 (http://www.erlang.org/downloads)
安装完成后,配置E环境变量RLANG_HOME为安装的根目录,并把%ERLANG_HOME%in追加到PATH环境变量
2)下载RabbitMQ 。version:3.6.12(http://www.rabbitmq.com/install-windows.html)
执行sbin目录下的rabbitmq-server.bat来启动服务,默认端口:5672
注意:elang 和 RabbitMQ的版本对应要求。
3)开启管理插件
Rabbitmq-management 插件提供了用于管理、监控rabbitmq server的http 应用程序接口,基于浏览器的用户界面 和 命令行工具rabbitmqadmin。
开启rabbitmq管理插件:
rabbitmq-plugins enable rabbitmq_management
4)启动 rabbitmq 服务,并使用默认用户guest登录web 用户界面。
(使用windows系统服务或者rabbit root/sbin/rabbitmq-server.bat启动):
登入
5)RabbitMQ Hello word 之(消息发布)
本文以JAVA语言为例进行实现。官网提供了PHP、C#、JAVASCRIPT等多种语言的实现代码。
注:需要引入rabbitmq java client包,Maven仓库信息:groupId: com.rabbitmq artifactId: amqp-client
package com.example.mq; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import java.io.IOException; import java.util.concurrent.TimeoutException; public class Sender_1 { public static void main(String[] args) throws IOException, TimeoutException { ConnectionFactory factory=new ConnectionFactory(); //对于所有的参数,rabbitmq server在本地都有一个合适的默认值 factory.setHost("127.0.0.1"); factory.setPort(5672); factory.setVirtualHost("/"); factory.setUsername("guest"); factory.setPassword("guest"); //可使用连接字符串代替 //factory.setUri("amqp://userName:password@hostName:portNumber/virtualHost"); Connection connection=factory.newConnection(); //使用连接打开一个通道。Channel可以用于发送、接收信息 Channel channel=connection.createChannel(); //生命 一个 Queues用于发送信息。 String queueName="queue_1"; channel.queueDeclare(queueName,false,false,false,null); String message="Hello world 1!"; channel.basicPublish("",queueName,null,message.getBytes()); System.out.println("[x] Sent '"+message+"'"); channel.close(); connection.close(); } }
执行消息发布程序,分别以mesaage="Hello world 1!"; mesaage="Hello world 2!";mesaage="Hello world 3!";发送三条消息。
发送成功后,可以在管理页面看到rabbitmq server 上有一个名为queue_1的消息队列,其中包含三条消息。
也可以使用命令查看队列和其包含的消息:rabbitmqctl.bat list_queues
6)RabbitMQ Hello word 之(消息接收)
package com.example.mq; import com.rabbitmq.client.*; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.concurrent.TimeoutException; public class Receiver_1 { private final static String queueName="queue_1"; public static void main(String [] args) throws IOException, TimeoutException { ConnectionFactory factory=new ConnectionFactory(); factory.setHost("127.0.0.1"); Connection connection=factory.newConnection(); Channel channel=connection.createChannel(); channel.queueDeclare(queueName,false,false,false,null); System.out.println("[*]waiting for message .to exit press ctrl+c..."); Consumer consumer=new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag,Envelope envelope,AMQP.BasicProperties properties,byte[] body) throws UnsupportedEncodingException { String message =new String(body,"UTF-8"); System.out.println("[x] Received '"+message+"'"); } }; channel.basicConsume(queueName,true,consumer); } }
执行消息接收程序 Receiver_1 ,从消息服务器rabbitmq上接收queue_1队列上的消息。
在控制台看到,分别接收到了前面发送到MQ上的三条消息,并且顺序遵循FIFO的队列模型。
相应的,管理页面上queue_1消息队列不再持有消息:
二、RabbitMQ Server
RabbitMQ带有默认的内置设置。 可以满足大部分的环境需要。 如果运行良好,那么你可能根本不需要任何配置。 对于所有其他情况,以及生产部署调优查看这里:http://next.rabbitmq.com/production-checklist.html
服务器和插件的各种设置的配置方式
1、配置文件
2、环境变量
3、最常配置的核心服务器设置
4、故障排除:如何验证配置文件的位置和有效的配置