springboot使用rabbitmq

使用springboot创建rabbitMQ的链接。

整个项目结构如下:

1.maven依赖

xml 复制代码
<dependency>
    	<groupId>com.rabbitmq</groupId>
    	<artifactId>amqp-client</artifactId>
    	<version>3.4.1</version>
</dependency>

application.yaml的配置如下

yaml 复制代码
spring:
  application:
    name: rabbitMQ
  rabbitmq:
    host: 192.168.142.128  #rabbitmq的主机名
    port: 5672			   #端口,默认5672
    username: itheima      #rabbitmq的账号
    password: 123321	   #密码
server:
  port: 8081               #项目启动端口

2.创建rabbitMQ配置类 -- RabbitConfig。

java 复制代码
@Configuration
@Slf4j
public class RabbitConfig {

    @Bean("directExchange")
    public DirectExchange directExchange() {
        return new DirectExchange(MQConstant.DIRECT_EXCHANGE);
    }

    @Bean("directQueue")
    public Queue directQueue() {
        return new Queue(MQConstant.DIRECT_QUEUE);
    }

    @Bean("bindingDirectExchange")
    public Binding bindingDirectExchange(@Qualifier("directExchange") DirectExchange directExchange,
                                         @Qualifier("directQueue") Queue directQueue) {
        return BindingBuilder.bind(directQueue).to(directExchange).with(MQConstant.ROUTING_KEY);
    }

}

3.创建RabbitMQ客户端类,主要是用来发送消息用的。

java 复制代码
@Component
@Slf4j
public class RabbitMqClient {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void send(MessageBody messageBody){
        try{
            String uuid = UUID.randomUUID().toString();
            CorrelationData correlationData = new CorrelationData(uuid);
            rabbitTemplate.convertAndSend(MQConstant.DIRECT_EXCHANGE, MQConstant.ROUTING_KEY, JSON.toJSONString(messageBody),
                    new MessagePostProcessor() {
                        @Override
                        public Message postProcessMessage(Message message) throws AmqpException {
                            // 消息持久化
                            message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                            log.info("message send,{}", message);
                            return message;
                        }
                    },correlationData);
            log.info("message send successful");
        }catch (Exception e){
            log.info("send message error:{}",e);
        }
    }
}

4.创建接收消息类 ---RabbitMqServer

java 复制代码
@Component
@Slf4j
public class RabbitMqServer {

    @RabbitListener(queues = MQConstant.DIRECT_QUEUE)
    public void receive(String message) {
        try {
            log.info("receive message:{}", message);
            MessageBody messageBody = JSON.parseObject(message, MessageBody.class);
            switch (messageBody.getTopic()) {
                case QueueTopic.USER_LOGIN:
                    User user = JSON.parseObject(messageBody.getData(), User.class);
                    log.info("receive user:{}", user);
                    break;
                default:
                    log.info("no need hanndle message:{},topic:{}", message, messageBody.getTopic());
                    break;
            }
        }catch (Exception e){
            log.error("rabbitmq receive message error:{}", e);
        }
    }
}

5.有了以上准备后就可以开始向mq里面发送消息了,在单元测试编写测试代码。

java 复制代码
@SpringBootTest(classes = RabbitMqApplication.class)
class RabbitMqApplicationTests {

	@Autowired
	private RabbitMqClient rabbitMqClient;

	@Test
	void testDirectSend() {
		//数据
		User user = new User();
		user.setId(123);
		user.setName("Lewin-jie2");
		user.setPassword("123");

		MessageBody messageBody = new MessageBody();
		messageBody.setData(JSON.toJSONString(user));

		long time = new Date().getTime();
		messageBody.setSendTime(time);
		//添加主题
		messageBody.setTopic(QueueTopic.USER_LOGIN);
		rabbitMqClient.send(messageBody);
	}

}

6.运行后,可以看到后台的日志,证明我们消息发送已经成功了。

我们打开rabbitmq的控制台(http://你的主机名:15672),可以开到队列里面也收到了消息,但是还没有被消费。

以上出现结果就证明rabbit已经是配置好了。那么我们来了解一下啊rabbitmq

简介:rabbitmq是基于amqp协议,用elang语言开发的一个高级的消息队列,以高性能,高可靠,高吞吐量而被大量应用到应用系统作为第三方消息中间件使用,为应用系统实现应用解耦削峰减流,异步消息

rabbitmq主要构造有,producter,consumer,exchange,queue组成

1.直连交换机(direct_exchange)。

刚刚配置的时候就是演示的producter发消息到直连交换机,然后再发送到queue中的过程。

2.广播交换机(fanout_exchange).

顾名思义,就是绑定该交换机的所有队列都可以收到这个交换机的消息

java 复制代码
	@Bean("fanoutExchange")
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange(MQConstant.FANOUT_EXCHANGE);
    }

    @Bean("aQueue")
    public Queue aQueue(){
        return new Queue(MQConstant.FANOUT_QUEUE_A);
    }

    @Bean("bQueue")
    public Queue bQueue(){
        return new Queue(MQConstant.FANOUT_QUEUE_B);
    }

    @Bean("cQueue")
    public Queue cQueue(){
        return new Queue(MQConstant.FANOUT_QUEUE_C);
    }

    /**
     * 绑定队列aQueue bQueue cQueue
     */
    @Bean("bindingFanoutExchange1")
    public Binding bindingFanoutExchange1(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange,
                                         @Qualifier("aQueue") Queue aQueue){
        return BindingBuilder.bind(aQueue).to(fanoutExchange);
    }

    @Bean("bindingFanoutExchange2")
    public Binding bindingFanoutExchange2(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange,
                                         @Qualifier("bQueue") Queue bQueue){
        return BindingBuilder.bind(bQueue).to(fanoutExchange);
    }

    @Bean("bindingFanoutExchange3")
    public Binding bindingFanoutExchange3(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange,
                                         @Qualifier("cQueue") Queue cQueue){
        return BindingBuilder.bind(cQueue).to(fanoutExchange);
    }

编写controller类,再postman上面测试[http://localhost:8081/mq/sendFanoutMsg?msg=hi i am a fanoutmag](http://localhost:8081/mq/sendFanoutMsg?msg=hi i am a fanoutmag)

java 复制代码
@Controller
@RequestMapping("/mq")
@Slf4j
public class SendMessageController {
    @Autowired
    private RabbitMqClient rabbitMqClient;

    @PostMapping("/sendFanoutMsg")
    public String sendFanoutMsg(@RequestParam("msg") String msg){
        try {
            MessageBody messageBody = new MessageBody();
            messageBody.setData(msg);
            rabbitMqClient.send1(messageBody);
        }catch (Exception e){
            log.error("sendFanoutMsg error{}", e);
        }
        return "send fanout msg success";
    }
}

结果:控制台收到消息了!!!

3.主题交换机(topic_exchange)

topic_exchange和direct_exchange很像,topic有通配符。direct没有。

  1. china.news 代表只关心中国新闻

  2. china.weather 代表只关心中国天气

  3. japan.news 代表只关心日本的新闻

  4. japan.weather 代表只关心日本的天气

    controller接口

    java 复制代码
    @PostMapping("/sendTopicMsg")
        public String sendTopicMsg(@RequestParam("msg") String msg,@RequestParam("type") String type){
            try {
                MessageBody messageBody = new MessageBody();
                messageBody.setData(msg);
                rabbitMqClient.send3(messageBody,type);
            }catch (Exception e){
                log.error("sendTopicMsg error{}", e);
            }
            return "send topic msg success";
        }

    利用postman测试。

    1.msg: "祖国75岁生日快乐",type:"china.news"

    预测:queue1,queue4会接收到消息。

    2.msg: "日本大量排核废水,导致哥斯拉出现",type:"japan.news"

    预测:queue2,queue4会接收到消息。

    3.msg: "今日日本出现大暴雨,怀疑是哥斯拉来了",type:"Japan.weather"

    预测:queue2,queue3会接收到消息

topic-exchange在代码中如何使用。首先创建交换机,和队列,绑定交换机。

java 复制代码
/*============================topic===========================*/
    @Bean("topicExchange")
    public TopicExchange topicExchange() {
        return new TopicExchange(MQConstant.TOPIC_EXCHANGE);
    }

    @Bean("queue1")
    public Queue queue1(){
        return new Queue(MQConstant.QUEUE1);
    }

    @Bean("queue2")
    public Queue queue2(){
        return new Queue(MQConstant.QUEUE2);
    }

    @Bean("queue3")
    public Queue queue3(){
        return new Queue(MQConstant.QUEUE3);
    }

    @Bean("queue4")
    public Queue queue4(){
        return new Queue(MQConstant.QUEUE4);
    }

    @Bean("bingTopicExchange1")
    public Binding bingTopicExchange1(@Qualifier("queue1") Queue queue1,
                                      @Qualifier("topicExchange") TopicExchange topicExchange) {
        return BindingBuilder.bind(queue1).to(topicExchange).with(MQConstant.CHINA_);
    }

    @Bean("bingTopicExchange2")
    public Binding bingTopicExchange2(@Qualifier("queue2") Queue queue2,
                                      @Qualifier("topicExchange") TopicExchange topicExchange) {
        return BindingBuilder.bind(queue2).to(topicExchange).with(MQConstant.JAPAN_);
    }

    @Bean("bingTopicExchange3")
    public Binding bingTopicExchange3(@Qualifier("queue3") Queue queue3,
                                      @Qualifier("topicExchange") TopicExchange topicExchange) {
        return BindingBuilder.bind(queue3).to(topicExchange).with(MQConstant._WEATHER);
    }

    @Bean("bingTopicExchange4")
    public Binding bingTopicExchange4(@Qualifier("queue4") Queue queue4,
                                      @Qualifier("topicExchange") TopicExchange topicExchange) {
        return BindingBuilder.bind(queue4).to(topicExchange).with(MQConstant._NEWS);
    }

消息发送

java 复制代码
 public void send3(MessageBody messageBody,String routingKey) {
        try{
            String uuid = UUID.randomUUID().toString();
            CorrelationData correlationData = new CorrelationData(uuid);
            rabbitTemplate.convertAndSend(MQConstant.TOPIC_EXCHANGE, routingKey , JSON.toJSONString(messageBody),
                    new MessagePostProcessor() {
                        @Override
                        public Message postProcessMessage(Message message) throws AmqpException {
                            // 消息持久化
                            message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                            log.info("message send,{}", message);
                            return message;
                        }
                    },correlationData);
            log.info("message send successful");
        }catch (Exception e){
            log.info("send message error:{}",e);
        }
    }

消息接收

java 复制代码
@RabbitListener(queues = MQConstant.QUEUE1)
    public void receive4(String message) {
        log.info("topic exchange");
        try {
            log.info("queue1 receive message:{}", message);
            MessageBody messageBody = JSON.parseObject(message, MessageBody.class);
            log.info("receive message:{}", messageBody.getData());
        }catch (Exception e){
            log.error("rabbitmq receive a message error:{}", e);
        }
    }

    @RabbitListener(queues = MQConstant.QUEUE2)
    public void receive5(String message) {
        log.info("topic exchange");
        try {
            log.info("queue2 receive message:{}", message);
            MessageBody messageBody = JSON.parseObject(message, MessageBody.class);
            log.info("receive message:{}", messageBody.getData());
        }catch (Exception e){
            log.error("rabbitmq receive a message error:{}", e);
        }
    }

    @RabbitListener(queues = MQConstant.QUEUE3)
    public void receive6(String message) {
        log.info("topic exchange");
        try {
            log.info("queue3 receive message:{}", message);
            MessageBody messageBody = JSON.parseObject(message, MessageBody.class);
            log.info("receive message:{}", messageBody.getData());
        }catch (Exception e){
            log.error("rabbitmq receive a message error:{}", e);
        }
    }

    @RabbitListener(queues = MQConstant.QUEUE4)
    public void receive7(String message) {
        log.info("topic exchange");
        try {
            log.info("queue4 receive message:{}", message);
            MessageBody messageBody = JSON.parseObject(message, MessageBody.class);
            log.info("receive message:{}", messageBody.getData());
        }catch (Exception e){
            log.error("rabbitmq receive a message error:{}", e);
        }
    }
相关推荐
kukubuzai2 小时前
文件(c语言文件流)
c语言·开发语言
黄同学real4 小时前
使用.NET 8构建高效的时间日期帮助类
后端·c#·.net
ChinaRainbowSea5 小时前
四.4 Redis 五大数据类型/结构的详细说明/详细使用( zset 有序集合数据类型详解和使用)
java·javascript·数据库·redis·后端·nosql
qq_447663057 小时前
java-----多线程
java·开发语言
a辰龙a7 小时前
【Java报错解决】警告: 源发行版 11 需要目标发行版 11
java·开发语言
听海边涛声7 小时前
JDK长期支持版本(LTS)
java·开发语言
IpdataCloud7 小时前
Java 获取本机 IP 地址的方法
java·开发语言·tcp/ip
MyMyMing7 小时前
Java的输入和输出
java·开发语言
Easonmax7 小时前
【javaSE】内部类(来自类和对象的补充)
开发语言·javascript·ecmascript
云夏之末7 小时前
【Java报错已解决】java.lang.UnsatisfiedLinkError
java·开发语言