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);
           }
         }
     }
}

结果

相关推荐
用户908324602731 天前
Spring AI 1.1.2 + Neo4j:用知识图谱增强 RAG 检索(上篇:图谱构建)
java·spring boot
用户8307196840822 天前
Spring Boot 集成 RabbitMQ :8 个最佳实践,杜绝消息丢失与队列阻塞
spring boot·后端·rabbitmq
Java水解2 天前
Spring Boot 视图层与模板引擎
spring boot·后端
Java水解2 天前
一文搞懂 Spring Boot 默认数据库连接池 HikariCP
spring boot·后端
洋洋技术笔记2 天前
Spring Boot Web MVC配置详解
spring boot·后端
初次攀爬者3 天前
Kafka 基础介绍
spring boot·kafka·消息队列
用户8307196840823 天前
spring ai alibaba + nacos +mcp 实现mcp服务负载均衡调用实战
spring boot·spring·mcp
Java水解3 天前
SpringBoot3全栈开发实战:从入门到精通的完整指南
spring boot·后端
用户8307196840824 天前
RabbitMQ vs RocketMQ 事务大对决:一个在“裸奔”,一个在“开挂”?
后端·rabbitmq·rocketmq
初次攀爬者4 天前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq