当前位置: 首页 > news >正文

网站建设问卷调研wordpress wiki 主题

网站建设问卷调研,wordpress wiki 主题,坤思特重庆网站建设熊掌号,微官网和小程序有什么区别前言 目前很多产品都用到过定时发布或者定时推送等功能#xff0c;定时推送有两种定义#xff0c;一种是后台自己有相关规则#xff0c;通过定时器设置好相应的时间进行推送(例如定时任务框架QuartZ、xxl-job等实现,或者通过springboot自带定时任务Scheduled注解等实现)定时推送有两种定义一种是后台自己有相关规则通过定时器设置好相应的时间进行推送(例如定时任务框架QuartZ、xxl-job等实现,或者通过springboot自带定时任务Scheduled注解等实现)这些都是基于后台设定的规则来进行定时推送。 还有一种场景便是根据用户自己选择想要的时间进行推送这时候再用到上面的方法来做会比较麻烦和复杂就需要用到延时队列来实现 实现方式 在做这个功能之前我在网上查阅了想要实现这种根据用户选择时间来推送的相关资料发现方式还是挺多的包括但不限于以下几种 最简单暴力的方法通过上述的定时任务框架或者springboot自带的定时器来实现把cron表达式书写为每分钟一次然后每分钟都去检查是否和用户设置的时间能匹配上如能匹配上就进行相关的业务操作通过实现springboot自带的SchedulingConfigurer接口来进行动态任务调用通过DelayQueue队列进行实现通过MQ中间件的发送消费来实现通过Redis设置key过期时间触发来进行实现 … 上面的几种实现第1、2点比较简单也很有效果但是容易出现效率问题和准确性的问题下面45点的比较不错但是相比较起来学习成本会高一些具体实现的思路差不太多这些都有相关的资料通过上面的关键字搜索便能查阅到 功能实现 看了那么多的方案之后再结合自身的项目最终决定用一种新的方案来实现通过Redis自带的DelayedQueue延时队列来完成和上面的第45点其实思路差不太多只不过这个更简单方便一点 定义一个实体类来进行配置 Data public class TaskBodyDto implements Serializable {/*** 重试最大次数*/public static final int MAX_RETRY 3;private String idKey;private String beanName;private String methodName;private MapString, Object paramMap;/*** 重试计时器*/private int cnt;/*** 延迟的时间*/private long delay;/*** 延迟的时间单位*/private TimeUnit timeUnit;}定义RedissonDelayQueue类 Slf4j Component public class RedissonDelayQueueDemo {Resourceprivate RedissonClient redissonClient;private RBlockingQueue rBlockingQueue;private RDelayedQueue rDelayedQueue;PostConstructprivate void init() {rBlockingQueue redissonClient.getBlockingQueue(TaskListener.class.getName());rDelayedQueue redissonClient.getDelayedQueue(rBlockingQueue);}public void add(TaskBodyDto reqVo) {rDelayedQueue.offer(reqVo, reqVo.getDelay(), reqVo.getTimeUnit());log.info(增加了延时队列{}, reqVo);}/*** 增加订单延时队列 -单位为秒** param id id,传入一个唯一标识,可以是业务ID* param beanName 类名* param methodName 方法名* param paramMap 参数* param delay 延迟时间*/public void add(String id, String beanName, String methodName, MapString, Object paramMap, long delay) {TaskBodyDto reqVo new TaskBodyDto();String idKey beanName : methodName : id;log.info(增加了延时队列 idKey);reqVo.setIdKey(idKey);reqVo.setBeanName(beanName);reqVo.setMethodName(methodName);reqVo.setParamMap(paramMap);reqVo.setTimeUnit(TimeUnit.SECONDS);reqVo.setDelay(delay);this.add(reqVo);}/*** 删除延时队列** param id id,传入一个唯一标识,可以是业务ID* param beanName 类名* param methodName 方法名*/public void remove(String id, String beanName, String methodName) {String idKey beanName : methodName : id;log.info(删除了延时队列 idKey);RDelayedQueueTaskBodyDto delayedQueue rDelayedQueue;StreamTaskBodyDto stream delayedQueue.stream().filter(s - idKey.equals(s.getIdKey()));ListTaskBodyDto c stream.collect(Collectors.toList());if (!c.isEmpty()) { // log.info(删除延时队列{}, c);delayedQueue.remove(c.get(0));}}}然后写一个工具类方便调用 Component public class RedissionDelayQueueUtils {Autowiredprivate RedissonDelayQueue redissonDelayQueue;Autowiredprivate static RedissonDelayQueue staticRedissonDelayQueue;PostConstructpublic void init() {staticRedissonDelayQueue redissonDelayQueue;}/*** 添加定时任务* param id 唯一标识,可以是业务ID* param paramMap 参数 key-value* param beanName bean类名称 注意类名需要小写* param methodName 方法名* param seconds 延迟时间 单位为秒*/public static void addDelayQueue(String id, MapString, Object paramMap, String beanName, String methodName, Integer seconds) {staticRedissonDelayQueue.add(id, beanName, methodName, paramMap, seconds);}/*** 删除定时任务* param id 唯一标识,可以是业务ID* param beanName bean类名称 注意类名需要小写* param methodName 方法名*/public static void removeDelayQueue(String id, String beanName, String methodName) {staticRedissonDelayQueue.remove(id, beanName, methodName);}}然后再配置好监听器在监听器里面通过反射获取到相关的方法然后执行里面的业务 Slf4j Component public class TaskListener implements RedisDelayedQueueListenerTaskBodyDto {private static final ListClass WRAP_CLASS Arrays.asList(Integer.class, Boolean.class, Double.class, Byte.class, Short.class, Long.class, Float.class, Double.class, BigDecimal.class, String.class);//队列QueueAutowiredprivate RedissonDelayQueue redissonDelayQueue;Autowiredprivate TaskSender taskSender;Overridepublic void invoke(TaskBodyDto reqVo) {log.info(开始执行监听...{}, reqVo);reqVo.setCnt(reqVo.getCnt() 1);try {Object bean ApplicationContextUtil.getBean(reqVo.getBeanName());Method method ReflectUtil.getMethodByName(bean.getClass(), reqVo.getMethodName());Class target AopUtils.getTargetClass(bean);Method targetMethod ReflectUtil.getMethodByName(target, reqVo.getMethodName());ListObject objects getMethodParamList(targetMethod, reqVo.getParamMap());method.invoke(bean, objects.toArray());} catch (Exception e) {log.error(invoke task err!, e);if (reqVo.getCnt() TaskBodyDto.MAX_RETRY) {log.error(重试次数超过最大次数不再重试。);DeadQueDto deadQueDto new DeadQueDto();deadQueDto.setBeanName(reqVo.getBeanName());deadQueDto.setMethodName(reqVo.getMethodName());deadQueDto.setParamMap(reqVo.getParamMap());taskSender.sendTask(deadQueDto);} else {//重试30分钟后重试秒为单位则用原数据if (reqVo.getTimeUnit().name().equals(TimeUnit.DAYS.name()) || reqVo.getTimeUnit().name().equals(TimeUnit.HOURS.name())) {reqVo.setDelay(30);reqVo.setTimeUnit(TimeUnit.MINUTES);redissonDelayQueue.add(reqVo);} else if (reqVo.getTimeUnit().name().equals(TimeUnit.MINUTES.name()) reqVo.getDelay() 30) {reqVo.setDelay(30);reqVo.setTimeUnit(TimeUnit.MINUTES);redissonDelayQueue.add(reqVo);} else {redissonDelayQueue.add(reqVo);}}}}private ListObject getMethodParamList(Method method, MapString, Object paramMap) throws Exception {ListObject objectList new ArrayList();// 利用Spring提供的类获取方法形参名DefaultParameterNameDiscoverer nameDiscoverer new DefaultParameterNameDiscoverer();String[] param nameDiscoverer.getParameterNames(method);for (int i 0; i method.getParameterTypes().length; i) {Class? parameterType method.getParameterTypes()[i];Object object null;// 基本类型不支持支持包装类String paramKey param[i];if (WRAP_CLASS.contains(parameterType)) {if (param ! null paramMap.containsKey(paramKey)) {object paramMap.get(paramKey);object ConvertUtils.convert(object, parameterType);}} else if (!parameterType.isPrimitive()) {if (parameterType.isAssignableFrom(List.class) || parameterType.isAssignableFrom(Map.class) || parameterType.isAssignableFrom(Set.class)) {object paramMap.get(paramKey);} else {object parameterType.newInstance();BeanUtils.populate(object, paramMap);}}objectList.add(object);}return objectList;}}都配置好之后可以写个方法进行测试 比如我要三十分钟之后执行test方法 public class Test {private void test(String name,String value){//执行业务代码}}然后在需要执行这个功能的地方进行调用比如用户在界面选择了发布时间之后后端接口收到请求进行处理 //延时队列MapString, Object map new HashMap();map.put(name,张三);map.put(value,这是value);RedissionDelayQueueUtils.addDelayQueue(唯一标识,map,test,test, (int) DateUtil.between(用户选择的时间,new Date(), DateUnit.SECOND)); 注意事项这上面的map便是被执行的方法需要的一些参数,切记不能直接传入Object类只能通过基本数据类型进行传递传入的bean类名也需要小写DateUtil.between()这个方法是用的hutool工具类里面的日期工具类为了算出用户选择的时间和当前时间相差多少秒可自行更改为适合自己的方法反正最后只需要取到两者时间差多少秒即可 后续redis的配置那些照常配置即可 总结 总结下来其实思路还是比较明确就是通过redis延时队列的机制这边配置好相关的参数然后加入到redis里面去配置好监听器之后由redis进行监听触发然后再通过反射的方式取到需要执行的bean和方法进行执行即可其实延时队列的方法很多我上面还推荐了一些其他的方法通过给出的关键字即可查阅相关的资料总之根据自身的情况选择最适合的方法就行 最后不管采取哪种方式建议在触发以及执行的地方及时把日志打印出来方便后期调试以及对问题的定位
http://www.huolong8.cn/news/430962/

相关文章:

  • 做网站不会框架广东住房建设厅网站
  • 企业网站建设的定位网页打不开但是微信和qq都可以上
  • 以什么主题做网站好企业为什么要建站
  • 优化网站 主题icp备案需要先建设网站么
  • wordpress短代码显示成都百度推广优化
  • 怎么套模板 网站做淘宝门头的网站
  • 网站开发行业资讯夜夜夜在线观看
  • 北京网站制作招聘建设部网站公民服务
  • 网站营销定义项目拉新平台
  • 牡丹江市建设工程交易中心网站网站域名使用费
  • 外贸公司 如何做公司网站全国信用企业公示平台官网
  • 用手机怎么做网站附近的网站电脑培训班
  • 苏州网站建设开发公司wordpress完全静态化
  • 响水企业做网站多少钱自己怎么申请免费网站
  • 找代做海报的网站百度在线使用网页版
  • 会计题库网站怎么做娶妻为什么不娶外贸女
  • 医院网站制作公司网站服务设计
  • 网站建设与管理就业岗位 方向甘肃省省建设厅网站
  • qq空间做淘宝客网站百度推广营销中心
  • 徐州做网站织梦做的网站首页幻灯片怎么不能显示
  • 用什么软件做商务网站南召微网站建设
  • 宁波企业网站建站中国铁建网站
  • 青浦区网站建设公司做美食网站视频下载
  • 深圳设计网站排行安徽网站设计找哪家
  • 建筑企业网站源码wordpress二次元简约主题
  • 南昌网站改版公司泰安集团网站建设方案
  • c 做彩票网站昆明市环保局建设网站
  • 在虚拟机中如何做二级域名网站网站结构怎么做
  • 做招聘求职网站设计资源网站大推荐
  • 南京和筑建设有限公司网站赛事竞猜网站开发