springboot整合rabbitmq

rabbitmq的七种模式

Hello word

客户端引入依赖

复制代码
<!--rabbitmq 依赖客户端-->
 <dependency>
     <groupId>com.rabbitmq</groupId>
     <artifactId>amqp-client</artifactId>
     <version>5.8.0</version>
 </dependency>

生产者

java 复制代码
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class Producer {
    private final static String QUEUE_NAME = "hello";

    public static void main(String[] args) throws Exception {
                //创建一个连接工厂
                ConnectionFactory factory = new ConnectionFactory();
                factory.setHost("43.139.59.28");
                factory.setUsername("guest");
                factory.setPassword("guest");
                //channel 实现了自动 close 接口 自动关闭 不需要显示关闭
                try(Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
                /**
                * 生成一个队列
                * 1.队列名称
                * 2.队列里面的消息是否持久化 默认消息存储在内存中
                * 3.该队列是否只供一个消费者进行消费 是否进行共享 true 可以多个消费者消费
                * 4.是否自动删除 最后一个消费者端开连接以后 该队列是否自动删除 true 自动删除
                * 5.其他参数
                */
                channel.queueDeclare(QUEUE_NAME,false,false,false,null);
                String message="hello world!!!!";
                /**
                * 发送一个消息
                * 1.发送到那个交换机
                * 2.路由的 key 是哪个
                * 3.其他的参数信息
                * 4.发送消息的消息体
                */
                channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
                System.out.println("消息发送完毕");
           }
    }
}

消费者

java 复制代码
import com.rabbitmq.client.*;

public class Consumer {
       private final static String QUEUE_NAME = "hello";

      public static void main(String[] args) throws Exception {
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("43.139.59.28");
            factory.setUsername("guest");
            factory.setPassword("guest");
            Connection connection = factory.newConnection();
            Channel channel = connection.createChannel();
            System.out.println("等待接收消息....");
            //推送的消息如何进行消费的接口回调
            DeliverCallback deliverCallback=(consumerTag, delivery)->{
            String message= new String(delivery.getBody());
            System.out.println(message);
            };
            //取消消费的一个回调接口 如在消费的时候队列被删除掉了
            CancelCallback cancelCallback=(consumerTag)->{
            System.out.println("消息消费被中断");
            };
             /**
              * 消费者消费消息
              * 1.消费哪个队列
              * 2.消费成功之后是否要自动应答 true 代表自动应答 false 手动应答
              * 3.消费者未成功消费的回调
              */
             channel.basicConsume(QUEUE_NAME,true,deliverCallback,cancelCallback);
      }
}

获取消息

工作队列

封装获取getChannel的工具类

java 复制代码
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class RabbitMqUtils {
     //得到一个连接的 channel
     public static Channel getChannel() throws Exception{
         //创建一个连接工厂
         ConnectionFactory factory = new ConnectionFactory();
         factory.setHost("43.139.59.28");
         factory.setUsername("guest");
         factory.setPassword("guest");
         Connection connection = factory.newConnection();
         Channel channel = connection.createChannel();
         return channel;
     }
}

接收消息工作1线程

java 复制代码
import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;

public class Worker01 {
     private static final String QUEUE_NAME="hello";

     public static void main(String[] args) throws Exception {
         Channel channel = RabbitMqUtils.getChannel();
         DeliverCallback deliverCallback=(consumerTag, delivery)->{
         String receivedMessage = new String(delivery.getBody());
         System.out.println("接收到消息:"+receivedMessage);
         };
         CancelCallback cancelCallback=(consumerTag)->{
         System.out.println(consumerTag+"消费者取消消费接口回调逻辑");
         };
         System.out.println("C1 消费者启动等待消费......");
         channel.basicConsume(QUEUE_NAME,true,deliverCallback,cancelCallback);
     }
}

接收消息工作线程2

java 复制代码
import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;

public class Worker02 {
    private static final String QUEUE_NAME="hello";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        DeliverCallback deliverCallback=(consumerTag, delivery)->{
            String receivedMessage = new String(delivery.getBody());
            System.out.println("接收到消息:"+receivedMessage);
        };
        CancelCallback cancelCallback=(consumerTag)->{
            System.out.println(consumerTag+"消费者取消消费接口回调逻辑");
        };
        System.out.println("C2 消费者启动等待消费......");
        channel.basicConsume(QUEUE_NAME,true,deliverCallback,cancelCallback);
    }
}

发送10次消息

线程1和线程2平分消息

发布订阅

RabbitMQ 消息传递模型的核心思想是: 生产者生产的消息从不会直接发送到队列。实际上,通常生产者甚至都不知道这些消息传递传递到了哪些队列中。
总共有以下类型: 直接(direct), 主题 (topic) , 标题 (headers) , 扇出 (fanout)

fanout

接收者1

java 复制代码
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;

public class ReceiveLogs01 {
    private static final String EXCHANGE_NAME = "logs";

    public static void main(String[] argv) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
        /**
        * 生成一个临时的队列 队列的名称是随机的
        * 当消费者断开和该队列的连接时 队列自动删除
        */
        String queueName = channel.queueDeclare().getQueue();
        //把该临时队列绑定我们的 exchange 其中 routingkey(也称之为 binding key)为空字符串
        channel.queueBind(queueName, EXCHANGE_NAME, "");
        System.out.println("等待接收消息,把接收到的消息打印在屏幕.....");
        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
           String message = new String(delivery.getBody(), "UTF-8");
           System.out.println("控制台打印接收到的消息"+message);
        };
     channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { });
   }
}

接收者2

java 复制代码
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import org.apache.commons.io.FileUtils;

import java.io.File;

public class ReceiveLogs02 {
    private static final String EXCHANGE_NAME = "logs";
    public static void main(String[] argv) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
        /**
        * 生成一个临时的队列 队列的名称是随机的
        * 当消费者断开和该队列的连接时 队列自动删除
        */
        String queueName = channel.queueDeclare().getQueue();
        //把该临时队列绑定我们的 exchange 其中 routingkey(也称之为 binding key)为空字符串
        channel.queueBind(queueName, EXCHANGE_NAME, "");
        System.out.println("等待接收消息,把接收到的消息写到文件.....");
        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
           String message = new String(delivery.getBody(), "UTF-8");
//           File file = new File("C:\\work\\rabbitmq_info.txt");
//           FileUtils.writeStringToFile(file,message,"UTF-8");
           System.out.println("数据写入文件成功"+message);
        };
        channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { });
    }
}

发送者

java 复制代码
import com.rabbitmq.client.Channel;

import java.util.Scanner;

public class EmitLog {
     private static final String EXCHANGE_NAME = "logs";

     public static void main(String[] argv) throws Exception {
         try (Channel channel = RabbitMqUtils.getChannel()) {
            /**
            * 声明一个 exchange
            * 1.exchange 的名称
            * 2.exchange 的类型
            */
            channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入信息");
            while (sc.hasNext()) {
               String message = sc.nextLine();
               channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8"));
               System.out.println("生产者发出消息" + message);
            }
         }
     }
}

结果

Direct

接收者1 ,写入错误日志

java 复制代码
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import org.apache.commons.io.FileUtils;

import java.io.File;

public class ReceiveLogsDirect01 {
    private static final String EXCHANGE_NAME = "direct_logs";
      public static void main(String[] argv) throws Exception {
         Channel channel = RabbitMqUtils.getChannel();
         channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
         String queueName = "disk";
         channel.queueDeclare(queueName, false, false, false, null);
         channel.queueBind(queueName, EXCHANGE_NAME, "error");
         System.out.println("等待接收消息.....");
         DeliverCallback deliverCallback = (consumerTag, delivery) -> {
             String message = new String(delivery.getBody(), "UTF-8");
             message="接收绑定键:"+delivery.getEnvelope().getRoutingKey()+",消息:"+message;
//             File file = new File("C:\\work\\rabbitmq_info.txt");
//             FileUtils.writeStringToFile(file,message,"UTF-8");
             System.out.println("错误日志已经接收"+message);
         };
         channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {
         });
      }
}

接收者2,打印控制台信息

java 复制代码
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;

public class ReceiveLogsDirect02 {
        private static final String EXCHANGE_NAME = "direct_logs";
        public static void main(String[] argv) throws Exception {
           Channel channel = RabbitMqUtils.getChannel();
           channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
           String queueName = "console";
           channel.queueDeclare(queueName, false, false, false, null);
           channel.queueBind(queueName, EXCHANGE_NAME, "info");
           channel.queueBind(queueName, EXCHANGE_NAME, "warning");
           System.out.println("等待接收消息.....");
           DeliverCallback deliverCallback = (consumerTag, delivery) -> {
              String message = new String(delivery.getBody(), "UTF-8");
              System.out.println(" 接收绑定键 :"+delivery.getEnvelope().getRoutingKey()+", 消息:"+message);
           };
           channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {
           });
        }
}

发送者

java 复制代码
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;

import java.util.HashMap;
import java.util.Map;

public class EmitLogDirect {
    private static final String EXCHANGE_NAME = "direct_logs";
     public static void main(String[] argv) throws Exception {
     try (Channel channel = RabbitMqUtils.getChannel()) {
         channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
         //创建多个 bindingKey
         Map<String, String> bindingKeyMap = new HashMap<>();
         bindingKeyMap.put("info","普通 info 信息");
         bindingKeyMap.put("warning","警告 warning 信息");
         bindingKeyMap.put("error","错误 error 信息");
         //debug 没有消费这接收这个消息 所有就丢失了
         bindingKeyMap.put("debug","调试 debug 信息");
         for (Map.Entry<String, String> bindingKeyEntry: bindingKeyMap.entrySet()){
            String bindingKey = bindingKeyEntry.getKey();
            String message = bindingKeyEntry.getValue();
            channel.basicPublish(EXCHANGE_NAME,bindingKey, null, 
            message.getBytes("UTF-8"));
            System.out.println("生产者发出消息:" + message);
         }
     }
     }
}

接收到信息

Topics

主题1

java 复制代码
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;

public class ReceiveLogsTopic01 {
       private static final String EXCHANGE_NAME = "topic_logs";
       public static void main(String[] argv) throws Exception {
          Channel channel = RabbitMqUtils.getChannel();
          channel.exchangeDeclare(EXCHANGE_NAME, "topic");
          //声明 Q1 队列与绑定关系
          String queueName="Q1";
          channel.queueDeclare(queueName, false, false, false, null);
          channel.queueBind(queueName, EXCHANGE_NAME, "*.orange.*");
          System.out.println("等待接收消息.....");
          DeliverCallback deliverCallback = (consumerTag, delivery) -> {
             String message = new String(delivery.getBody(), "UTF-8");
             System.out.println(" 接收队列 :"+queueName+" 绑 定 键:"+delivery.getEnvelope().getRoutingKey()+",消息:"+message);
          };
          channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {
          });
       }
}

主题2

java 复制代码
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;

public class ReceiveLogsTopic02 {
     private static final String EXCHANGE_NAME = "topic_logs";
      public static void main(String[] argv) throws Exception {
          Channel channel = RabbitMqUtils.getChannel();
          channel.exchangeDeclare(EXCHANGE_NAME, "topic");
          //声明 Q2 队列与绑定关系
          String queueName="Q2";
          channel.queueDeclare(queueName, false, false, false, null);
          channel.queueBind(queueName, EXCHANGE_NAME, "*.*.rabbit");
          channel.queueBind(queueName, EXCHANGE_NAME, "lazy.#");
          System.out.println("等待接收消息.....");
          DeliverCallback deliverCallback = (consumerTag, delivery) -> {
             String message = new String(delivery.getBody(), "UTF-8");
             System.out.println(" 接收队列 :"+queueName+" 绑 定 键:"+delivery.getEnvelope().getRoutingKey()+",消息:"+message);
          };
          channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {
          });
      }
}

发送者

java 复制代码
import com.rabbitmq.client.Channel;

import java.util.HashMap;
import java.util.Map;

public class EmitLogTopic {
    private static final String EXCHANGE_NAME = "topic_logs";
     public static void main(String[] argv) throws Exception {
         try (Channel channel = RabbitMqUtils.getChannel()) {
         channel.exchangeDeclare(EXCHANGE_NAME, "topic");
         /**
         * Q1-->绑定的是
         * 中间带 orange 带 3 个单词的字符串(*.orange.*)
         * Q2-->绑定的是
         * 最后一个单词是 rabbit 的 3 个单词(*.*.rabbit)
         * 第一个单词是 lazy 的多个单词(lazy.#)
         *
         */
         Map<String, String> bindingKeyMap = new HashMap<>();
         bindingKeyMap.put("quick.orange.rabbit","被队列 Q1Q2 接收到");
         bindingKeyMap.put("lazy.orange.elephant","被队列 Q1Q2 接收到");
         bindingKeyMap.put("quick.orange.fox","被队列 Q1 接收到");
         bindingKeyMap.put("lazy.brown.fox","被队列 Q2 接收到");
         bindingKeyMap.put("lazy.pink.rabbit","虽然满足两个绑定但只被队列 Q2 接收一次");
         bindingKeyMap.put("quick.brown.fox","不匹配任何绑定不会被任何队列接收到会被丢弃");
         bindingKeyMap.put("quick.orange.male.rabbit","是四个单词不匹配任何绑定会被丢弃");
         bindingKeyMap.put("lazy.orange.male.rabbit","是四个单词但匹配 Q2");
           for (Map.Entry<String, String> bindingKeyEntry: bindingKeyMap.entrySet()){
              String bindingKey = bindingKeyEntry.getKey();
              String message = bindingKeyEntry.getValue();
              channel.basicPublish(EXCHANGE_NAME,bindingKey, null, 
             message.getBytes("UTF-8"));
              System.out.println("生产者发出消息" + message);
           }
         }
     }
}

结果

相关推荐
seventeennnnn1 小时前
谢飞机的Java高级开发面试:从Spring Boot到分布式架构的蜕变之旅
spring boot·微服务架构·java面试·分布式系统·电商支付
超级小忍2 小时前
服务端向客户端主动推送数据的几种方法(Spring Boot 环境)
java·spring boot·后端
时间会给答案scidag3 小时前
报错 400 和405解决方案
vue.js·spring boot
Wyc724093 小时前
SpringBoot
java·spring boot·spring
ladymorgana5 小时前
【Spring Boot】HikariCP 连接池 YAML 配置详解
spring boot·后端·mysql·连接池·hikaricp
GJCTYU6 小时前
spring中@Transactional注解和事务的实战理解附代码
数据库·spring boot·后端·spring·oracle·mybatis
风象南7 小时前
SpringBoot敏感配置项加密与解密实战
java·spring boot·后端
写不出来就跑路8 小时前
暑期实习感悟与经验分享:从校园到职场的成长之路
java·开发语言·经验分享·spring boot
程序员张313 小时前
Maven编译和打包插件
java·spring boot·maven
灵犀学长14 小时前
EasyExcel之SheetWriteHandler:解锁Excel写入的高阶玩法
spring boot·excel