在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何使用Spring Boot 2.x和Redis執行異步任務?

冬至子 ? 來源:ImportNew ? 作者:ImportNew ? 2023-06-06 15:57 ? 次閱讀

Spring/Spring Boot

Spring 是最流行 Java 應用程序開發框架。因此,Spring 社區也是最大的開源社區之一。除此之外,Spring 博客還提供了最新的開發文檔,內容非常豐富。涵蓋了框架的內部工作原理和示例項目,在StackOverflow上有10萬多個問題。

Spring 早期只支持基于XML的配置,為此飽受批評。后來 Spring 引入了基于注解的配置,情況發生了根本改變。Spring 3.0是第一個支持基于注解的配置的版本。2014年發布的 Spring Boot 1.0,徹底改變了人們對 Spring 框架生態的看法。在這里可以找到更詳細的時間表。

Redis

Redis 是最流行的 NoSQL 內存數據庫之一,支持不同類型的數據結構,包括 Set、哈希表、List、簡單鍵值對等。Redis 調用延遲為亞毫秒級,支持 replica set 等功能。Redis 操作的延遲也是亞毫秒級,在開發者社區中更具吸引力。

為什么需要異步執行任務

一個典型的 API 調用包括以下五個方面:

  1. 執行數據庫(RDBMS 或 NoSQL)查詢
  2. 在某些緩存系統(內存、分布式等)上執行操作
  3. 進行計算(對一些數據進行數學計算)
  4. 調用其他(內部或外部)服務
  5. 調度任務稍后執行或者在后臺立即執行。

任務可根據需要定時執行,例如在創建訂單或裝運單后7天后生成發票。同樣,電子郵件通知無需立即發送,因此可以設為延期發送。

考慮到這些實際場景,有時候需要異步執行任務,減少 API 響應時間。例如,如果一次在同一個 API 調用中刪除一千多條記錄,那么肯定會增加 API 響應時間。為了減少 API 響應時間,可以運行一個后臺任務刪除這些記錄。

延遲隊列

當計劃在指定時間或者按照設定間隔執行任務時,可以使用 corn job。有很多不同的工具可以執行定時任務,比如 UNIX 風格的 crontabs、Chronos。如果用 Spring 框架,那么可以用默認提供的 Scheduled 注解。

大多數 cron job 會在需要執行特定操作時查找記錄,例如查找所有已發貨7天但未生成發票的記錄。這些調度機制中大多數都會遇到擴展問題,在數據庫中掃描查找相關行或者記錄。多數情況會引發全表掃描,性能非常差。設想一下正在運行的應用程序與批處理系統使用相同的數據庫。

由于不可擴展,因此需要一些可擴展系統,可以在指定時間或按照設定時間間隔執行任務,不會出現任何性能問題。有許多擴展的方法,例如用批處理方式執行任務,或者在用戶、區域子集上執行任務。另一種方法是在指定時間執行任務,任務之間沒有依賴,例如 serverless 函數。定時器達到預定時間后會立即觸發執行作業,這時可以使用延遲隊列。有很多隊列系統或軟件可供使用,但很少像 SQS 這樣可以設置延遲15分鐘,而不是延遲7個小時或者7天。

Rqueue

Rqueue 是針對 Spring 框架構建的消息代理,它把數據存儲到 Redis 中并且提供了一種機制可以按任意延遲執行任務。Rqueue 得到了 Redis 支持。相比 Kafka、SQS 等常見隊列系統,Redis 具有一些優勢。在大多數 Web 應用后端程序中,Redis 用來緩存數據或者其他用途。在當今世界,8.4%的 Web 應用程序正在使用 Redis 數據庫。

通常,使用 Kafka、SQS 或者其他隊列系統會帶來不同程度的額外開銷,而 Rqueue 和 Redis 可以將費用降為零。

除了使用 Kafka 帶來的開銷,還需配置基礎架構、進行維護等等。由于大多數程序已經使用了 Redis,因此不需要其他操作開銷。實際上,可以在同一個 Redis 服務器或群集上使用 Rqueue。Rqueue支持任意長度延遲

圖片

消息傳遞

由于長數據不會在數據庫中丟失,Rqueue 能夠確保至少發送一次消息。在 Rqueue 簡介中可以了解更多信息。

需要的工具:

  1. IDE
  2. Gradle
  3. Java
  4. Redis

簡單起見,這里使用 Spring Boot。通過Spring Boot初始化程序 創建一個 Gradle 項目。

需要添加以下依賴:

1.Spring Data Redis

2.Spring Web

3.Lombok 等。

目錄/文件夾結構如下所示:

圖片

使用Rqueue開發庫實現按任意延遲時間執行任務。Rqueue 是一個基于 Spring 的異步任務執行器,可以按照任意延遲執行任務,它基于 Spring 消息庫并由 Redis 提供支持。

這里將使用**com.github.sonus21:rqueue-spring-boot-starter:1.2-RELEASE添加 Rqueue spring boot starter **依賴。

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-data-redis'
  implementation 'org.springframework.boot:spring-boot-starter-web'
  implementation 'com.github.sonus21:rqueue-spring-boot-starter:1.2-RELEASE'
  compileOnly 'org.projectlombok:lombok'   
  annotationProcessor 'org.projectlombok:lombok'
  providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
  testImplementation('org.springframework.boot:spring-boot-starter-test') {
    exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'  
  }
}

需要啟用 Redis Spring Boot 功能。出于測試目的,這里還將啟用 WEB MVC。

application 文件更新如下:

@SpringBootApplication
@EnableRedisRepositories
@EnableWebMvc
public class AsynchronousTaskExecutorApplication {
  public static void main(String[] args) {
    SpringApplication.run(AsynchronousTaskExecutorApplication.class, args);
  }
}

使用 Rqueue 添加任務非常簡單,只要對方法添加 RqueueListener 注解。RqueuListener 注解提供了一些字段,可根據使用場景設置。對于延遲任務,需要設置 delayedQueue="true" 并且必須提供 value;否則注解將被忽略。value 是隊列名稱。設置 deadLetterQueue 可以將任務推送到另一個隊列。否則,執行失敗時任務會被丟棄。還可以使用 numRetries 字段設置任務重試次數。

創建名為 MessageListener 的 Java 文件并增加一些方法執行任務:

@Component
@Slf4j
public class MessageListener {
  @RqueueListener(value = "${email.queue.name}") (1)
  public void sendEmail(Email email) {
    log.info("Email {}", email);
  }
  @RqueueListener(delayedQueue = "true", value = "${invoice.queue.name}") (2)
  public void generateInvoice(Invoice invoice) {
    log.info("Invoice {}", invoice);
  }
}

用 Email 和 Invoice 類分別存儲電子郵件和發票數據。簡單起見,這些類只包含少數幾個字段。

Invoice.java:

import lombok.Data;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Invoice {
  private String id;
  private String type;
}

Email.java:

import lombok.Data;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Email {
  private String email;
  private String subject;
  private String content;
}

提交任務

可以使用 RqueueMessageSender bean 提交任務。根據使用場景,可以采用多種方式設置任務,例如,對于重試可以使用方法重試計數,對于延遲任務可以設置延遲。

需要對 RqueueMessageSender 進行 autowire 或使用構造函數注入 bean。

下面展示了如何為測試創建 Controller。

這里會在30秒內生成發票。為此,在發票隊列上提交一個延遲30000(毫秒)的任務。另外,這里會嘗試在后臺發送一封電子郵件。為此添加兩個 GET 方法,sendEmail 和 generateInvoice,當然也可以使用 POST。

@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class Controller {
  private @NonNull RqueueMessageSender rqueueMessageSender;
  @Value("${email.queue.name}")
  private String emailQueueName;
  @Value("${invoice.queue.name}")
  private String invoiceQueueName;
  @Value("${invoice.queue.delay}")
  private Long invoiceDelay;
  @GetMapping("email")
  public String sendEmail(
      @RequestParam String email, @RequestParam String subject, @RequestParam String content) {
    log.info("Sending email");
    rqueueMessageSender.put(emailQueueName, new Email(email, subject, content));
    return "Please check your inbox!";
  }
  @GetMapping("invoice")
  public String generateInvoice(@RequestParam String id, @RequestParam String type) {
    log.info("Generate invoice");
    rqueueMessageSender.put(invoiceQueueName, new Invoice(id, type), invoiceDelay);
    return "Invoice would be generated in " + invoiceDelay + " milliseconds";
  }
}

在 application.properties 加入以下內容:

email.queue.name=email-queue
invoice.queue.name=invoice-queue
# 30 seconds delay for invoice
invoice.queue.delay=300000

現在可以運行該程序。程序成功啟動后,訪問 鏈接。

在日志中,可以看到電子郵件任務正在后臺執行:

圖片

下面是延遲30秒生成發票:

圖片

總結

可以看到,使用 Rqueue 執行定時任務不需要冗長的模板代碼!配置和使用 Rqueue 庫時,進行了仔細考慮。要記住:無論是普通任務還是延遲任務,都需要盡快執行。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • JAVA
    +關注

    關注

    20

    文章

    2983

    瀏覽量

    106467
  • XML技術
    +關注

    關注

    0

    文章

    15

    瀏覽量

    6093
  • RDBMS
    +關注

    關注

    0

    文章

    9

    瀏覽量

    5913
  • nosql
    +關注

    關注

    0

    文章

    39

    瀏覽量

    10163
  • Redis
    +關注

    關注

    0

    文章

    381

    瀏覽量

    11229
收藏 人收藏

    評論

    相關推薦

    Spring Boot如何實現異步任務

    Spring Boot 提供了多種方式來實現異步任務,這里介紹三種主要實現方式。 1、基于注解 @Async @Async 注解是 Spring
    的頭像 發表于 09-30 10:32 ?1596次閱讀

    Spring Boot Starter需要些什么

    pulsar-spring-boot-starter是非常有必要的,在此之前,我們先看看一個starter需要些什么。 Spring Boot Starter spring-boot
    的頭像 發表于 09-25 11:35 ?938次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b> Starter需要些什么

    基于maven的spring-data-redis整合

    springredis的整合
    發表于 04-12 14:03

    redis緩存注解怎么使用

    spring boot —— redis 緩存注解使用教程
    發表于 09-11 14:43

    Spring bootRedis的使用

    【本人禿頂程序員】springboot專輯:Spring bootRedis的使用
    發表于 03-27 11:42

    Spring Boot定時任務的重寫方法

    Spring Boot應該是目前最火的java開源框架了,它簡化了我們創建一個web服務的過程,讓我們可以在很短時間、基本零配置就可以啟動一個web服務。
    的頭像 發表于 01-20 17:38 ?2571次閱讀

    Spring認證」什么是Spring GraphQL?

    這個項目建立在 Boot 2.x 上,但它應該與最新的 Boot2.4.x5 相關。 要創建項目,請轉到start.spring.io并為要使用的GraphQL傳輸選擇啟動器: 啟動機
    的頭像 發表于 08-10 14:08 ?936次閱讀
    「<b class='flag-5'>Spring</b>認證」什么是<b class='flag-5'>Spring</b> GraphQL?

    如何實現一個秒殺系統

    實現一個秒殺系統,采用spring boot 2.x + mybatis+ redis + swagger2 + lombok實現。
    的頭像 發表于 09-15 09:56 ?2351次閱讀

    強大的Spring Boot 3.0要來了

    和 Bugfix。 Spring Boot 3.0 的開發工作始于實驗性的 Spring Native,旨在為 GraalVM 原生鏡像提供支持。 在該版本中,開發者現在可以使用標準 Spri
    的頭像 發表于 10-31 11:17 ?2146次閱讀

    Spring Boot中整合兩種定時任務的方法

    框架 Quartz ,Spring Boot 源自 Spring+SpringMVC ,因此天然具備這兩個 Spring 中的定時任務實現策
    的頭像 發表于 04-07 14:55 ?1716次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b>中整合兩種定時<b class='flag-5'>任務</b>的方法

    Spring Boot中如何使用定時任務

    本文介紹在 Spring Boot 中如何使用定時任務,使用非常簡單,就不做過多說明了。
    的頭像 發表于 04-12 10:56 ?1107次閱讀

    Spring Boot Actuator快速入門

    一下 Spring Boot Actuator ,學習如何在 Spring Boot 2.x 中使用、配置和擴展這個監控工具。
    的頭像 發表于 10-09 17:11 ?768次閱讀

    Spring Boot啟動 Eureka流程

    在上篇中已經說過了 Eureka-Server 本質上是一個 web 應用的項目,今天就來看看 Spring Boot 是怎么啟動 Eureka 的。 Spring Boot 啟動 E
    的頭像 發表于 10-10 11:40 ?1061次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b>啟動 Eureka流程

    Spring Boot的啟動原理

    可能很多初學者會比較困惑,Spring Boot 是如何做到將應用代碼和所有的依賴打包成一個獨立的 Jar 包,因為傳統的 Java 項目打包成 Jar 包之后,需要通過 -classpath 屬性
    的頭像 發表于 10-13 11:44 ?809次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b>的啟動原理

    Spring Boot 的設計目標

    什么是Spring Boot Spring BootSpring 開源組織下的一個子項目,也是 S
    的頭像 發表于 10-13 14:56 ?700次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b> 的設計目標
    主站蜘蛛池模板: 乱色伦肉小说 | 亚洲大成色www永久网 | 久久亚洲国产成人影院 | 国产黄色在线视频 | 色多多高清在线观看视频www | 正在播放久久 | 五月婷婷之婷婷 | 久久艹综合 | 久热首页 | 91大神免费视频 | 1024你懂的国产在线播放 | 黄色三级国产 | 特黄特色大片免费视频大全 | 欧美性受xxxx极品 | 黄色大秀视频 | 国产天堂网 | 特级淫片aaaaa片毛片 | 免费91视频 | 日本黄色片视频 | 亚洲一二三区视频 | 黄色福利小视频 | 免费观看黄a一级视频 | 国产精品天天看大片特色视频 | 午夜剧| 中韩日欧美电影免费看 | 在线视频一区二区三区四区 | 亚洲综合春色另类久久 | 天天做人人爱夜夜爽2020 | 久久这里只有精品免费播放 | 8050网午夜一级毛片免费不卡 | 电源天堂| 羞羞答答91麻豆网站入口 | aaaa黄色片 | 欧美激情一欧美吧 | 天天爽夜夜爽视频 | 高h上错人1v1 | 萌白酱香蕉白丝护士服喷浆 | 久久男人的天堂色偷偷 | 一区二区三区四区视频在线 | asian极品呦女爱爱 | 日本卡一卡2卡3卡4精品卡无人区 |