springboot redis使用_使用Redis和SpringBoot执行异步任务

Spring/Spring Boot

Spring是Java应用程序开发中最流行的框架。因此,Spring拥有最大的开源社区之一。除此之外,Spring还提供了大量最新的文档,这些文档涵盖了框架的内部工作和博客中的示例项目--有100 K+的问题StackOverflow.

在早期,Spring只支持基于XML的配置,正因为如此,它受到许多批评。后来,Spring引入了一种基于注释的配置,它改变了一切。Spring3.0是第一个支持基于注释的配置的版本。在2014年,Spring Boot1.0已经发布,完全改变了我们看待Spring框架生态系统的方式。可以找到更详细的时间表。

Redis

Redis是内存中最流行的NoSQL数据库之一。redis支持不同类型的数据结构。redis支持不同类型的数据结构,例如:SET、Hash表、List、简单的键值对等等。Redis调用的延迟时间是亚毫秒,对副本集的支持等等。Redis操作的延迟是亚毫秒,这使得它在整个开发人员社区中更具吸引力。

异步任务执行的原因

一个典型的api调用包括五件事

  1. 执行一个或多个数据库(RDBMS/NoSQL)查询
  2. 在某些缓存系统(内存中、分布式等)上的一个或多个操作
  3. 一些计算(可能是一些数据处理,做一些数学运算)
  4. 调用其他服务(内部/外部)
  5. 将一个或多个任务安排在稍后时间或立即执行,但在背景

由于许多原因,可以在稍后时间安排任务。例如,发票必须在订单创建或装运后7天生成。同样,电子邮件通知不需要立即发送,因此我们可以使它们延迟。

考虑到这些真实的例子,有时我们需要异步执行任务以减少API响应时间。例如,如果我们一次删除1K+记录,如果在同一个API调用中删除所有这些记录,则API响应时间肯定会增加。为了减少API响应时间,我们可以在后台运行一个任务来删除这些记录。

延迟队列

每当我们安排一个任务在给定的时间或某个时间间隔运行时,我们就使用在特定时间或间隔调度的cron作业。我们可以使用UNIX样式的crontab之类的不同工具来运行调度任务,史考斯,如果我们使用Spring框架,那么它是现成的排定注释❤️。

大多数cron作业都能找到必须采取某一特定行动的记录,例如,在七天后找到所有货物,而且没有为这些货物生成发票。这些调度机制中的大多数都会受到影响。标度问题,我们将扫描数据库以查找相关的行/记录。在许多情况下,这会导致全表扫描表现很差。假设一个实时应用程序和这个批处理系统使用相同的数据库。由于它不是可伸缩的,所以我们需要一些可伸缩的系统,它可以在给定的时间或间隔内执行任务,而不会出现任何性能问题。有许多方法可以以这种方式进行扩展,比如以批处理方式运行任务,或者在特定的用户/区域子集上操作任务。另一种方法可以是在给定的时间运行特定的任务,而不依赖于其他任务,比如无服务器功能。一个延迟队列可以在这样的情况下使用,在这种情况下,一旦计时器到达预定时间,就会触发作业。有很多排队系统/软件可用,但很少有系统/软件提供此功能,如SQS它提供了15分钟的延迟,而不是像7小时或7天这样的任意延迟。

RQueue

RQueue是为Spring框架构建的MessageBroker,该框架将数据存储在Redis中,并提供了在任意延迟时执行任务的机制。RQueue是由Redis支持的,因为与广泛使用的队列系统(如Kafka、SQS)相比,Redis具有一些优势。在大多数Web应用程序后端中,Redis用于存储缓存数据或其他用途。在当今世界,8.4% Web应用程序正在使用Redis数据库。

通常,对于队列,我们使用Kafka/SQS或其他一些系统,这些系统在不同的维度带来额外的开销,例如金钱,使用RQueue和Redis可以将这些开销降到零。除了成本之外,如果我们使用Kafka,那么我们需要进行基础设施的设置、维护,即更多的OPS,因为大多数应用程序已经在使用Redis,所以我们不会有OPS开销,实际上,RQueue可以使用相同的Redis服务器/集群。RQueue支持任意延迟

834ec85deb638dc2914c377eef8341e6.png

讯息传递

RQueue保证至少一次消息传递,因为数据库中的数据不会丢失。更多地读到引入RQueue

我们需要的工具:1.任何IDE2.梯度3.Java4.红色

我们要用弹簧靴为了简单。我们将从SpringBoot初始化器创建一个Gradle项目

对于依赖项,我们需要: 1.SpringDataRedis 2.SpringWeb3.Lombok等。目录/文件夹结构如下所示:

c58f9e7a09cf956a2a912cc745e636e9.png

我们要用RQueue库执行任意延迟的任何任务。RQueue是一个基于Spring的异步任务执行器,它可以在任何延迟时执行任务,它建立在Spring消息传递库的基础上,并得到Redis的支持。

我们将使用com.github.sonus21:rqueue-spring-boot-starter:2.0.0-RELEASE

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:2.0.0-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'

}

}

我们需要启用RedisSpringBoot功能。出于测试目的,我们还将启用WebMVC。

将应用程序文件更新为:

@SpringBootApplication

@EnableRedisRepositories

@EnableWebMvc

public class AsynchronousTaskExecutorApplication {

public static void main(String[] args) {

SpringApplication.run(AsynchronousTaskExecutorApplication.class, args);

}

}

使用RQueue添加任务非常简单。我们需要用RqueueListener。这个RqueuListener注释有几个字段可以根据用例设置。集deadLetterQueue将任务推送到另一个队列。否则,任务将在失败时被丢弃。我们还可以使用 numRetries场。

创建一个名为MessageListener并添加一些方法来执行任务:

@Component

@Slf4j

public class MessageListener {

@RqueueListener(value = "${email.queue.name}") (1)

public void sendEmail(Email email) {

log.info("Email {}", email);

}

@RqueueListener(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 豆子。 它有多个方法来根据用例使用可用方法之一对任务进行排队。对于简单的任务,使用队列来处理延迟的任务。

我们需要自动连线RqueueMessageSender或者使用基于构造函数的注入来注入这些bean。

这是如何为测试目的创建控制器。

我们将安排发票的生成,可以在30秒内完成。为此,我们将在发票队列上提交一个延迟30000(毫秒)的任务。另外,我们将尝试发送一封可以在后台执行的电子邮件。为此,我们将添加两个GET方法,sendEmail和 generateInvoice,我们也可以使用POST。

@RestController@RequiredArgsConstructor(onConstructor = @__(@Autowired))@Slf4jpublic 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.enqueu(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.enqueueIn(invoiceQueueName, new Invoice(id, type), invoiceDelay); return "Invoice would be generated in " + invoiceDelay + " milliseconds"; }}

在applicy.properties文件中添加以下内容:

email.queue.name=email-queue

invoice.queue.name=invoice-queue

# 30 seconds delay for invoice

invoice.queue.delay=300000

现在,我们可以运行这个应用程序了。

在日志中,我们可以看到电子邮件任务正在后台执行:

9e83338c09859b38f004cc967d1ec502.png

以下是30秒后的发票时间安排:

dd0875cb62cf99c3667ada814b533d61.png

结语

我们现在可以使用RQueue来调度任务,而不需要太多的代码!在配置和使用RQueue库时,我们考虑了一些重要问题。需要记住的一件重要事情是:在默认情况下,任务是否是延迟的任务,假设任务需要尽快执行。

为感谢您对我们的认可,特意准备了一些IT入门和进阶的干货

包括:Java、UI设计、H5前端、Python+人工智能、软件测试和新媒体运营六大学科视频资料。以及IT就业大礼包。

线上视频、音频,随时学习观看

关注我们并私信“资料”即可获取。

如果你觉得这篇文章有帮助,请与你的朋友和同事分享,不要忘了竖起大拇指!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值