RabbitMQ

RabbitMQ

MQ是什么

MQ:Message Queue消息队列

MQ是用来干嘛的呢?

消息队列:
队列-----先进先出
消息------传输的消息

向队列中存放传输的消息

消息队列有点类似于生活中的物流

你只需要将物品放到这个物流的平台上 物流就会给你进行运输到指定的目的地

使用MQ到底有什么作用呢?

1:可以将并行的请求串行化 -------- 消流 流量的消峰

2:模块之间的异步通信 主要是用在微服务上实现服务之间的异步通信

常见的消息队列有哪些呢?

JMS:JAVA Message Service :这个是JAVA的消息服务 是sun公司制定的一个标准

这个标准中存在两种通信模型

队列模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IEYoZSfn-1585470194466)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image002.jpg)]

主题模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IiwpY9Gs-1585470194470)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\msohtmlclip1\01\clip_image004.jpg)]

ActiveMQ(简单的一个 实现sun公司制定的 JMS标准)

RabbitMQ(这个是我们讲的)

RocketMQ(阿里的)

Kafka(原本的设计初衷不是用来做消息队列的 是用来进行日志的处理的 因为日志有严格的顺序问题 所以就用来做消息队列来了)

RabbitMQ是什么?

RabbitMQ就是一个消息中间件 这个消息的中间件的作用就是实现 上面MQ的两个功能

RabbitMQ能干什么?

  • 模块之间的异步通信
  • 流量的消峰处理
  • 将并行的处理串行化

RabbitMQ的安装

​ (2) 从EPEL源安装(这种方式安装的Erlang版本可能不是最新的,有时候不能满足RabbitMQ需要的最低版本)

yum install epel-release 
  yum install erlang  

安装RabbitMQ:

   wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.15/rabbitmq-server-3.6.15-1.el7.noarch.rpm

下载完成后安装:

 yum install rabbitmq-server-3.6.15-1.el7.noarch.rpm 

安装时如果遇到下面的依赖错误:
Error: Package: socat-1.7.2.3-1.el6.x86_64 (epel) Requires: libreadline.so.5()(64bit)
可以尝试先执行:

 yum install socat 

RabbitMQ的一些基本操作:
# 添加开机启动RabbitMQ服务

systemctl enable rabbitmq-server.service

#查看服务状态

 systemctl status  rabbitmq-server.service  

启动服务

systemctl start rabbitmq-server.service 

停止服务

systemctl stop rabbitmq-server.service 

查看当前所有用户

rabbitmqctl list_users

查看默认guest用户的权限

 rabbitmqctl list_user_permissions guest 

由于RabbitMQ默认的账号用户名和密码都是guest。为了安全起见, 先删掉默认用户

rabbitmqctl delete_user guest

添加新用户

rabbitmqctl add_user `username` `password`  (此处设置自己的用户名和密码)

设置用户tag

rabbitmqctl set_user_tags username administrator   

赋予用户默认vhost的全部操作权限

rabbitmqctl set_permissions -p / username ".*"   ".*" ".*"  

查看用户的权限

 rabbitmqctl list_user_permissions username   

开启web管理接口 如果只从命令行操作RabbitMQ,多少有点不方便。幸好RabbitMQ自带了web管理界面,只需要启动插件便可以使用。

rabbitmq-plugins enable rabbitmq_management 

访问: Linux远程地址:15672 例如:http://192.168.9.128:15672
登录遇到问题:User can only log in localhost
在这里插入图片描述
原因是从RabbitMQ3.3.0开始,禁止使用guest/guest权限通过localhost外的访问
所以最好新建一个用户

RabbitMQ的五种通信模型

基本的通信模型

1:创建一个帮助类

public class ConnectionUtils {            
    /**         
    * 返回连接服务器的连接         
    * @return         
    * @throws IOException         
    * @throws TimeoutException         
    */        
    public static Connection   getConnection() throws IOException, TimeoutException {            //申明一个连接的工厂            
        ConnectionFactory   connectionFactory = new ConnectionFactory();                //设置RabbitMQ的主机的地址            
        connectionFactory.setHost("116.62.6.66");           
        //设置虚拟主机    这里一般写成/就OK了            connectionFactory.setVirtualHost("/");            
        //设置用户名            
        connectionFactory.setUsername("xiaobobo");            
        //设置密码            
        connectionFactory.setPassword("123456");            
        //设置请求的服务的端口            
        connectionFactory.setPort(5672);            
        //返回这个连接            
        return   connectionFactory.newConnection();       
    }    
}      

2:创建生产者

  public class Sender {            
  private static final String   QUEUE_NAME="queue_01";            public static void main(String[]   args) throws IOException, TimeoutException {                
  //第一步:获取连接            
  Connection connection =   ConnectionUtils.getConnection();            //第二步:创建通道            
  Channel channel =   connection.createChannel();                //第三步:申明队列            
  /**             
  * 第一个参数:队列的名字             
* 第二个参数:是否持久化    如果rabbitmq从新启动的话 那么 这个数据会丢失  持久化就可以解决这个问题             * 第三个参数:是否排外             *            1:连接关闭之后这个队列是否自动删除             *            2:是否允许其他的通道来进行访问             * 第四个参数:是否自动删除             *             当最后一个连接断开的时候  是否需要自动删除             * 第五个参数:申明队列带的这个参数             *             */              channel.queueDeclare(QUEUE_NAME,false,false,false,null);            //第四步:发送数据到队列            
* /**             
* * 第一个参数:交换机 没有就写""             
* * 第二个参数:路由的key    只有队列的名字             
* * 第三个参数:发送数据的时候可以携带参数             
* */              
* channel.basicPublish("",QUEUE_NAME,null,"我是HelloWorld发送的数据".getBytes());            
* channel.close();            
* connection.close();        }    }   

3:创建消费者

   public class Consumer {        
   private static final String   QUEUE_NAME="queue_01";        public static void main(String[]   args) throws IOException, TimeoutException {
               //第一步:获取连接            
               Connection connection =   ConnectionUtils.getConnection();            
               //第二步:创建通道            
               Channel channel =   connection.createChannel();                
               //第三步:申明队列            
               /**             
               * 第一个参数:队列的名字             
               *  第二个参数:是否持久化    如果rabbitmq从新启动的话 那么 这个数据会丢失  持久化就可以解决这个问题             
               * 第三个参数:是否排外             
               * *            1:连接关闭之后这个队列是否自动删除             
               * *            2:是否允许其他的通道来进行访问             
               * * 第四个参数:是否自动删除             *             当最后一个连接断开的时候  是否需要自动删除             * 第五个参数:申明队列带的这个参数             
               * *             
               * */              
               channel.queueDeclare(QUEUE_NAME,false,false,false,null);            
               //申明了一个消费者            
               DefaultConsumer defaultConsumer   = new DefaultConsumer(channel) {
                               /**                 *                 * @param consumerTag:消费者的唯一的标记                 * @param envelope:信封 就是将请求的消息封装成一个对象                 * @param properties:前面队列带过来的属性的值                 * @param body:消息体                 * @throws IOException                 */                @Override                
                               public void   handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties   properties, byte[] body) throws IOException {
                                                     System.out.println("收到消息了:"+new String(body));                }            };            /**             * 第一个参数:队列的名字             * 第二个参数:是否自动应答             * 第三个参数:消费者的申明             */              channel.basicConsume(QUEUE_NAME,true,defaultConsumer);        }    } 

Work模型

一个队列存在多个消费者的时候 多个消费者消费的数据之和 才是原来队列中的所有数据

1:生产者

public class Sender {
    private static final String QUEUE_NAME = "queue_03";

    public static void main(String[] args) throws IOException, TimeoutException {
        //第一步:获取连接
        Connection connection =   ConnectionUtils.getConnection();
        // 第二步:创建通道
        Channel channel = connection.createChannel();
        // 第三步:申明队列
        /**
         * * 第一个参数:队列的名字
         * * 第二个参数:是否持久化    如果rabbitmq从新启动的话 那么 这个数据会丢失  持久化就可以解决这个问题
         * * 第三个参数:是否排外
         * *            1:连接关闭之后这个队列是否自动删除
         * *            2:是否允许其他的通道来进行访问
         * * 第四个参数:是否自动删除
         * *             当最后一个连接断开的时候  是否需要自动删除
         * * 第五个参数:申明队列带的这个参数
         * *
         * */
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //第四步:发送数据到队列            
        /**
         * * 第一个参数:交换机 没有就写""             
         * * 第二个参数:路由的key    只有队列的名字             
         * * 第三个参数:发送数据的时候可以携带参数             
         * */
        for (int i = 0; i < 100; i++) {
            channel.basicPublish("", QUEUE_NAME, null, ("我是WorkQueue模型传输的数据" + i).getBytes());
        }
        channel.close();
        connection.close();
    }
}    

2:消费者1

public class Consumer1 { private static final String QUEUE_NAME=“queue_03”; public static void main(String[] args) throws IOException, TimeoutException { //第一步:获取连接 Connection connection = ConnectionUtils.getConnection(); //第二步:创建通道 final Channel channel = connection.createChannel(); //第三步:申明队列 /** * 第一个参数:队列的名字 * 第二个参数:是否持久化 如果rabbitmq从新启动的话 那么 这个数据会丢失 持久化就可以解决这个问题 * 第三个参数:是否排外 * 1:连接关闭之后这个队列是否自动删除 * 2:是否允许其他的通道来进行访问 * 第四个参数:是否自动删除 * 当最后一个连接断开的时候 是否需要自动删除 * 第五个参数:申明队列带的这个参数 * / channel.queueDeclare(QUEUE_NAME,false,false,false,null); //没有确认的话 那么就不用分配任务给我 channel.basicQos(1); //申明了一个消费者 DefaultConsumer defaultConsumer = new DefaultConsumer(channel) { /* * * @param consumerTag:消费者的唯一的标记 * @param envelope:信封 就是将请求的消息封装成一个对象 * @param properties:前面队列带过来的属性的值 * @param body:消息体 * @throws IOException / @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println(“11111111111收到消息了:”+new String(body)); try { Thread.sleep(1000); }catch (Exception err){ } //表示的是手动告诉队列我已经收到这个消息了 channel.basicAck(envelope.getDeliveryTag(),false); } }; /* * 第一个参数:队列的名字 * 第二个参数:是否自动应答 false:表示的是要手动应答 没有应答的话 那么在队列中依然存在 * 第三个参数:消费者的申明 */ channel.basicConsume(QUEUE_NAME,false,defaultConsumer); // channel.close(); // // connection.close(); } }

3:消费者2

public class Consumer2 { private static final String QUEUE_NAME=“queue_03”; public static void main(String[] args) throws IOException, TimeoutException { //第一步:获取连接 Connection connection = ConnectionUtils.getConnection(); //第二步:创建通道 final Channel channel = connection.createChannel(); //第三步:申明队列 /** * 第一个参数:队列的名字 * 第二个参数:是否持久化 如果rabbitmq从新启动的话 那么 这个数据会丢失 持久化就可以解决这个问题 * 第三个参数:是否排外 * 1:连接关闭之后这个队列是否自动删除 * 2:是否允许其他的通道来进行访问 * 第四个参数:是否自动删除 * 当最后一个连接断开的时候 是否需要自动删除 * 第五个参数:申明队列带的这个参数 * / channel.queueDeclare(QUEUE_NAME,false,false,false,null); //这句话的意思是我还没有确认的时候 你没有必要给我分配任务 channel.basicQos(1); //申明了一个消费者 DefaultConsumer defaultConsumer = new DefaultConsumer(channel) { /* * * @param consumerTag:消费者的唯一的标记 * @param envelope:信封 就是将请求的消息封装成一个对象 * @param properties:前面队列带过来的属性的值 * @param body:消息体 * @throws IOException / @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println(“222222222222收到消息了:”+new String(body)); //表示的是手动告诉队列我已经收到这个消息了 channel.basicAck(envelope.getDeliveryTag(),false); } }; /* * 第一个参数:队列的名字 * 第二个参数:是否自动应答 false:表示的是要手动应答 没有应答的话 那么在队列中依然存在 * 第三个参数:消费者的申明 */ channel.basicConsume(QUEUE_NAME,false,defaultConsumer); // channel.close(); // // connection.close(); } }

发布订阅模式(经常用来做模块之间的异步通信)

生产者

public class Sender { //定义一个交换机的名字 private static final String EXCHANGE_NAME=“exchange1”; public static void main(String[] args) throws IOException, TimeoutException { Connection connection = ConnectionUtils.getConnection(); Channel channel = connection.createChannel(); //申明的是交换机 /** * 第一个参数:交换机的名字 * 第二个参数:交换机的类型 如果是发布订阅模式的话那么 交换机的类型只能是fanout */ channel.exchangeDeclare(EXCHANGE_NAME,“fanout”); //生产者发送信息到交换机 for (int i = 0; i <100 ; i++) { channel.basicPublish(EXCHANGE_NAME,"",null,(“发布订阅模式下的值”+i).getBytes()); } //关闭资源 channel.close(); connection.close(); } }

消费者1

public class Consumer1 { private static final String QUEUE_NAME=“queue_05”; private static final String EXCHANGE_NAME=“exchange1”; public static void main(String[] args) throws IOException, TimeoutException { //第一步:获取连接 Connection connection = ConnectionUtils.getConnection(); //第二步:创建通道 final Channel channel = connection.createChannel(); //第三步:申明队列 /** * 第一个参数:队列的名字 * 第二个参数:是否持久化 如果rabbitmq从新启动的话 那么 这个数据会丢失 持久化就可以解决这个问题 * 第三个参数:是否排外 * 1:连接关闭之后这个队列是否自动删除 * 2:是否允许其他的通道来进行访问 * 第四个参数:是否自动删除 * 当最后一个连接断开的时候 是否需要自动删除 * 第五个参数:申明队列带的这个参数 * / channel.queueDeclare(QUEUE_NAME,false,false,false,null); //申明交换机 channel.exchangeDeclare(EXCHANGE_NAME,“fanout”); //将队列绑定到交换机上 channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,""); //没有确认的话 那么就不用分配任务给我 channel.basicQos(1); //申明了一个消费者 DefaultConsumer defaultConsumer = new DefaultConsumer(channel) { /* * * @param consumerTag:消费者的唯一的标记 * @param envelope:信封 就是将请求的消息封装成一个对象 * @param properties:前面队列带过来的属性的值 * @param body:消息体 * @throws IOException / @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println(“11111111111收到消息了:”+new String(body)); //表示的是手动告诉队列我已经收到这个消息了 channel.basicAck(envelope.getDeliveryTag(),false); } }; /* * 第一个参数:队列的名字 * 第二个参数:是否自动应答 false:表示的是要手动应答 没有应答的话 那么在队列中依然存在 * 第三个参数:消费者的申明 */ channel.basicConsume(QUEUE_NAME,false,defaultConsumer); } }

消费者2

public class Consumer2 { private static final String QUEUE_NAME=“queue_06”; private static final String EXCHANGE_NAME=“exchange1”; public static void main(String[] args) throws IOException, TimeoutException { //第一步:获取连接 Connection connection = ConnectionUtils.getConnection(); //第二步:创建通道 final Channel channel = connection.createChannel(); //第三步:申明队列 /** * 第一个参数:队列的名字 * 第二个参数:是否持久化 如果rabbitmq从新启动的话 那么 这个数据会丢失 持久化就可以解决这个问题 * 第三个参数:是否排外 * 1:连接关闭之后这个队列是否自动删除 * 2:是否允许其他的通道来进行访问 * 第四个参数:是否自动删除 * 当最后一个连接断开的时候 是否需要自动删除 * 第五个参数:申明队列带的这个参数 * / channel.queueDeclare(QUEUE_NAME,false,false,false,null); //申明交换机 channel.exchangeDeclare(EXCHANGE_NAME,“fanout”); //将队列绑定到交换机上 channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,""); //没有确认的话 那么就不用分配任务给我 channel.basicQos(1); //申明了一个消费者 DefaultConsumer defaultConsumer = new DefaultConsumer(channel) { /* * * @param consumerTag:消费者的唯一的标记 * @param envelope:信封 就是将请求的消息封装成一个对象 * @param properties:前面队列带过来的属性的值 * @param body:消息体 * @throws IOException / @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println(“11111111111收到消息了:”+new String(body)); //表示的是手动告诉队列我已经收到这个消息了 channel.basicAck(envelope.getDeliveryTag(),false); } }; /* * 第一个参数:队列的名字 * 第二个参数:是否自动应答 false:表示的是要手动应答 没有应答的话 那么在队列中依然存在 * 第三个参数:消费者的申明 */ channel.basicConsume(QUEUE_NAME,false,defaultConsumer); } }

路由模式(有选择性的路由到提前设置好的队列)

1:生产者

public class Sender { //定义一个交换机的名字 private static final String EXCHANGE_NAME=“exchange2”; public static void main(String[] args) throws IOException, TimeoutException { Connection connection = ConnectionUtils.getConnection(); Channel channel = connection.createChannel(); //申明的是交换机 /** * 第一个参数:交换机的名字 * 第二个参数:交换机的类型 如果是发布订阅模式的话那么 交换机的类型只能是fanout / channel.exchangeDeclare(EXCHANGE_NAME,“direct”); //生产者发送信息到交换机 /* * 第二个参数:路由的key * 这个key可以进行自己设置 xiaobobo */ for (int i = 0; i <100 ; i++) { channel.basicPublish(EXCHANGE_NAME,“xiaowangzi”,null,(“发布订阅模式下的值”+i).getBytes()); } //关闭资源 channel.close(); connection.close(); } }

2:消费者1

public class Consumer1 { private static final String QUEUE_NAME=“queue_07”; private static final String EXCHANGE_NAME=“exchange2”; public static void main(String[] args) throws IOException, TimeoutException { //第一步:获取连接 Connection connection = ConnectionUtils.getConnection(); //第二步:创建通道 final Channel channel = connection.createChannel(); //第三步:申明队列 /** * 第一个参数:队列的名字 * 第二个参数:是否持久化 如果rabbitmq从新启动的话 那么 这个数据会丢失 持久化就可以解决这个问题 * 第三个参数:是否排外 * 1:连接关闭之后这个队列是否自动删除 * 2:是否允许其他的通道来进行访问 * 第四个参数:是否自动删除 * 当最后一个连接断开的时候 是否需要自动删除 * 第五个参数:申明队列带的这个参数 * / channel.queueDeclare(QUEUE_NAME,false,false,false,null); //申明交换机 channel.exchangeDeclare(EXCHANGE_NAME,“direct”); //将队列绑定到交换机上 channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,“xiaobobo”); //没有确认的话 那么就不用分配任务给我 channel.basicQos(1); //申明了一个消费者 DefaultConsumer defaultConsumer = new DefaultConsumer(channel) { /* * * @param consumerTag:消费者的唯一的标记 * @param envelope:信封 就是将请求的消息封装成一个对象 * @param properties:前面队列带过来的属性的值 * @param body:消息体 * @throws IOException / @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println(“11111111111收到消息了:”+new String(body)); //表示的是手动告诉队列我已经收到这个消息了 channel.basicAck(envelope.getDeliveryTag(),false); } }; /* * 第一个参数:队列的名字 * 第二个参数:是否自动应答 false:表示的是要手动应答 没有应答的话 那么在队列中依然存在 * 第三个参数:消费者的申明 */ channel.basicConsume(QUEUE_NAME,false,defaultConsumer); } }

3:消费者2

public class Consumer2 { private static final String QUEUE_NAME=“queue_08”; private static final String EXCHANGE_NAME=“exchange2”; public static void main(String[] args) throws IOException, TimeoutException { //第一步:获取连接 Connection connection = ConnectionUtils.getConnection(); //第二步:创建通道 final Channel channel = connection.createChannel(); //第三步:申明队列 /** * 第一个参数:队列的名字 * 第二个参数:是否持久化 如果rabbitmq从新启动的话 那么 这个数据会丢失 持久化就可以解决这个问题 * 第三个参数:是否排外 * 1:连接关闭之后这个队列是否自动删除 * 2:是否允许其他的通道来进行访问 * 第四个参数:是否自动删除 * 当最后一个连接断开的时候 是否需要自动删除 * 第五个参数:申明队列带的这个参数 * / channel.queueDeclare(QUEUE_NAME,false,false,false,null); //申明交换机 channel.exchangeDeclare(EXCHANGE_NAME,“direct”); //将队列绑定到交换机上 channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,“xiaowangzi”); //没有确认的话 那么就不用分配任务给我 channel.basicQos(1); //申明了一个消费者 DefaultConsumer defaultConsumer = new DefaultConsumer(channel) { /* * * @param consumerTag:消费者的唯一的标记 * @param envelope:信封 就是将请求的消息封装成一个对象 * @param properties:前面队列带过来的属性的值 * @param body:消息体 * @throws IOException / @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println(“11111111111收到消息了:”+new String(body)); //表示的是手动告诉队列我已经收到这个消息了 channel.basicAck(envelope.getDeliveryTag(),false); } }; /* * 第一个参数:队列的名字 * 第二个参数:是否自动应答 false:表示的是要手动应答 没有应答的话 那么在队列中依然存在 * 第三个参数:消费者的申明 */ channel.basicConsume(QUEUE_NAME,false,defaultConsumer); } }

主题模式(比路由模式要高级一点 设置路由的key的时候只需要设置前缀就可以了)

生产者

public class Sender { //定义一个交换机的名字 private static final String EXCHANGE_NAME=“exchange3”; public static void main(String[] args) throws IOException, TimeoutException { Connection connection = ConnectionUtils.getConnection(); Channel channel = connection.createChannel(); //申明的是交换机 /** * 第一个参数:交换机的名字 * 第二个参数:交换机的类型 如果是发布订阅模式的话那么 交换机的类型只能是fanout / channel.exchangeDeclare(EXCHANGE_NAME,“topic”); //生产者发送信息到交换机 /* * 第二个参数:路由的key * 这个key可以进行自己设置 xiaobobo */ for (int i = 0; i <100 ; i++) { channel.basicPublish(EXCHANGE_NAME,“xiaobobo.asasfcsvofhnjwv”,null,(“发布订阅模式下的值”+i).getBytes()); } //关闭资源 channel.close(); connection.close(); } }

消费者1

public class Consumer1 { private static final String QUEUE_NAME=“queue_09”; private static final String EXCHANGE_NAME=“exchange3”; public static void main(String[] args) throws IOException, TimeoutException { //第一步:获取连接 Connection connection = ConnectionUtils.getConnection(); //第二步:创建通道 final Channel channel = connection.createChannel(); //第三步:申明队列 /** * 第一个参数:队列的名字 * 第二个参数:是否持久化 如果rabbitmq从新启动的话 那么 这个数据会丢失 持久化就可以解决这个问题 * 第三个参数:是否排外 * 1:连接关闭之后这个队列是否自动删除 * 2:是否允许其他的通道来进行访问 * 第四个参数:是否自动删除 * 当最后一个连接断开的时候 是否需要自动删除 * 第五个参数:申明队列带的这个参数 * / channel.queueDeclare(QUEUE_NAME,false,false,false,null); //申明交换机 channel.exchangeDeclare(EXCHANGE_NAME,“topic”); //将队列绑定到交换机上 channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"xiaobobo."); //没有确认的话 那么就不用分配任务给我 channel.basicQos(1); //申明了一个消费者 DefaultConsumer defaultConsumer = new DefaultConsumer(channel) { /** * * @param consumerTag:消费者的唯一的标记 * @param envelope:信封 就是将请求的消息封装成一个对象 * @param properties:前面队列带过来的属性的值 * @param body:消息体 * @throws IOException / @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println(“11111111111收到消息了:”+new String(body)); //表示的是手动告诉队列我已经收到这个消息了 channel.basicAck(envelope.getDeliveryTag(),false); } }; /* * 第一个参数:队列的名字 * 第二个参数:是否自动应答 false:表示的是要手动应答 没有应答的话 那么在队列中依然存在 * 第三个参数:消费者的申明 */ channel.basicConsume(QUEUE_NAME,false,defaultConsumer); } }

消费者2

public class Consumer2 { private static final String QUEUE_NAME=“queue_10”; private static final String EXCHANGE_NAME=“exchange3”; public static void main(String[] args) throws IOException, TimeoutException { //第一步:获取连接 Connection connection = ConnectionUtils.getConnection(); //第二步:创建通道 final Channel channel = connection.createChannel(); //第三步:申明队列 /** * 第一个参数:队列的名字 * 第二个参数:是否持久化 如果rabbitmq从新启动的话 那么 这个数据会丢失 持久化就可以解决这个问题 * 第三个参数:是否排外 * 1:连接关闭之后这个队列是否自动删除 * 2:是否允许其他的通道来进行访问 * 第四个参数:是否自动删除 * 当最后一个连接断开的时候 是否需要自动删除 * 第五个参数:申明队列带的这个参数 * / channel.queueDeclare(QUEUE_NAME,false,false,false,null); //申明交换机 channel.exchangeDeclare(EXCHANGE_NAME,“topic”); //将队列绑定到交换机上 channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"xiaowangzi."); //没有确认的话 那么就不用分配任务给我 channel.basicQos(1); //申明了一个消费者 DefaultConsumer defaultConsumer = new DefaultConsumer(channel) { /** * * @param consumerTag:消费者的唯一的标记 * @param envelope:信封 就是将请求的消息封装成一个对象 * @param properties:前面队列带过来的属性的值 * @param body:消息体 * @throws IOException / @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { System.out.println(“11111111111收到消息了:”+new String(body)); //表示的是手动告诉队列我已经收到这个消息了 channel.basicAck(envelope.getDeliveryTag(),false); } }; /* * 第一个参数:队列的名字 * 第二个参数:是否自动应答 false:表示的是要手动应答 没有应答的话 那么在队列中依然存在 * 第三个参数:消费者的申明 */ channel.basicConsume(QUEUE_NAME,false,defaultConsumer); } }

列的名字 * 第二个参数:是否自动应答 false:表示的是要手动应答 没有应答的话 那么在队列中依然存在 * 第三个参数:消费者的申明 */ channel.basicConsume(QUEUE_NAME,false,defaultConsumer); } }

​ p

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值