
ruoyi系统导入容易超时解决方案(redis+多线程)
在日常开发中,如果一个链接执行的时间过长,前端等不到后端返回数据会报错,或者用户一直等待任务执行,影响用户体验。private final String STATE_MSG_200 = "任务执行完毕";private final String STATE_MSG_400 = "任务执行失败";private final String STATE_MSG_0 = "任务正在运行";//简化一套 用
·
- 简介
在日常开发中,如果一个链接执行的时间过长,前端等不到后端返回数据会报错,或者用户一直等待任务执行,影响用户体验。
很多时候采用的方法是,前端将链接超时时间设长,但这有时并不优雅。
在这里采用redis+多线程,用户可以实时查看当前任务进度,还不必去过多等待任务执行。
- 项目流程
- 技术概要
此项目是在ruoyi架构上进行的(没有单独配置redis)
为了与其他功能解耦,将此功能单独设置成一个模块,通过用户调用,实现流程。
通过java代理对用户要执行的代码进行处理,使用户只需要处理业务代码,简化用户操作(核心)。
//给run方法添加代理 InvocationHandler invocationHandler = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //执行任务,报错 Object invoke = null; try { invoke = method.invoke(runnable, args); updateTaskState(key,Entity.builder().state("200").msg(STATE_MSG_200).build()); } catch (Exception e) { updateTaskState(key,Entity.builder().state("400").msg(STATE_MSG_400).build()); } return invoke; } };
- 代码
用户调用:
通过简单的代码,就能完成对控制器的修改,并且不入侵原先的代码。如果觉得redisTaskServer.getTaskState(key)获取后判断,还是冗余,可以把这段代码放入到createTask方法中通过抛出异常实现
String key = "user:12fla:001"; //key建议使用用户id加方法的标示 Entity method = redisTaskServer.getTaskState(key); if(method != null){ return "上一个任务没有执行完:"+method.getMsg(); } redisTaskServer.createTask(key, new Runnable() { @Override public void run() { //要执行的业务端代码 } }); return "已添加任务";
功能:
##########对外开放接口类 public interface RedisTaskServer { //查询任务结果 public Entity getTaskState(String key); //删除任务结果 public int deleteTaskKey(List<String> keys); //修改任务结果 public Entity updateTaskState(String key,Entity entity); //简化一套 用户只要发送过来key与要执行人任务就可以。 //自动生成任务信息共cglib动态生成结果 public boolean createTask(String key,Runnable runnable); public String createKey(String arg); } #################对外开放实体类 @Data @Builder @NoArgsConstructor @AllArgsConstructor public class Entity { private String state; private String msg; } ################接口实现类 @Service public class RedisTaskServerImpl implements RedisTaskServer { private final String KEY = "redisTask"; private final String STATE_MSG_0 = "任务正在运行"; private final String STATE_MSG_200 = "任务执行完毕"; private final String STATE_MSG_400 = "任务执行失败"; @Autowired private RedisCache redisCache; @Override public Entity getTaskState(String key) { String cacheMapValue = redisCache.getCacheMapValue(KEY, key); if(!cacheMapValue.isEmpty()){ Entity entity = JSONUtil.toBean(cacheMapValue, Entity.class); return entity; } return null; } @Override public int deleteTaskKey(List<String> keys) { Map<String, Object> cacheMap = redisCache.getCacheMap(KEY); if(cacheMap == null){return 0;} int result = 0; for (String key : keys) { if(cacheMap.remove(key)!=null){ result++; } } return result; } @Override public Entity updateTaskState(String key, Entity entity) { redisCache.setCacheMapValue(KEY,key,JSONUtil.parse(entity).toString()); return entity; } @Override public boolean createTask(String key, Runnable runnable) { //不负责结果key冲突 updateTaskState(key,Entity.builder().state("0").msg(STATE_MSG_0).build()); //给run方法添加代理 InvocationHandler invocationHandler = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //执行任务,报错 Object invoke = null; try { invoke = method.invoke(runnable, args); updateTaskState(key,Entity.builder().state("200").msg(STATE_MSG_200).build()); } catch (Exception e) { updateTaskState(key,Entity.builder().state("400").msg(STATE_MSG_400).build()); } return invoke; } }; Runnable o = (Runnable) Proxy.newProxyInstance(RedisTaskServerImpl.class.getClassLoader(),runnable.getClass().getInterfaces(),invocationHandler); new Thread(o).start(); return true; } @Override public String createKey(String arg) { Long deptId = SecurityUtils.getLoginUser().getUser().getDeptId(); String key = "user:"+deptId+"fla:"+arg; return key; } }复制
推荐内容
更多推荐
所有评论(0)