亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot使用RabbitMQ延時(shí)隊(duì)列(小白必備)

 更新時(shí)間:2019年12月22日 14:28:48   作者:一元情書 釋  
這篇文章主要介紹了SpringBoot使用RabbitMQ延時(shí)隊(duì)列(小白必備),詳細(xì)的介紹延遲隊(duì)列的使用場景及其如何使用,需要的小伙伴可以一起來了解一下

1.什么是MQ

MQ,是一種跨進(jìn)程的通信機(jī)制,用于上下游傳遞消息。

在互聯(lián)網(wǎng)架構(gòu)中,MQ是一種非常常見的上下游“邏輯解耦+物理解耦”的消息通信服務(wù)。

使用了MQ之后,消息發(fā)送上游只需要依賴MQ,不用依賴其他服務(wù)。

為什么會產(chǎn)生消息列隊(duì)?

  1. 不同進(jìn)程(process)之間傳遞消息時(shí),兩個(gè)進(jìn)程之間耦合程度過高,改動一個(gè)進(jìn)程,引發(fā)必須修改另一個(gè)進(jìn)程,為了隔離這兩個(gè)進(jìn)程,在兩進(jìn)程間抽離出一層(一個(gè)模塊),所有兩進(jìn)程之間傳遞的消息,都必須通過消息隊(duì)列來傳遞,單獨(dú)修改某一個(gè)進(jìn)程,不會影響另一個(gè);
  2. 不同進(jìn)程(process)之間傳遞消息時(shí),為了實(shí)現(xiàn)標(biāo)準(zhǔn)化,將消息的格式規(guī)范化了,并且,某一個(gè)進(jìn)程接受的消息太多,一下子無法處理完,并且也有先后順序,必須對收到的消息進(jìn)行排隊(duì),因此誕生了事實(shí)上的消息隊(duì)列;

延時(shí)列隊(duì)的使用場景?

  1. 訂單業(yè)務(wù):在淘寶或者京東購買東西,用戶下單后未付款則30分鐘后取消訂單。
  2. 短信通知:手機(jī)用戶交完話費(fèi)后,幾分鐘之內(nèi)將會收到繳費(fèi)信息

2.什么是RabbitMQ(這里就做了一下簡單介紹)

RabbitMQ是一種消息隊(duì)列 ,用于常見的進(jìn)程通信。支持點(diǎn)對點(diǎn),請求應(yīng)答和發(fā)布訂閱模式 并且提供多種語言的支持。常見的java,c#,php都支持。

常被用在異步處理,應(yīng)用解耦。流量消鋒等復(fù)雜的業(yè)務(wù)場景中。和java的kafka一樣都屬于消息中間件。

下載地址:

https://www.rabbitmq.com/download.html

進(jìn)入RabbitMQ官網(wǎng)

1.第一步

在這里插入圖片描述

第二步

在這里插入圖片描述

下載好后不要著急安裝RabbitMQ,我們這里還需要安裝Erlang

下載地址:http://www.erlang.org/download/otp_win64_17.3.exe

安裝步驟

步驟一

在這里插入圖片描述

步驟二

在這里插入圖片描述

步驟三

在這里插入圖片描述

步驟四

在這里插入圖片描述

安裝完成

現(xiàn)在安裝RabbitMQ

步驟一

在這里插入圖片描述

步驟二

在這里插入圖片描述

步驟三

在這里插入圖片描述

安裝完成

啟動RabbitMQ管理工具

開始菜單 — 最新添加 — 展開 — 選中雙擊

在這里插入圖片描述

輸入命令:rabbitmq-plugins enable rabbitmq_management

效果如果圖

在這里插入圖片描述

在瀏覽器中輸入地址查看:http://127.0.0.1:15672/

在這里插入圖片描述

出現(xiàn)次頁面代表成功,默認(rèn)用戶和密碼都是guest/ guest

若不出現(xiàn)此頁面,就是安裝失敗了,不要慌,多半問題在系統(tǒng)用戶名必須是中文(放心有解決辦法):

Windows下安裝RabbitMQ后,按正常RabbitMQ會自動注冊服務(wù)并自動啟動,但是如果有的道友不注意中英文目錄就會出現(xiàn)服務(wù)啟動后幾秒鐘自動停止,而且反反復(fù)復(fù)。

出現(xiàn)這種情況一般都是由我們的用戶名是中文,而導(dǎo)致默認(rèn)的DB和log訪問出現(xiàn)問。所以我建議以后大家在使用windows操作系統(tǒng)的時(shí)候盡量用英文來命名文件或目錄,這樣會極大的減小以后安裝軟件出現(xiàn)莫名其妙的問題的bug。

接下來我們先卸載我們的RabbitMQ,然后在我們的系統(tǒng)變量里設(shè)置一個(gè)RABBITMQ_BASE 的變量路徑為一個(gè)不含英文的路徑 比如 E:\rabbit,最后我們重新安裝RabbitMQ即可,然后就會看到RabbitMQ服務(wù)自動注冊了,并且不會自動停止。

SpringBoot整合RabbitMQ

1.添加依賴

pom.xml中添加 spring-boot-starter-amqp的依賴

 <!-- spring-boot-starter-amqp的依賴 -->
      <dependency>
   <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
 </dependency>

其他依賴

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
  
      <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
      </dependency>
  
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
          <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
      
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
      </dependency>

application.yml文件中配置rabbitmq相關(guān)內(nèi)容

spring:
  rabbitmq:
   host: localhost
   port: 5672
   username: guest
   password: guest

這里我們環(huán)境就搭建起來了

2.具體編碼實(shí)現(xiàn)

配置列隊(duì)

 package com.example.spring_boot_rabbitmq;
  
  
  
  import lombok.extern.slf4j.Slf4j;
  import org.springframework.amqp.core.*;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  
  import java.util.HashMap;
  import java.util.Map;
  
  /**
   * @author:zq
   * @date: Greated in 2019/12/19 11:46
   * 配置隊(duì)列
   */
  
  @Configuration
  @Slf4j
  public class DelayRabbitConfig {
  
    /**
     * 延遲隊(duì)列 TTL 名稱
     */
    private static final String ORDER_DELAY_QUEUE = "user.order.delay.queue";
    /**
     * DLX,dead letter發(fā)送到的 exchange
     * 延時(shí)消息就是發(fā)送到該交換機(jī)的
     */
    public static final String ORDER_DELAY_EXCHANGE = "user.order.delay.exchange";
    /**
     * routing key 名稱
     * 具體消息發(fā)送在該 routingKey 的
     */
    public static final String ORDER_DELAY_ROUTING_KEY = "order_delay";
  
    public static final String ORDER_QUEUE_NAME = "user.order.queue";
    public static final String ORDER_EXCHANGE_NAME = "user.order.exchange";
    public static final String ORDER_ROUTING_KEY = "order";
  
    /**
     * 延遲隊(duì)列配置
     * <p>
     * 1、params.put("x-message-ttl", 5 * 1000);
     * 第一種方式是直接設(shè)置 Queue 延遲時(shí)間 但如果直接給隊(duì)列設(shè)置過期時(shí)間,這種做法不是很靈活,(當(dāng)然二者是兼容的,默認(rèn)是時(shí)間小的優(yōu)先)
     * 2、rabbitTemplate.convertAndSend(book, message -> {
     * message.getMessageProperties().setExpiration(2 * 1000 + "");
     * return message;
     * });
     * 第二種就是每次發(fā)送消息動態(tài)設(shè)置延遲時(shí)間,這樣我們可以靈活控制
     **/
    @Bean
    public Queue delayOrderQueue() {
      Map<String, Object> params = new HashMap<>();
      // x-dead-letter-exchange 聲明了隊(duì)列里的死信轉(zhuǎn)發(fā)到的DLX名稱,
      params.put("x-dead-letter-exchange", ORDER_EXCHANGE_NAME);
      // x-dead-letter-routing-key 聲明了這些死信在轉(zhuǎn)發(fā)時(shí)攜帶的 routing-key 名稱。
      params.put("x-dead-letter-routing-key", ORDER_ROUTING_KEY);
      return new Queue(ORDER_DELAY_QUEUE, true, false, false, params);
    }
    /**
     * 需要將一個(gè)隊(duì)列綁定到交換機(jī)上,要求該消息與一個(gè)特定的路由鍵完全匹配。
     * 這是一個(gè)完整的匹配。如果一個(gè)隊(duì)列綁定到該交換機(jī)上要求路由鍵 “dog”,則只有被標(biāo)記為“dog”的消息才被轉(zhuǎn)發(fā),
     * 不會轉(zhuǎn)發(fā)dog.puppy,也不會轉(zhuǎn)發(fā)dog.guard,只會轉(zhuǎn)發(fā)dog。
     * @return DirectExchange
     */
    @Bean
    public DirectExchange orderDelayExchange() {
      return new DirectExchange(ORDER_DELAY_EXCHANGE);
    }
    @Bean
    public Binding dlxBinding() {
      return BindingBuilder.bind(delayOrderQueue()).to(orderDelayExchange()).with(ORDER_DELAY_ROUTING_KEY);
    }
  
    @Bean
    public Queue orderQueue() {
      return new Queue(ORDER_QUEUE_NAME, true);
    }
    /**
     * 將路由鍵和某模式進(jìn)行匹配。此時(shí)隊(duì)列需要綁定要一個(gè)模式上。
     * 符號“#”匹配一個(gè)或多個(gè)詞,符號“*”匹配不多不少一個(gè)詞。因此“audit.#”能夠匹配到“audit.irs.corporate”,但是“audit.*” 只會匹配到“audit.irs”。
     **/
    @Bean
    public TopicExchange orderTopicExchange() {
      return new TopicExchange(ORDER_EXCHANGE_NAME);
    }
  
    @Bean
    public Binding orderBinding() {
      // TODO 如果要讓延遲隊(duì)列之間有關(guān)聯(lián),這里的 routingKey 和 綁定的交換機(jī)很關(guān)鍵
      return BindingBuilder.bind(orderQueue()).to(orderTopicExchange()).with(ORDER_ROUTING_KEY);
    }
  
  }

創(chuàng)建一個(gè)Order實(shí)體類

package com.example.spring_boot_rabbitmq.pojo;
 
 import lombok.Data;
 
 import java.io.Serializable;
 
 /**
  * @author:zq
  * @date: Greated in 2019/12/19 11:49
  */
 @Data
 public class Order implements Serializable {
   private static final long serialVersionUID = -2221214252163879885L;
 
   private String orderId; // 訂單id
 
   private Integer orderStatus; // 訂單狀態(tài) 0:未支付,1:已支付,2:訂單已取消
 
   private String orderName; // 訂單名字
 
 }

接收者

package com.example.spring_boot_rabbitmq;
 
 import com.example.spring_boot_rabbitmq.pojo.Order;
 import com.rabbitmq.client.Channel;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.amqp.core.Message;
 import org.springframework.amqp.rabbit.annotation.RabbitListener;
 import org.springframework.stereotype.Component;
 
 import java.util.Date;
 
 /**
  * @author:zq
  * @date: Greated in 2019/12/19 11:53
  * 接收者
  */
 
 @Component
 @Slf4j
 public class DelayReceiver {
   @RabbitListener(queues = {DelayRabbitConfig.ORDER_QUEUE_NAME})
   public void orderDelayQueue(Order order, Message message, Channel channel) {
     log.info("###########################################");
     log.info("【orderDelayQueue 監(jiān)聽的消息】 - 【消費(fèi)時(shí)間】 - [{}]- 【訂單內(nèi)容】 - [{}]", new Date(), order.toString());
     if(order.getOrderStatus() == 0) {
       order.setOrderStatus(2);
       log.info("【該訂單未支付,取消訂單】" + order.toString());
     } else if(order.getOrderStatus() == 1) {
       log.info("【該訂單已完成支付】");
     } else if(order.getOrderStatus() == 2) {
       log.info("【該訂單已取消】");
     }
     log.info("###########################################");
   }
 
 }

發(fā)送者

 package com.example.spring_boot_rabbitmq;
 
 
 import com.example.spring_boot_rabbitmq.pojo.Order;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.amqp.core.AmqpTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.Date;
 
 /**
 * @author:zq
 * @date: Greated in 2019/12/19 11:55
 * 發(fā)送者
 */
 @Component
 @Slf4j
 public class DelaySender {
   @Autowired
   private AmqpTemplate amqpTemplate;
 
   public void sendDelay(Order order) {
     log.info("【訂單生成時(shí)間】" + new Date().toString() +"【1分鐘后檢查訂單是否已經(jīng)支付】" + order.toString() );
     this.amqpTemplate.convertAndSend(DelayRabbitConfig.ORDER_DELAY_EXCHANGE, DelayRabbitConfig.ORDER_DELAY_ROUTING_KEY, order, message -> {
       // 如果配置了 params.put("x-message-ttl", 5 * 1000); 那么這一句也可以省略,具體根據(jù)業(yè)務(wù)需要是聲明 Queue 的時(shí)候就指定好延遲時(shí)間還是在發(fā)送自己控制時(shí)間
       message.getMessageProperties().setExpiration(1 * 1000 * 60 + "");
       return message;
     });
   }
 
 }

測試,訪問http://localhost:8080/sendDelay查看日志輸出

package com.example.spring_boot_rabbitmq;

import com.example.spring_boot_rabbitmq.pojo.Order;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;


/**
 * @author:zq
 * @date: Greated in 2019/12/19 11:57
 * 測試
 */

@RestController
public class TestController {
  @Autowired
  private DelaySender delaySender;

  @GetMapping("/sendDelay")
  public Object sendDelay() {
    Order order1 = new Order();
    order1.setOrderStatus(0);
    order1.setOrderId("123456");
    order1.setOrderName("小米6");

    Order order2 = new Order();
    order2.setOrderStatus(1);
    order2.setOrderId("456789");
    order2.setOrderName("小米8");

    delaySender.sendDelay(order1);
    delaySender.sendDelay(order2);
    return "ok";
  }

}

輸出

在這里插入圖片描述

到此已經(jīng)SpringBoot使用RabbitMQ延時(shí)隊(duì)列已經(jīng)完成,希望對你有所幫助,若有地方不理解或者有更好的辦法請留言,謝謝。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring實(shí)現(xiàn)文件上傳功能

    Spring實(shí)現(xiàn)文件上傳功能

    本篇文章主要介紹了Spring實(shí)現(xiàn)文件上傳功能,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-01-01
  • Java利用LocalDate進(jìn)行日期處理的完全指南

    Java利用LocalDate進(jìn)行日期處理的完全指南

    這篇文章主要為大家詳細(xì)介紹了Java利用LocalDate進(jìn)行日期處理的詳細(xì)教程,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-03-03
  • Java?中的?switch?語句:類型支持與限制詳解

    Java?中的?switch?語句:類型支持與限制詳解

    Java?中的?switch?語句是一種強(qiáng)大的多分支選擇結(jié)構(gòu),它支持多種數(shù)據(jù)類型,包括基本數(shù)據(jù)類型、字符串和枚舉類型,本文給大家介紹Java?中的?switch?語句:類型支持與限制,感興趣的朋友一起看看吧
    2024-08-08
  • 基于servlet實(shí)現(xiàn)統(tǒng)計(jì)網(wǎng)頁訪問次數(shù)

    基于servlet實(shí)現(xiàn)統(tǒng)計(jì)網(wǎng)頁訪問次數(shù)

    這篇文章主要為大家詳細(xì)介紹了基于servlet實(shí)現(xiàn)統(tǒng)計(jì)網(wǎng)頁訪問次數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Java 多態(tài)中繼承的轉(zhuǎn)型詳解與用法分析

    Java 多態(tài)中繼承的轉(zhuǎn)型詳解與用法分析

    繼承是java面向?qū)ο缶幊碳夹g(shù)的一塊基石,因?yàn)樗试S創(chuàng)建分等級層次的類。繼承就是子類繼承父類的特征和行為,使得子類對象(實(shí)例)具有父類的實(shí)例域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為
    2021-10-10
  • 簡單介紹區(qū)分applet和application的方法

    簡單介紹區(qū)分applet和application的方法

    applet和application都是Java語言編寫出來的應(yīng)用程序,本文簡單介紹了二者的不同之處,需要的朋友可以參考下
    2017-09-09
  • Java StringBuilder的用法示例

    Java StringBuilder的用法示例

    這篇文章主要給大家介紹了關(guān)于Java StringBuilder用法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Javadoc 具體使用詳解

    Javadoc 具體使用詳解

    這篇文章主要介紹了Javadoc 具體使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • SpringBoot中如何進(jìn)行統(tǒng)一異常處理

    SpringBoot中如何進(jìn)行統(tǒng)一異常處理

    大家好,本篇文章主要講的是SpringBoot中如何進(jìn)行統(tǒng)一異常處理,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-02-02
  • 一篇文章帶你了解XGBoost算法

    一篇文章帶你了解XGBoost算法

    XGBoost全名叫(eXtreme Gradient Boosting)極端梯度提升,經(jīng)常被用在一些比賽中,其效果顯著。它是大規(guī)模并行boosted tree的工具,它是目前最快最好的開源boosted tree工具包
    2021-08-08

最新評論