网站推广费用价格网上暴利赚钱项目
news/
2025/10/2 3:10:26/
文章来源:
网站推广费用价格,网上暴利赚钱项目,十大最火网络游戏,畅销营销型网站建设电话项目场景#xff1a; 在电商、支付等领域#xff0c;往往会有这样的场景#xff0c;用户下单后放弃支付了#xff0c;那这笔订单会在指定的时间段后进行关闭操作#xff0c;细心的你一定发现了像某宝、某东都有这样的逻辑#xff0c;而且时间很准确#xff0c;误差在1s内…项目场景 在电商、支付等领域往往会有这样的场景用户下单后放弃支付了那这笔订单会在指定的时间段后进行关闭操作细心的你一定发现了像某宝、某东都有这样的逻辑而且时间很准确误差在1s内那他们是怎么实现的呢 一般实现的方法有几种使用 redisson、rocketmq、rabbitmq等消息队列的延时投递功能。 解决方案 一般项目集成redis的比较多所以我这篇文章就说下redisson延迟队列如果使用rocketmq或rabbitmq需要额外集成中间件比较麻烦一点。 1.集成redisson
maven依赖
dependencygroupIdorg.redisson/groupIdartifactIdredisson-spring-boot-starter/artifactIdversion3.21.1/version
/dependency
yml配置单节点配置可以兼容redis的配置方式
# redis配置
spring:redis:database: 0host: 127.0.0.1password: redispassport: 6001 更详细的配置参考Spring Boot整合Redisson的两种方式-CSDN博客
2.配置多线程 因为延迟队列可能会多个任务同时执行所以需要多线程处理。 import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.ThreadPoolExecutor;Configuration
EnableAsync
public class ExecutorConfig {/*** 异步任务自定义线程池*/Bean(name taskExecutor)public ThreadPoolTaskExecutor asyncServiceExecutor() {ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor();//配置核心线程数executor.setCorePoolSize(50);//配置最大线程数executor.setMaxPoolSize(500);//配置队列大小executor.setQueueCapacity(300);//允许线程空闲时间executor.setKeepAliveSeconds(60);//配置线程池中的线程的名称前缀executor.setThreadNamePrefix(taskExecutor-);// rejection-policy当pool已经达到max size的时候如何处理新任务// CALLER_RUNS不在新线程中执行任务而是有调用者所在的线程来执行executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());//调用shutdown()方法时等待所有的任务完成后再关闭executor.setWaitForTasksToCompleteOnShutdown(true);//等待所有任务完成后的最大等待时间executor.setAwaitTerminationSeconds(60);return executor;}
}
3.具体业务 比如消息通知、关闭订单等 这里加上了Async注解可以异步执行 import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;import java.text.SimpleDateFormat;
import java.util.Date;Service
public class AsyncService {Asyncpublic void executeQueue(Object value) {System.out.println();System.out.println(当前线程Thread.currentThread().getName());System.out.println(执行任务value);//打印时间方便查看SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);System.out.println(执行任务的时间sdf.format(new Date()));//自己的业务逻辑可以根据id发送通知消息等//......}
}
4.延迟队列(关键代码) 这里包括添加延迟队列和消费延迟队列PostConstruct注解的意思是服务启动加载一次参考 Spring Boot项目启动时执行指定的方法-CSDN博客Spring Boot中多个PostConstruct注解执行顺序控制_多个postconstruct执行顺序-CSDN博客 import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;Service
public class TestService {Resourceprivate AsyncService asyncService;Resourceprivate ThreadPoolTaskExecutor executor;Autowiredprivate RedissonClient redissonClient;/*** 添加延迟任务*/public void addQueue() {//获取延迟队列RBlockingQueueObject blockingQueue redissonClient.getBlockingQueue(delayedQueue);RDelayedQueueObject delayedQueue redissonClient.getDelayedQueue(blockingQueue);for (int i 1; i 10; i) {long delayTime 5i; //延迟时间(秒)
// long delayTime 5; //这里时间统一可以测试并发执行delayedQueue.offer(延迟任务i, delayTime, TimeUnit.SECONDS);}//打印时间方便查看SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);System.out.println(添加任务的时间sdf.format(new Date()));}/*** 服务启动时加载开始消费延迟队列*/PostConstructpublic void consumer() {System.out.println(服务启动时加载);//获取延迟队列RBlockingQueueObject delayedQueue redissonClient.getBlockingQueue(delayedQueue);//启用一个线程来消费这个延迟队列executor.execute(() -{while (true){try {
// System.out.println(while中的线程Thread.currentThread().getName());//获取延迟队列中的任务Object value delayedQueue.poll();if(value null){//如果没有任务就休眠1秒休眠时间根据业务自己定义Thread.sleep(1000); //这里休眠时间越短误差就越小continue;}//异步处理延迟队列中的消息asyncService.executeQueue(value);} catch (Exception e) {e.printStackTrace();}}});}
}
5.测试接口
import com.test.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
RequestMapping(/test)
public class TestController {Autowiredprivate TestService testService;/** 添加延迟任务*/GetMapping(value /addQueue)public String addQueue() {testService.addQueue();return success;}}
6.测试结果 总结 Redisson的的RDelayedQueue是基于Redis实现的而Redis本身并不保证数据的持久性。如果Redis服务器宕机那么所有在RDelayedQueue中的数据都会丢失。因此我们需要在应用层面进行持久化设计例如定期将RDelayedQueue中的数据持久化到数据库。在设计延迟任务时我们应该根据实际需求来合理设置延迟时间避免设置过长的延迟时间导致内存占用过高。 源码https://download.csdn.net/download/u011974797/89225515
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/924521.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!