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

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何使用Spring Boot 2.x和Redis執(zhí)行異步任務(wù)?

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

Spring/Spring Boot

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

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

Redis

Redis 是最流行的 NoSQL 內(nèi)存數(shù)據(jù)庫之一,支持不同類型的數(shù)據(jù)結(jié)構(gòu),包括 Set、哈希表、List、簡單鍵值對等。Redis 調(diào)用延遲為亞毫秒級,支持 replica set 等功能。Redis 操作的延遲也是亞毫秒級,在開發(fā)者社區(qū)中更具吸引力。

為什么需要異步執(zhí)行任務(wù)

一個(gè)典型的 API 調(diào)用包括以下五個(gè)方面:

  1. 執(zhí)行數(shù)據(jù)庫(RDBMS 或 NoSQL)查詢
  2. 在某些緩存系統(tǒng)(內(nèi)存、分布式等)上執(zhí)行操作
  3. 進(jìn)行計(jì)算(對一些數(shù)據(jù)進(jìn)行數(shù)學(xué)計(jì)算)
  4. 調(diào)用其他(內(nèi)部或外部)服務(wù)
  5. 調(diào)度任務(wù)稍后執(zhí)行或者在后臺立即執(zhí)行。

任務(wù)可根據(jù)需要定時(shí)執(zhí)行,例如在創(chuàng)建訂單或裝運(yùn)單后7天后生成發(fā)票。同樣,電子郵件通知無需立即發(fā)送,因此可以設(shè)為延期發(fā)送。

考慮到這些實(shí)際場景,有時(shí)候需要異步執(zhí)行任務(wù),減少 API 響應(yīng)時(shí)間。例如,如果一次在同一個(gè) API 調(diào)用中刪除一千多條記錄,那么肯定會增加 API 響應(yīng)時(shí)間。為了減少 API 響應(yīng)時(shí)間,可以運(yùn)行一個(gè)后臺任務(wù)刪除這些記錄。

延遲隊(duì)列

當(dāng)計(jì)劃在指定時(shí)間或者按照設(shè)定間隔執(zhí)行任務(wù)時(shí),可以使用 corn job。有很多不同的工具可以執(zhí)行定時(shí)任務(wù),比如 UNIX 風(fēng)格的 crontabs、Chronos。如果用 Spring 框架,那么可以用默認(rèn)提供的 Scheduled 注解。

大多數(shù) cron job 會在需要執(zhí)行特定操作時(shí)查找記錄,例如查找所有已發(fā)貨7天但未生成發(fā)票的記錄。這些調(diào)度機(jī)制中大多數(shù)都會遇到擴(kuò)展問題,在數(shù)據(jù)庫中掃描查找相關(guān)行或者記錄。多數(shù)情況會引發(fā)全表掃描,性能非常差。設(shè)想一下正在運(yùn)行的應(yīng)用程序與批處理系統(tǒng)使用相同的數(shù)據(jù)庫。

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

Rqueue

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

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

除了使用 Kafka 帶來的開銷,還需配置基礎(chǔ)架構(gòu)、進(jìn)行維護(hù)等等。由于大多數(shù)程序已經(jīng)使用了 Redis,因此不需要其他操作開銷。實(shí)際上,可以在同一個(gè) Redis 服務(wù)器或群集上使用 Rqueue。Rqueue支持任意長度延遲

圖片

消息傳遞

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

需要的工具:

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

簡單起見,這里使用 Spring Boot。通過Spring Boot初始化程序 創(chuàng)建一個(gè) Gradle 項(xiàng)目。

需要添加以下依賴:

1.Spring Data Redis

2.Spring Web

3.Lombok 等。

目錄/文件夾結(jié)構(gòu)如下所示:

圖片

使用Rqueue開發(fā)庫實(shí)現(xiàn)按任意延遲時(shí)間執(zhí)行任務(wù)。Rqueue 是一個(gè)基于 Spring 的異步任務(wù)執(zhí)行器,可以按照任意延遲執(zhí)行任務(wù),它基于 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 添加任務(wù)非常簡單,只要對方法添加 RqueueListener 注解。RqueuListener 注解提供了一些字段,可根據(jù)使用場景設(shè)置。對于延遲任務(wù),需要設(shè)置 delayedQueue="true" 并且必須提供 value;否則注解將被忽略。value 是隊(duì)列名稱。設(shè)置 deadLetterQueue 可以將任務(wù)推送到另一個(gè)隊(duì)列。否則,執(zhí)行失敗時(shí)任務(wù)會被丟棄。還可以使用 numRetries 字段設(shè)置任務(wù)重試次數(shù)。

創(chuàng)建名為 MessageListener 的 Java 文件并增加一些方法執(zhí)行任務(wù):

@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 類分別存儲電子郵件和發(fā)票數(shù)據(jù)。簡單起見,這些類只包含少數(shù)幾個(gè)字段。

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;
}

提交任務(wù)

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

需要對 RqueueMessageSender 進(jìn)行 autowire 或使用構(gòu)造函數(shù)注入 bean。

下面展示了如何為測試創(chuàng)建 Controller。

這里會在30秒內(nèi)生成發(fā)票。為此,在發(fā)票隊(duì)列上提交一個(gè)延遲30000(毫秒)的任務(wù)。另外,這里會嘗試在后臺發(fā)送一封電子郵件。為此添加兩個(gè) GET 方法,sendEmail 和 generateInvoice,當(dāng)然也可以使用 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 加入以下內(nèi)容:

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

現(xiàn)在可以運(yùn)行該程序。程序成功啟動后,訪問 鏈接。

在日志中,可以看到電子郵件任務(wù)正在后臺執(zhí)行:

圖片

下面是延遲30秒生成發(fā)票:

圖片

總結(jié)

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

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    2986

    瀏覽量

    107079
  • XML技術(shù)
    +關(guān)注

    關(guān)注

    0

    文章

    15

    瀏覽量

    6106
  • RDBMS
    +關(guān)注

    關(guān)注

    0

    文章

    9

    瀏覽量

    5937
  • nosql
    +關(guān)注

    關(guān)注

    0

    文章

    39

    瀏覽量

    10277
  • Redis
    +關(guān)注

    關(guān)注

    0

    文章

    385

    瀏覽量

    11338
收藏 人收藏

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    Spring Boot如何實(shí)現(xiàn)異步任務(wù)

    Spring Boot 提供了多種方式來實(shí)現(xiàn)異步任務(wù),這里介紹三種主要實(shí)現(xiàn)方式。 1、基于注解 @Async @Async 注解是 Spring
    的頭像 發(fā)表于 09-30 10:32 ?1683次閱讀

    Spring Boot Starter需要些什么

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

    基于maven的spring-data-redis整合

    springredis的整合
    發(fā)表于 04-12 14:03

    redis緩存注解怎么使用

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

    Spring bootRedis的使用

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

    Spring Boot定時(shí)任務(wù)的重寫方法

    Spring Boot應(yīng)該是目前最火的java開源框架了,它簡化了我們創(chuàng)建一個(gè)web服務(wù)的過程,讓我們可以在很短時(shí)間、基本零配置就可以啟動一個(gè)web服務(wù)。
    的頭像 發(fā)表于 01-20 17:38 ?2676次閱讀

    Spring認(rèn)證」什么是Spring GraphQL?

    這個(gè)項(xiàng)目建立在 Boot 2.x 上,但它應(yīng)該與最新的 Boot2.4.x5 相關(guān)。 要創(chuàng)建項(xiàng)目,請轉(zhuǎn)到start.spring.io并為要使用的GraphQL傳輸選擇啟動器: 啟動機(jī)
    的頭像 發(fā)表于 08-10 14:08 ?996次閱讀
    「<b class='flag-5'>Spring</b>認(rèn)證」什么是<b class='flag-5'>Spring</b> GraphQL?

    如何實(shí)現(xiàn)一個(gè)秒殺系統(tǒng)

    實(shí)現(xiàn)一個(gè)秒殺系統(tǒng),采用spring boot 2.x + mybatis+ redis + swagger2 + lombok實(shí)現(xiàn)。
    的頭像 發(fā)表于 09-15 09:56 ?2434次閱讀

    強(qiáng)大的Spring Boot 3.0要來了

    和 Bugfix。 Spring Boot 3.0 的開發(fā)工作始于實(shí)驗(yàn)性的 Spring Native,旨在為 GraalVM 原生鏡像提供支持。 在該版本中,開發(fā)者現(xiàn)在可以使用標(biāo)準(zhǔn) Spri
    的頭像 發(fā)表于 10-31 11:17 ?2265次閱讀

    Spring Boot中整合兩種定時(shí)任務(wù)的方法

    框架 Quartz ,Spring Boot 源自 Spring+SpringMVC ,因此天然具備這兩個(gè) Spring 中的定時(shí)任務(wù)實(shí)現(xiàn)策
    的頭像 發(fā)表于 04-07 14:55 ?1791次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b>中整合兩種定時(shí)<b class='flag-5'>任務(wù)</b>的方法

    Spring Boot中如何使用定時(shí)任務(wù)

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

    Spring Boot Actuator快速入門

    一下 Spring Boot Actuator ,學(xué)習(xí)如何在 Spring Boot 2.x 中使用、配置和擴(kuò)展這個(gè)監(jiān)控工具。
    的頭像 發(fā)表于 10-09 17:11 ?842次閱讀

    Spring Boot啟動 Eureka流程

    在上篇中已經(jīng)說過了 Eureka-Server 本質(zhì)上是一個(gè) web 應(yīng)用的項(xiàng)目,今天就來看看 Spring Boot 是怎么啟動 Eureka 的。 Spring Boot 啟動 E
    的頭像 發(fā)表于 10-10 11:40 ?1146次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b>啟動 Eureka流程

    Spring Boot的啟動原理

    可能很多初學(xué)者會比較困惑,Spring Boot 是如何做到將應(yīng)用代碼和所有的依賴打包成一個(gè)獨(dú)立的 Jar 包,因?yàn)閭鹘y(tǒng)的 Java 項(xiàng)目打包成 Jar 包之后,需要通過 -classpath 屬性
    的頭像 發(fā)表于 10-13 11:44 ?911次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b>的啟動原理

    Spring Boot 的設(shè)計(jì)目標(biāo)

    什么是Spring Boot Spring BootSpring 開源組織下的一個(gè)子項(xiàng)目,也是 S
    的頭像 發(fā)表于 10-13 14:56 ?773次閱讀
    <b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b> 的設(shè)計(jì)目標(biāo)
    主站蜘蛛池模板: 中国一级特黄视频 | 国产一级特黄毛片 | 中文字幕视频二区 | 欧美一级特黄aa大片 | 国产真实乱xxxav | 亚欧免费视频一区二区三区 | 亚洲一本 | 久久香蕉国产线看观看精品yw | 欧美夜夜操 | 99热都是精品 | 天天天天做夜夜夜夜做 | 天天成人 | 来吧成人综合网 | 97久久综合区小说区图片专区 | 天堂在线免费视频 | 国产一级特黄在线播放 | 天天搞天天爽 | 色婷婷丁香六月 | 五月婷亚洲 | 成人性色生活影片 | 天堂成人精品视频在线观 | 手机在线观看国产精选免费 | 日本三浦理惠子中文字幕 | 福利色播 | 手机看片日韩高清1024 | 国产精品三级在线观看 | 欧美一卡二卡科技有限公司 | 中文天堂最新版资源新版天堂资源 | 91福利视频网站 | 国产性做久久久久久 | 天天操天天干天天爽 | 天堂资源在线最新版 | 69er小视频 | 天天看天天摸色天天综合网 | 日日插天天操 | 亚洲日本在线观看 | 国产精品三区四区 | 综合亚洲一区二区三区 | 国产精品欧美一区二区三区 | 午夜啪啪福利视频 | 午夜影院日韩 |