rabbitmq的應用總結

環境搭建

項目採用springboot整合rabbitmq完成,所以項目的一些配置都是採用springboot操作

pom配置文件

   <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

mq的基本配置

rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: xxxx
    publisher-confirms: true

mq的配置類

package com.example.springbootjpa.mq;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

/**
 * @Author: weidl
 * @Description:
 * @Date: Created in 10:18 2019/5/15
 */
@Configuration
public class MqConfiguration {
    /**
     * voice
     */
    public static final  String QUEUE_VOICE_MESSAGE="queue_voice_message";
    public static final String EXCHANGE_VOICE_MESSAGE="VoiceMessaging.DomainEvent";

    @Bean(EXCHANGE_VOICE_MESSAGE)
    public Exchange exchangeVoiceMessage() {
        return ExchangeBuilder.fanoutExchange(EXCHANGE_VOICE_MESSAGE).durable(true).build();
    }


    @Bean(QUEUE_VOICE_MESSAGE)
    public Queue queueVoiceMessage() {
        return new Queue(QUEUE_VOICE_MESSAGE);
    }

    @Bean
    public Binding queueVoice(@Qualifier(QUEUE_VOICE_MESSAGE) Queue queue, @Qualifier(EXCHANGE_VOICE_MESSAGE) Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with("").noargs();
    }
 
}

上邊的內容就是聲明交換機,聲明隊列,將隊列綁定到交換機上。
ExchangeBuilder.fanoutExchange(EXCHANGE_VOICE_MESSAGE).durable(true).build();
這段代碼意思就是聲明的交換機可以進行持久化。
隊列採用了new Queue(QUEUE_VOICE_MESSAGE);這裏默認頁就可以進行持久化操作
消息持久化不僅僅需要上邊兩個持久化方式還必須需要消息持久化,在投遞時指定delivery_mode=> 2(1是非持久化)。
同時設置三個持久化方式,那麼消息就可以被持久化了。

發送消息

public class SendMessageController {
    @Autowired
    private AmqpTemplate amqpTemplate;

    @GetMapping("send")
    public void sendMessage(){
         Student student=new Student();
        student.setId(123);
        student.setName("張三");
        amqpTemplate.convertAndSend(student);
        Object o = amqpTemplate.convertSendAndReceive("VoiceMessaging.DomainEvent", "", student);
        System.out.println("消息已經發送,返回的結果爲:{}"+o);
    }
    @GetMapping("test")
    public void test(){
        System.out.println("========================發送消息");
    }
}

上邊的代碼我們採用了convertSendAndReceive方法這裏離的方法是有返回值操作的,我們可以通過消費者拿到數據然後返回給發送方。

接收消息

@Component
@RabbitListener(queues = "queue_voice_message")
public class ReceiveMessage {
    public  static int count=0;
    @RabbitHandler
    public String processC(Student student, Message message){
        String msgStr =  new String();
    System.out.println("------------------>監聽的內容爲:"+msgStr);
        System.out.println("這是第"+(count++)+"次重試");
        return "消息消費成功";
}

點擊發送消息我們就可以看到創建了隊列和交換機
隊列
交換機

消費端

------------------>監聽的內容爲:
這是第0次重試
消息已經發送,返回的結果爲:{}消息消費成功

上邊感覺還不錯吧,但是如果我在消費過程正增加如下代碼:

int i=1/0;

那麼在此點擊發送會發現消費端一直在請求。無限次重試,這裏很不友好吧,所以我們需要進行對重試機制加以控制。

  listener:
      simple:
        retry:
#          開啓重試機制
          enabled: true
          #最大重試次數(默認無數次)
          max-attempts: 5
          #重試間隔時間
          initial-interval: 3000

上邊內容我就不多講了,
拓展一些,如果五次失敗之後,我們可以通過發郵件方式通知管理員。對於每次消費都不一定進行重試,如果是客戶端發送問題我們可以採用重試方式,但是對於消費端出現的問題,我們就沒有必要進行重試操作,因爲一次出現問題,那麼必定每次都會出現。注意,有時候在隊列中一直有消息未被消費,我們更改代碼後也無法消費掉,此時我們可採取進入到rabbitmq的控制檯中找到對應的隊列將其刪除即可。

下一章進行詳解回調相關內容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章