rabbitMQ的优点(适用范围)
1. 基于erlang语言开发具有高可用高并发的优点,适合集群服务器。
2. 健壮、稳定、易用、跨平台、支持多种语言、文档齐全。
3. 有消息确认机制和持久化机制,可靠性高。
4. 开源
其他MQ的优势:
1. Apache ActiveMQ曝光率最高,但是可能会丢消息。
2. ZeroMQ延迟很低、支持灵活拓扑,但是不支持消息持久化和崩溃恢复。
安装rabbitmq
我是在vBox虚拟机上安装的,系统为centos6.3
一、安装Erlang
1.RabbitMQ是基于Erlang的,所以首先必须配置Erlang环境.
2.从Erlang的官网 http://www.erlang.org/download.html 下载最新的erlang安装包,下载的版本是 R15B01
3.解压下载的gz包 tar zxcf *.tar.gz
4.cd 进入解压出来的文件夹 ./configure && make && make install
4.cd 进入解压出来的文件夹 ./configure && make && make install
5.编译完成以后,输入erl测试erl是否安装成功
二、simplejson安装
1.wget http://pypi.python.org/packages/source/s/simplejson/simplejson-下载simplejson
2.tar zxvf xxx.tar.gz解压缩文件
3.cd 解压后的目录,python setup.py install。
三 rabbitmq安装
- wget http://www.rabbitmq.com/releases/rabbitmq-server/v2.7.1/rabbitmq-server-generic-unix-2.8.2.tar.gz下载rabbitmq
- tar zxvf rabbitmq-server-generic-unix-2.8.2.tar.gz (-C /opt解压到指定的文件夹下)
- cd 解压后的目录/sbin,./rabbitmq-server -detached可以实现后台启动
- 修改/etc/profile,添加环境变量
- export PATH=$PATH:/mq安装目录/sbin
- source profile
- rabbitmqctl stop为关闭mq命令
- 启用管理方式(用网页方式管理MQ)
- 先关闭mq,执行rabbitmq-plugin enable rabbitmq-management,然后访问http://localhost:55672 (注意防火墙端口是否开放)
- 这样就完成了安装 (参考http://www.cnblogs.com/astroboyx/archive/2012/04/09/2739902.html)
生产者
package test.mq;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* 生产者
* @author ephemeral
*
*/
public class Send {
//消息队列名称
private final static String QUEUE_NAME="hello";
public static void main(String[] args) throws java.io.IOException, TimeoutException{
//创建链接工程
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.1.158");
factory.setPort(5672);
//创建链接
Connection connection = factory.newConnection();
//创建消息通道
Channel channel = connection.createChannel();
//生成一个消息队列
//若durable设置为true ,则服务器收到消息后就会立刻将消息写入到硬盘,
//就可以防止突然服务器挂掉,而引起的数据丢失了。
//但是服务器如果刚收到消息,还没来得及写入到硬盘,就挂掉了,这样还是无法避免消息的丢失。
boolean durable = false;
channel.queueDeclare(QUEUE_NAME, durable, false, false, null);
String message = "Hello World"+System.currentTimeMillis();
//发布消息,第一个参数表示路由(Exchange名称),未""则表示使用默认消息路由
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println(" [x] Sent '"+message+"'");
//关闭消息通道和链接
channel.close();
connection.close();
}
}
消费者
package test.mq;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.ShutdownSignalException;
/**
* 消费者
* @author ephemeral
*
*/
public class Recv {
//消息队列名称
private final static String QUEUE_NAME="hello";
public static void main(String[] args) throws java.io.IOException,java.lang.InterruptedException, TimeoutException{
//创建链接工厂
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.1.158");
//创建链接
Connection connection = factory.newConnection();
//创建消息信道
Channel channel = connection.createChannel();
//生命消息队列
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
System.out.println("[*] Waiting for message. To exist press CTRL+C");
//消费者用于获取消息信道绑定的消息队列中的信息
QueueingConsumer consumer = new QueueingConsumer(channel);
//自动确认设置为false
boolean autoAck = false;
channel.basicConsume(QUEUE_NAME, autoAck,consumer);
while(true){
QueueingConsumer.Delivery delivery = null;
try {
//循环获取消息队列中的信息
delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("[x] Received '"+message+"'");
// //确认消息,已经收到 因为此时autoAck设置为false ,若不手动ack则 Publisher不能确认这个消息已经被正确处理
// channel.basicAck(delivery.getEnvelope().getDeliveryTag()
// , false);
throw new RuntimeException("ex occured");
} catch (ShutdownSignalException e) {
e.printStackTrace();
} catch (ConsumerCancelledException e) {
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
//requeue设置为false则该消息不会被重新发布,若设置为true则会被重新发布
boolean requeue = false;
channel.basicNack(delivery.getEnvelope().getDeliveryTag(), false,requeue);
}
}
}
}