最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

RabbitMQ在springboot中實(shí)現(xiàn)短信服務(wù)的異步通信方式

 更新時(shí)間:2026年05月19日 16:46:09   作者:胡思亂想罷了~  
RabbitMQ是一個(gè)開源消息中間件,適用于異步通信、應(yīng)用解耦、可靠消息傳遞、靈活路由、延遲消息處理和分布式系統(tǒng)調(diào)等場景,SpringBoot使用需要新建隊(duì)列、交換機(jī)并配置綁定,文章通過短信驗(yàn)證碼服務(wù)為例,演示了RabbitMQ在項(xiàng)目中的應(yīng)用場景和配置方法

springboot中RabbitMQ基本使用

RabbitMQ是一個(gè)開源的消息中間件

具有以下用途和優(yōu)點(diǎn):

  • 異步通信:RabbitMQ可以作為應(yīng)用程序之間進(jìn)行異步通信的媒介,生產(chǎn)者可以將消息發(fā)送到RabbitMQ,而消費(fèi)者可以從中獲取消息并進(jìn)行處理。這種異步通信可以實(shí)現(xiàn)系統(tǒng)各部分的解耦,提高系統(tǒng)的可伸縮性和性能。
  • 應(yīng)用解耦:通過使用RabbitMQ,不同的應(yīng)用程序可以通過發(fā)送和接收消息來解耦,并減少應(yīng)用之間的依賴。這樣可以提高系統(tǒng)的靈活性,使系統(tǒng)更易于維護(hù)和擴(kuò)展。
  • 可靠消息傳遞:RabbitMQ確保消息傳遞的可靠性。它提供持久化和消息確認(rèn)機(jī)制,即使在消息發(fā)送或消費(fèi)者出現(xiàn)故障的情況下,也能保證消息的不丟失和不重復(fù)。
  • 靈活的消息路由和交換:RabbitMQ支持多種消息路由模式和交換機(jī)類型,如直連、扇形、主題和頭部交換機(jī)。這使得可以根據(jù)消息的內(nèi)容和標(biāo)簽將消息路由到不同的隊(duì)列中,滿足各種復(fù)雜的應(yīng)用場景。
  • 延遲消息處理:RabbitMQ支持延遲消息的發(fā)送和處理,可以用于處理定時(shí)任務(wù)、延遲通知和調(diào)度等需求。
  • 分布式系統(tǒng)中的協(xié)調(diào):RabbitMQ在分布式系統(tǒng)中扮演著關(guān)鍵的角色,可以用于實(shí)現(xiàn)分布式系統(tǒng)的任務(wù)分發(fā)、事件發(fā)布訂閱、分布式鎖等。它提供了一種簡單而強(qiáng)大的方式來處理分布式系統(tǒng)間的通信和協(xié)調(diào)機(jī)制。

RabbitMQ是一個(gè)功能強(qiáng)大、可靠性高且易于使用的消息中間件。它在異步通信、應(yīng)用解耦、可靠消息傳遞、靈活的消息路由和交換、延遲消息處理以及分布式系統(tǒng)中的協(xié)調(diào)等方面具有廣泛應(yīng)用。

在SpringbBoot在使用首先需要在rabbitmq管理界面新建隊(duì)列和交換機(jī)。

RabbitMQ支持多種類型的交換機(jī),用于定義消息的路由規(guī)則。

以下是幾種常見的交換機(jī)類型:

  • 直連交換機(jī)(Direct Exchange):根據(jù)消息的路由鍵(Routing Key)精確地將消息路由到匹配的隊(duì)列。例如,通過將消息的路由鍵設(shè)置為特定的關(guān)鍵詞,可以將消息發(fā)送到對應(yīng)的隊(duì)列,以便消費(fèi)者進(jìn)行處理。
  • 扇形交換機(jī)(Fanout Exchange):將消息廣播到所有與交換機(jī)綁定的隊(duì)列。無論消息的路由鍵是什么,扇形交換機(jī)都會(huì)將消息發(fā)送到所有綁定的隊(duì)列中。適用于多個(gè)消費(fèi)者需要處理相同消息的場景。
  • 主題交換機(jī)(Topic Exchange):根據(jù)路由鍵的模式進(jìn)行匹配和路由??梢允褂猛ㄅ浞?hào)“*”匹配一個(gè)單詞,使用“#”匹配零個(gè)或多個(gè)單詞。主題交換機(jī)可以滿足更復(fù)雜的路由需求,可以將消息路由到多個(gè)隊(duì)列。
  • 頭部交換機(jī)(Headers Exchange):根據(jù)消息的頭部屬性進(jìn)行匹配和路由。消息發(fā)布者在發(fā)送消息時(shí)可以在消息的頭部添加自定義的屬性,交換機(jī)將根據(jù)這些屬性進(jìn)行匹配和路由。

不同類型的交換機(jī)適用于不同的應(yīng)用場景,開發(fā)者可以根據(jù)具體需求選擇適合的交換機(jī)類型來進(jìn)行消息路由和分發(fā)。

在項(xiàng)目中引入依賴

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

yml文件配置

rabbitmq的用戶名和密碼都為默認(rèn)

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/market?useSSl=true&useUnicode=true$characterEncoding=utf-8&serverTimezone=GMT%2B8
    username: root
    password: 010409
  rabbitmq:
      host: 127.0.0.1
      port: 5672
      username: guest
      password: guest

交換機(jī)與隊(duì)列綁定配置

@Configuration
public class RabbitMQConfig {
    private static final String MARKET = "market";
    private static final String ORDER = "order";
    private static final String EXCHANGE = "market.exChanges";
    @Bean
    public Queue queue01(){
        return new Queue(MARKET);
    }
    @Bean
    public Queue queue02(){
        return new Queue(ORDER);
    }
    @Bean
    public DirectExchange fanoutExchange(){
        return new DirectExchange(EXCHANGE);
    }
    // 綁定交換機(jī)和隊(duì)列
    @Bean
    public Binding binding01(){
        return BindingBuilder.bind(queue01()).to(fanoutExchange()).with("market");
    }
    @Bean
    public Binding binding02(){
        return BindingBuilder.bind(queue02()).to(fanoutExchange()).with("order");
    }
}

應(yīng)用場景

短信驗(yàn)證碼服務(wù),這里我使用的是阿里云短信服務(wù)SMS,將短信驗(yàn)證碼與前端輸入的手機(jī)號(hào)存入隊(duì)列中,將驗(yàn)證碼存入redis中,方便后續(xù)注冊時(shí)驗(yàn)證碼驗(yàn)證,最后監(jiān)聽隊(duì)列拿到信息后發(fā)送短信。

SMS依賴與配置,需要將配置修改為自己的

<!--  阿里云短信依賴  -->
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>4.5.16</version>
</dependency>
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
    <version>2.1.0</version>
</dependency>
@Service
public class SmsService {
    public boolean send(Map<String, Object> param, String phone) {

        if(StringUtils.isEmpty(phone)) return false;
        //default 地域節(jié)點(diǎn),默認(rèn)就好  后面是 阿里云的 id和秘鑰(這里記得去阿里云復(fù)制自己的id和秘鑰哦)
        DefaultProfile profile = DefaultProfile.getProfile("default",  "LTAI5tNtEzgs7etoRVhWQuXz", "X8odaVou1eSwT0boKEgvYxPSUtWafL");
        IAcsClient client = new DefaultAcsClient(profile);

        CommonRequest request = new CommonRequest();

        request.setProtocol(ProtocolType.HTTPS);
        request.setMethod(MethodType.POST);
        request.setDomain("dysmsapi.aliyuncs.com");
        request.setVersion("2017-05-25");
        request.setAction("SendSms");

        request.putQueryParameter("PhoneNumbers", phone);  //手機(jī)號(hào)
        request.putQueryParameter("SignName", "阿里云短信測試");    //申請阿里云 簽名名稱(暫時(shí)用阿里云測試的,自己還不能注冊簽名)
        request.putQueryParameter("TemplateCode",  "SMS_154950909"); //申請阿里云 模板code(用的也是阿里云測試的)
        request.putQueryParameter("TemplateParam", JSONObject.toJSONString(param));

        try {
            CommonResponse response = client.getCommonResponse(request);
//            System.out.println(response.getData());
            return response.getHttpResponse().isSuccess();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}

發(fā)送短信的接口:

@RequestMapping("/sendCode")
public Result sendCode(String phone){
    return UserService.sendCode(phone);
}

實(shí)現(xiàn):

   @Override
    public Result sendCode(String phone) {
        // 1.校驗(yàn)手機(jī)號(hào)
        String regex = "^1[3456789]\\d{9}$";

        if (!phone.matches(regex)) {
            // 2.如果不符合,返回錯(cuò)誤信息
            return new Result(100,"手機(jī)號(hào)格式錯(cuò)誤!");
        }

//      3. 生成驗(yàn)證碼
        String code = "";
        for (int i = 0; i < 6; i++) {
            int var = new Random().nextInt(10);
            code = code + var;
        }

        Map<String,Object> param = new HashMap<>();
        param.put("code", code);

        // 4.保存驗(yàn)證碼到 redis
        redisCache.setCacheObject(phone,code);

        Map<String,String> map=new HashMap();
        map.put("phone", phone);
        map.put("code", code);
        // 5.保存驗(yàn)證碼和手機(jī)號(hào)到隊(duì)列
        rabbitTemplate.convertAndSend("market.exChanges","market",map);

        return new Result(200, "發(fā)送成功");
    }

監(jiān)聽隊(duì)列并發(fā)送短信。

@RabbitListener(queues = "market")
@RabbitHandler
public void executeSPC(Map<String, String> map, Channel channel, @Headers Map<String, Object> headers) throws IOException {
    try {
        Map<String,Object> param = new HashMap<>();
        param.put("code", map.get("code"));
        smsService.send(param, map.get("phone"));

        // 手動(dòng)發(fā)送ACK,確認(rèn)消息已接收
        Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        channel.basicAck(deliveryTag, false);
    } catch (Exception e) {
        // 處理異常情況,根據(jù)業(yè)務(wù)需要選擇是否重新入列或者拒絕消息等操作
        Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        channel.basicNack(deliveryTag, false, true);
    }
}

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java畫筆的簡單實(shí)用方法

    Java畫筆的簡單實(shí)用方法

    這篇文章主要介紹了Java畫筆的簡單實(shí)用方法,需要的朋友可以參考下
    2017-09-09
  • java導(dǎo)出Excel實(shí)現(xiàn)八倍效率優(yōu)化的方法詳解

    java導(dǎo)出Excel實(shí)現(xiàn)八倍效率優(yōu)化的方法詳解

    這篇文章主要為大家詳細(xì)介紹了java導(dǎo)出Excel實(shí)現(xiàn)八倍效率優(yōu)化的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-11-11
  • 如何使用Idea中的 Deployment 實(shí)現(xiàn)打包自動(dòng)部署

    如何使用Idea中的 Deployment 實(shí)現(xiàn)打包自動(dòng)部署

    這篇文章主要介紹了使用Idea中的 Deployment 實(shí)現(xiàn)打包自動(dòng)部署,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • SpringBoot實(shí)現(xiàn)Thymeleaf驗(yàn)證碼生成

    SpringBoot實(shí)現(xiàn)Thymeleaf驗(yàn)證碼生成

    本文使用SpringBoot實(shí)現(xiàn)Thymeleaf驗(yàn)證碼生成,使用后臺(tái)返回驗(yàn)證碼圖片,驗(yàn)證碼存到session中后端實(shí)現(xiàn)校驗(yàn),前端只展示驗(yàn)證碼圖片。感興趣的可以了解下
    2021-05-05
  • Java編程實(shí)現(xiàn)獲取當(dāng)前代碼行行號(hào)的方法示例

    Java編程實(shí)現(xiàn)獲取當(dāng)前代碼行行號(hào)的方法示例

    這篇文章主要介紹了Java編程實(shí)現(xiàn)獲取當(dāng)前代碼行行號(hào)的方法,結(jié)合實(shí)例形式分析了java基于StackTraceElement對象實(shí)現(xiàn)獲取代碼行號(hào)的相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • Java如何使用interrupt()終止線程

    Java如何使用interrupt()終止線程

    這篇文章主要介紹了Java如何使用interrupt()終止線程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java實(shí)現(xiàn)冒泡排序示例介紹

    Java實(shí)現(xiàn)冒泡排序示例介紹

    冒泡排序是一種簡單的排序算法,通過不斷比較相鄰兩個(gè)元素的大小,將較大的元素向后移動(dòng),最終將最大的元素放到了數(shù)組的末尾。Java中的實(shí)現(xiàn)方式是通過嵌套兩層循環(huán),外層循環(huán)控制比較的次數(shù),內(nèi)層循環(huán)控制每次比較時(shí)相鄰元素的比較和交換
    2023-04-04
  • 一文帶你真正理解Java中的內(nèi)部類

    一文帶你真正理解Java中的內(nèi)部類

    不知道大家在平時(shí)的開發(fā)過程中或者源碼里是否留意過內(nèi)部類,那有思考過為什么要有內(nèi)部類,內(nèi)部類都有哪幾種形式,本篇文章主要帶領(lǐng)大家理解下這塊內(nèi)容
    2022-08-08
  • 使用SpringBoot簡單實(shí)現(xiàn)無感知的刷新 Token功能

    使用SpringBoot簡單實(shí)現(xiàn)無感知的刷新 Token功能

    實(shí)現(xiàn)無感知的刷新 Token 是一種提升用戶體驗(yàn)的常用技術(shù),可以在用戶使用應(yīng)用時(shí)自動(dòng)更新 Token,無需用戶手動(dòng)干預(yù),這種技術(shù)在需要長時(shí)間保持用戶登錄狀態(tài)的應(yīng)用中非常有用,以下是使用Spring Boot實(shí)現(xiàn)無感知刷新Token的一個(gè)場景案例和相應(yīng)的示例代碼
    2024-09-09
  • 當(dāng)mybatis返回值遇見內(nèi)部類的問題

    當(dāng)mybatis返回值遇見內(nèi)部類的問題

    這篇文章主要介紹了當(dāng)mybatis返回值遇見內(nèi)部類的問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12

最新評(píng)論

鹿邑县| 龙南县| 仪征市| 涡阳县| 漯河市| 海晏县| 收藏| 冕宁县| 房产| 宜兴市| 资兴市| 榆中县| 清原| 日土县| 壶关县| 栖霞市| 措美县| 仁布县| 营山县| 南雄市| 永安市| 上饶县| 同江市| 明光市| 灌云县| 甘孜县| 嘉兴市| 潞城市| 泸州市| 普兰店市| 深水埗区| 苍山县| 海安县| 张家界市| 塔河县| 重庆市| 南陵县| 和静县| 崇明县| 新兴县| 龙陵县|