一、概述和模型
- 一个消费者处理一个消息队列,耦合度高
二、java代码实现
- 添加jar包(用maven创建的项目)
<!-- 单日志门面 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.10</version>
</dependency>
<!-- 添加log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
<!-- rabbitmq -->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>4.0.2</version>
</dependency>
- 创建MQ连接工具类
public class RabbitmqUntil {
//获取连接
public static Connection getRabbitmqConnection() throws Exception{
//定义连接工厂
ConnectionFactory factory = new ConnectionFactory();
//设置服务地址
factory.setHost("127.0.0.1");
//设置端口(这里的端口号指定是AMQP协议所用的端口号)
factory.setPort(5672);
//设置数据库
factory.setVirtualHost("/test");
//设置用户名
factory.setUsername("test");
//设置密码
factory.setPassword("test");
return factory.newConnection();
}
}
- 创建消息发送者
public class SingleSender {
//队列名称
public final static String queryName="singleQuery";
public void sendMessage() throws Exception{
//获取连接
Connection rabbitmqConnection = RabbitmqUntil.getRabbitmqConnection();
//获取管道
Channel channel = rabbitmqConnection.createChannel();
/**
* 队列创建(如果队列存在,则不进行创建)
* 参数1:队列名
* 参数2:是否支持持久化,默认队列在内存中,重启会丢失。设置为true,会保存到erlang自带的数据库中
* 参数3:当连接关闭后是否自动删除队列;是否私有队列,如果私有,其他通道不能访问当前队列
* 参数4:当没有消费者,是否自动删除队列
* 参数5:其他参数
*/
channel.queueDeclare(queryName,false,false,false,null);
//发送的信息
String msg="hello ,I am single query";
System.out.println(msg);
/**
* 发布信息
* 参数1:交互机名,如果为空表示匿名转发。如果不为空第二个参数为路由键routingKey,否则为队列名
* 参数2:routingKey/query
* 参数3:channel的继承属性 BasicProperties basicProperties = new AMQP.BasicProperties(){}
* 参数4:推送的信息
*/
channel.basicPublish("",queryName,null,msg.getBytes());
//关闭资源
channel.close();
rabbitmqConnection.close();
}
public static void main(String[] arg)throws Exception{
SingleSender singleSender = new SingleSender();
singleSender.sendMessage();
}
}
步骤:
1、通过工具类获取连接
2、获取管道channel
3、创建队列,如果队列已经存在了,则不做处理
4、发布信息
5、关闭资源
- 创建消息接收者
public class SingleReceiver {
//队列名称
public final static String queryName="singleQuery";
//接收信息
public void receiveMessage() throws Exception{
//获取连接
Connection rabbitmqConnection = RabbitmqUntil.getRabbitmqConnection();
//获取管道
Channel channel = rabbitmqConnection.createChannel();
/**
* 队列创建(如果队列存在,则不进行创建)
* 参数1:队列名
* 参数2:是否支持持久化,默认队列在内存中,重启会丢失。设置为true,会保存到erlang自带的数据库中
* 参数3:当连接关闭后是否自动删除队列;是否私有队列,如果私有,其他通道不能访问当前队列
* 参数4:当没有消费者,是否自动删除队列
* 参数5:其他参数
*/
channel.queueDeclare(queryName,false,false,false,null);
//创建接收信息用户
DefaultConsumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("接收到的信息"+new String(body));
}
};
/**
* 监听rabbitmq队列信息(此时程序会自动堵塞,当有数据到达时,处理相应的数据)
* 参数1:队列名
* 参数2:是否自动问答
* 参数3:消费用户
*/
channel.basicConsume(queryName,true,consumer);
}
public static void main(String[] arg)throws Exception{
SingleReceiver singleReceiver = new SingleReceiver();
singleReceiver.receiveMessage();
}
}
步骤:
1、通过工具类获取连接
2、获取管道channel
3、创建队列,如果队列已经存在了,则不做处理
4、创新接收信息用户
5、监听队列信息,如果有队列到达,进行获取、处理
- 运行main方法,就可以看到信息的传输
注:如果先运行消息发送代码,可以在界面管理看到相应的队列
注:Rabbitmq老版本消费者的实现(QueueingConsumer()为过期方法)
//老版本接收信息
public void old_receiveMessage() throws Exception{
//获取连接
Connection rabbitmqConnection = RabbitmqUntil.getRabbitmqConnection();
//获取管道
Channel channel = rabbitmqConnection.createChannel();
/**
* 队列创建(如果队列存在,则不进行创建)
* 参数1:队列名
* 参数2:是否支持持久化,默认队列在内存中,重启会丢失。设置为true,会保存到erlang自带的数据库中
* 参数3:当连接关闭后是否自动删除队列;是否私有队列,如果私有,其他通道不能访问当前队列
* 参数4:当没有消费者,是否自动删除队列
* 参数5:其他参数
*/
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
channel.basicConsume(queryName,true,queueingConsumer);
while (true){
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
System.out.println("老版本接收到的信息"+new String(delivery.getBody()));
}
}