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、不足之处

耦合性高 生产消费一一对应(如果有多个消费者想都消费这个消息,就不行了) 队列名称变更时需要同时更改

 

posted @ 2019-03-14 15:22  MrChengs  阅读(212)  评论(0编辑  收藏  举报