2、RabbitMQ-simplest thing(简单队列)
1、项目准备:
使用maven的依赖
<dependencies> <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>4.0.2</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.10</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> </dependencies>
2、简单队列 hello world
2.1、模型图片
P:消息的生产者
C:消息的消费者
红色:队列
生产者将消息发送到队列,消费者从队列中获取消息。
那么我们根据以上的模型,咱们抽取出 3 个对象
生产者(用户发送消息)
生产者(用户发送消息)
队列(中间件):类似于容器(存储消息)
消费者(获取队列中的消息)
2.2、JAVA 操作 获取 MQ 连接
import java.io.IOException; import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; public class ConnectionUtils { public static Connection getConnection() throws IOException, TimeoutException{ //定义链接工厂 ConnectionFactory factory = new ConnectionFactory(); //设置服务地址 factory.setHost("127.0.0.1"); //设置端口 factory.setPort(5672); //设置账户、密码、vhost等 factory.setVirtualHost("/user"); factory.setUsername("user"); factory.setPassword("user"); //通过工程获取链接 Connection conn = factory.newConnection(); return conn; } }
2.3、生产者发送数据到消息队列
import java.io.IOException; import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.util.ConnectionUtils; public class Send { private static final String QUEUE_NAME ="test_simple_queue"; public static void main(String[] args) throws IOException, TimeoutException { //获取一个连接 Connection conn = ConnectionUtils.getConnection(); //从消息队列中获取一个信道 Channel c = conn.createChannel();
//创建队列声明 c.queueDeclare(QUEUE_NAME, false, false, false, null); //发送信息 String msg = "hello simple"; c.basicPublish("",QUEUE_NAME , null, msg.getBytes()); //关闭资源 c.close(); conn.close(); } }
进行新建队列的查看:
查看相关的消息:
2.4、消费者消费
使用较早的api进行对队列中的消息进行获取
package com.rabbitmq.simple; import java.io.IOException; import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConsumerCancelledException; import com.rabbitmq.client.QueueingConsumer; import com.rabbitmq.client.QueueingConsumer.Delivery; import com.rabbitmq.client.ShutdownSignalException; import com.rabbitmq.util.ConnectionUtils; //消费者接受消息 public class Receive { private static final String QUEUE_NAME ="test_simple_queue"; public static void main(String[] args) throws IOException, TimeoutException, ShutdownSignalException, ConsumerCancelledException, InterruptedException { //获取连接 Connection conn = ConnectionUtils.getConnection(); //创建信道 Channel c = conn.createChannel(); //定义队列的消费者 QueueingConsumer queueingConsumer = new QueueingConsumer(c); //监听队列 c.basicConsume(QUEUE_NAME, true,queueingConsumer); while(true){ Delivery delivery =queueingConsumer.nextDelivery(); String msg = new String(delivery.getBody()); System.out.println(msg); } } }
此方法现在已经很少进行使用,如果使用较早的api可以进行了解一下
此时的监听不会关闭!!!
只要队列有消息就会进行监听
使用新的api
import java.io.IOException; import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConsumerCancelledException; import com.rabbitmq.client.DefaultConsumer; import com.rabbitmq.client.Envelope; import com.rabbitmq.client.QueueingConsumer; import com.rabbitmq.client.QueueingConsumer.Delivery; import com.rabbitmq.client.ShutdownSignalException; import com.rabbitmq.client.AMQP.BasicProperties; import com.rabbitmq.util.ConnectionUtils; //消费者接受消息 public class Receive { private static final String QUEUE_NAME ="test_simple_queue"; public static void main(String[] args) throws IOException, TimeoutException, ShutdownSignalException, ConsumerCancelledException, InterruptedException { //获取连接 Connection conn = ConnectionUtils.getConnection(); //创建频道 Channel channel = conn.createChannel(); //队列声明 channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//定义一个消费者 DefaultConsumer consumer = new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body) throws IOException { //重写父方法 String msg = new String(body,"utf-8"); System.out.println(msg); } }; //进行监听队列 channel.basicConsume(QUEUE_NAME, true,consumer); } }
此时会一致动态的进行对队列的监控
3、不足之处
耦合性高 生产消费一一对应(如果有多个消费者想都消费这个消息,就不行了) 队列名称变更时需要同时更改