网站开发设计教程,500人企业的网络搭建,网站建设相关的网站,做网站导航多大字号任务调度框架
Java中如何实现定时任务#xff1f;
比如#xff1a; 1.每天早上6点定时执行 2.每月最后一个工作日#xff0c;考勤统计 3.每个月25号信用卡还款 4.会员生日祝福 5.每隔3秒#xff0c;自动提醒
10分钟的超时订单的自动取消#xff0c;每隔30秒或1分钟查询…任务调度框架
Java中如何实现定时任务
比如 1.每天早上6点定时执行 2.每月最后一个工作日考勤统计 3.每个月25号信用卡还款 4.会员生日祝福 5.每隔3秒自动提醒
10分钟的超时订单的自动取消每隔30秒或1分钟查询一次订单拿当前的时间上前推10分钟 定时任务资源会有误差的存在如果使用定时任务 定时任务用于统计的时候最多。
自动统计考勤一般0点之后开始统计可以使用定时任务
nacos心跳
晚上要求和采购部门生成采购单达到最低预警值的时候去发给采购部门
我们可以通过任务调度框架实现上述的需求 任务调度框架可以实现定时任务实现间隔多少时间的重复执行实现指定日期的重复执行
电商自动好评间隔时间长的误差几分钟影响不大。
java中任务调度框架 1、Spring Task spring自带的 2、Quartz 古老的框架 3、XXL-Job 4、第三方云平台-比如说阿里云-SchedulerX等等 选择一个:Spring Task 2个注解 包task任务、job
使用步骤 1、开关类使用注解 EnableScheduling // 开启任务调度 2、定义定时任务
Scheduled(cron 0/3 * * * ?)
CORN表达式 秒 分 时 日 月 星期几 年 其中只有年可以省略 定时任务需要重复执行的方法
CORN表达式 特殊字符串主要用来描述时间的用于任务调度等 https://cron.qqe2.com/
/ 间隔
- 是连续
, 枚举值
L 最后星期、日中用
W 有效工作日
LW 某个月最后一个工作日
# 用于确定每个月第几个星期几母亲节或父亲节
4#2 某个月的第二个星期三 4代表星期三中文的时候有可能不影响项目名SpringTask01 Spring Web、Lombok
RabbitMq实现延迟
死信延迟消息处理
死信RabbitMQ的队列中的消息满足以下条件任意其一就会成为死信消息 1.消息被拒绝 2.消息过期 3.队列满了 死信交换器:专门用来转发队列中的死信消息将死信消息转发到指定的队列中
十分钟未支付取消订单 十分钟之后消息会过期过期后通过死信交换器转发队列中的死信消息将死信消息转发到指定的队列中由消费者去处理。
我们可以通过死信死信交换器实现延迟消息处理 RabbitMQ实现延迟消息处理有2种方式 1、死信死信交换器 代码实现可控更方便一些 2、延迟消息插件
1、死信死信交换器 代码实现可控更方便一些 发送消息到队列1产生延迟队列产生死信 一个消息过一段时间实现消费。
核心 1.队列 是2个队列第1个队列 目的 产生死信1.设置有效期2.不设置消费者借助死信交换器把产生的死信发到指定的队列中 第二个对了目的 消费死信这里获取的信息时间就是延迟的延迟的就是上面的有效期 2.1个交换器 死信交换器整个系统一般就一个可以用来转发各个功能产生的死信是Direct类型的交换通过RK进行消息匹配到对应的队列中。 RabbitMQ的消息的有效期有2种设置方式 1.设置队列上的有效期整个队列中所有消息都使用 2.可以在每个消息上设置有效期这种适用于有多个不同有效期的消息 如果队列和消息都有有效期谁短听谁的。
代码 RabbitMQ02 实现 1.pom
dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency!-- RabbitMQ --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-amqp/artifactId/dependency/dependencies2.代码 config-RabbitMQConfig
package com.yd.rabbitmq02.config;import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;/*** author MaoXiqi* organization: Lucky* create 2023-10-16 11:35:54* description RabbitMQConfigApi*/
Configuration
public class RabbitMQConfig {// 1.创建2个队列Beanpublic Queue createQ1() {// 1.设置队列 内部消息有效期 设置死信交换器 设置RKHashMapString, Object params new HashMap();// 设置队列中每个消息的有效期 单位 毫秒params.put(x-message-ttl, 3000);// 设置对应的死信交换器params.put(x-dead-letter-exchange, dead-ex-yd);// 设置交换器匹配的路由名称params.put(x-dead-letter-routing-key, test);return QueueBuilder.durable(dl-q01).withArguments(params).build();}Beanpublic Queue createQ2() {return new Queue(dl-q02);}// 2.创建1个交换器1.fanout 2direct 3.topic 4.header-死信交换器direct类型Beanpublic DirectExchange createDe() {return new DirectExchange(dead-ex-yd);}// 3.创建1个绑定Beanpublic Binding createBd1(DirectExchange de) {return BindingBuilder.bind(createQ2()).to(de).with(test);}
} 2.1.创建两个队列 1、设置队列内部消息有效期 设置死信交换器 设置RK 注意参数名是固定的值根据业务需求去改值 单位是毫秒
2.2创建1个交换器1.fanout 2.direct 3.tipic 4.header-死信交换器direct类型
2.3.创建一个绑定
controller-DeadController GetMapping(send)public String sendDead(String msg) {System.out.println(发送消息, msg ,发送时间: System.currentTimeMillis());template.convertAndSend(, dl-q01, msg);return ok;}发送 监听消息-主要是为了消费 listener-DeadListener RabbitListener(queues dl-q02)public void handler(String m) {System.out.println(延迟消息,m,接受时间: System.currentTimeMillis());}yml
spring:rabbitmq:host: 121.36.5.100port: 5672username: guestpassword: guest
server:port: 8082测试
RabbitMQ事务
数据库中事务保证数据一致性特别是多个操作要么都成功要么都失败 RabbitMQ事务一次性发多条消息需要开启事务 RabbitMQ也有自己的事务如果本次 使用步骤
源码RabbitMQ02 1.创建配置类 2.使用基于事务发送 3.监听消息
1.创建配置类 config-RabbitMQTranConfig 1.准备一个队列 2.创建事务管理器
// 创建事务管理器Beanpublic RabbitTransactionManager createTran(ConnectionFactory factory) {return new RabbitTransactionManager(factory);}2.controller-TranController 开启事务 发送消息 // 事务Transactional // 需要开启SpringBoot的事务机制GetMapping(sendmsg)public String sendMsg(String msg, int count) {// 开启 RabbitMQ的通道的事务template.setChannelTransacted(true);// 发送消息for (int i 0; i count; i) {template.convertAndSend(, yd-tran-q01, msg -- count);// 出错看看 事务是否生效if (i2) {System.out.println(1/0);}}return ok;}3.listener-DeadListener // 事务RabbitListener(queues yd-tran-q01)public void handler2(String msg) {System.out.println(监听消息msg);// 处理业务逻辑 出错了}手动ACK
RabbitMQ怎么防止消息丢失: 1.发送端没有发送过去 解决 1.用事务 2.confirm消息确认机制 万能转人工处理 2.MQ服务器丢失MQ服务器蹦了 解决开启持久化 3.消费端消息丢失 解决自动应答改成开始手动ACK
消息确认机制默认是自动确认
消息的发送和接收是异步
RabbitMQ如何防止消息丢失 代码 config-RabbitMqTranConfig //消费消息的⼿动应答Beanpublic Queue createQ4() {return new Queue(yd-ack-q01);}controller-DeadController // 事务Transactional // 需要开启SpringBoot的事务机制GetMapping(sendmsg)public String sendMsg(String msg, int count) {// 开启 RabbitMQ的通道的事务template.setChannelTransacted(true);// 发送消息for (int i 0; i count; i) {template.convertAndSend(, yd-tran-q01, msg -- count);// 出错看看 事务是否生效if (i2) {System.out.println(1/0);}}return ok;}listener-DeadListener 一般设置个上限比如最多三次 RabbitListener(queues yd-ack-q01)public void handler3(String msg, Channel channel, Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {//消费者获取消息默认采用的自动应答就是获取就应答这样MQ服务器就删除消息//还可以手动应答:结果:1.成功(MQ删除)2.失败(MQ消息)System.out.println(收到ACK消息监听消息: msg);//拒绝消息 参数说明1.消息id 2.结果 true 成功 false 拒绝 3.是否把消息添加回队列中channel.basicNack(tag,false,true);//成功消息 参数说明1.消息id 2.结果 true 成功 false 拒绝//channel.basicAck(tag,true);// 处理业务逻辑 出错了}消费消息的手动应答 RabbitMQ默认的消费者消息获取模式采用的是手动应答 但是这种有缺陷可能会出现消息获取了但是业务出了问题导致MQ也自动删除了消息最终导致业务没有执行 所以为了解决这种问题可以开启手动应答模式结合自己的业务执行情况如果业务执行成功那么就成功应答如果失败了就拒绝消息同时把消息再加回队列这样就可以再次消息再次处理加个上限 测试
RabbitMQ如何保证消息的幂等性 幂等性就是重复消费。 解决 1.生成一个全局id存入redis或者数据库在消费者消费消息之前查询一下该消息是否有小费过。 2.
用户充值重复消费相当如充值了多次是一定要杜绝的。 不要返回值的时候可以用RabbitMQ替代OpenFegin因为消费完就不回了。MQ默认是单向的 短信发信可以用MQ这个业务要做做起来可能会很耗时中间要经过运营商过程不可控
RabbitMQ应用场景 消息通信发送消息和接收消息是异步 1.实现服务通信 用在微服务中实现2个服务的通信这种不带返回值的只是为了执行另一个服务的方法执行 2.解决耗时操作 比如邮件、短信、第三方接口等比较耗时 3.解耦 4.提升性能 5.重复代码封装 6.削峰填谷订单先下到redis中再通过MQ和延迟队列慢慢的从redis搬到mysql中
关键词异步、解耦、延迟