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

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

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

springboot中RabbitMQ基本使用

RabbitMQ是一個開源的消息中間件

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

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

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

在SpringbBoot在使用首先需要在rabbitmq管理界面新建隊列和交換機。

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

以下是幾種常見的交換機類型:

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

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

在項目中引入依賴

<!-- 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

交換機與隊列綁定配置

@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);
    }
    // 綁定交換機和隊列
    @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)用場景

短信驗證碼服務(wù),這里我使用的是阿里云短信服務(wù)SMS,將短信驗證碼與前端輸入的手機號存入隊列中,將驗證碼存入redis中,方便后續(xù)注冊時驗證碼驗證,最后監(jiān)聽隊列拿到信息后發(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é)點,默認(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);  //手機號
        request.putQueryParameter("SignName", "阿里云短信測試");    //申請阿里云 簽名名稱(暫時用阿里云測試的,自己還不能注冊簽名)
        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);
}

實現(xiàn):

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

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

//      3. 生成驗證碼
        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.保存驗證碼到 redis
        redisCache.setCacheObject(phone,code);

        Map<String,String> map=new HashMap();
        map.put("phone", phone);
        map.put("code", code);
        // 5.保存驗證碼和手機號到隊列
        rabbitTemplate.convertAndSend("market.exChanges","market",map);

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

監(jiān)聽隊列并發(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"));

        // 手動發(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é)

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

相關(guān)文章

  • Java畫筆的簡單實用方法

    Java畫筆的簡單實用方法

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新評論

离岛区| 商丘市| 贵溪市| 河津市| 南溪县| 广西| 桐城市| 潮安县| 中牟县| 武威市| 普陀区| 饶阳县| 游戏| 泸定县| 修武县| 沁阳市| 洪泽县| 佳木斯市| 汉寿县| 罗源县| 满洲里市| 闵行区| 泾川县| 平阴县| 营口市| 罗甸县| 衡东县| 新河县| 靖远县| 罗山县| 海淀区| 汨罗市| 武定县| 巴南区| 邢台县| 来宾市| 溧水县| 广州市| 荔波县| 且末县| 太湖县|