ruoyi系统导入容易超时解决方案(redis+多线程)

  • 简介

在日常开发中,如果一个链接执行的时间过长,前端等不到后端返回数据会报错,或者用户一直等待任务执行,影响用户体验。
很多时候采用的方法是,前端将链接超时时间设长,但这有时并不优雅。
在这里采用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;
    }
}
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RuoYi-plus是一个基于RuoYi升级的springcloud版本管理系统。软件由SMP多商户后台管理系统+API后端接口组成,项目支持cms内容管理和商城业务,提供单机版服务、微服务体系双向选择,微服务集成分布式事务解决方案seata,框架基于SpringBoot2.x,springcloudG版本。 RuoYi-plus项目介绍 项目核心: 多商户权限系统+商城平台+CMS内容管理+微服务API系统 架构技术: 基于SpringBoot2.x, springcloud G版本eureka、hystrix、feign、config、gateway微服务架构体系的全新版本,集成分布式事务解决方案seata,集成redis、quartz、tk.mybatis、lombok、各种设计模式等。 项目优势: 架构更清晰、技术更前沿、代码更整洁、页面更美观、学习商用均可。可用于OA系统、 CRM系统、 PDM系统等二次开发,微服务架构学习,非常适用于公司管理平台旧版本升级、新平台搭建快速整合、同时提供API接口服务(供APP、微端、h5等使用)。 RuoYi-plus内置功能 管理平台基础功能 1、用户管理:用户是系统操作者,该功能主要完成系统用户配置。 2、部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。 3、岗位管理:配置系统用户所属担任职务。 4、菜单管理:配置系统菜单,操作权限,按钮权限标识等。 5、角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。 6、字典管理:对系统中经常使用的一些较为固定的数据进行维护。 7、参数管理:对系统动态配置常用参数。 8、通知公告:系统通知公告信息发布维护。 9、操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 10、登录日志:系统登录日志记录查询包含登录异常。 11、在线用户:当前系统中活跃用户状态监控。 12、定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 13、代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。 14、系统接口:根据业务代码自动生成相关的api接口文档。 15、服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。 16、在线构建器:拖动表单元素生成相应的HTML代码。 17、连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。 商城业务基础功能 1、商户管理:多商户系统核心业务,商户管理对应权限数据。 2、类别管理:商品类别配置,为商品区分类别。 3、商品管理:每个商户下的商品信息。 CMS内容基础功能 1、文章类别管理:文章列表信息,为文章区分不同类别。 2、文章信息管理:文章具体信息,直接生成文章html页面。 3、素材类别管理:为素材提供类别以区分不同业务的素材图片/视频。 4、素材信息管理:文章信息的素材图片管理。 API接口基础功能 1、业务模块:接收网关gateWay转发请求,api微服务结构处理具体业务,解决分布式事务。 2、订单模块:订单相关业务处理。 3、商品模块:商品相关业务处理。 商用须知 本项目遵循MIT协议,无需授权,留言备注公司信息即可。 演示地址账号:tecom  密码:123456
【项目说明】 1.项目代码均经过功能验证ok,确保稳定可靠运行。欢迎下载食用体验! 2.主要针对各个计算机相关专业,包括计算机科学、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师、企业员工。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。在使用过程中,如有问题或建议,请及时沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈! 【资源介绍】 基于Ruoyi开发的社团管理系统源码(含数据库+说明文档).zip 内置功能 1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。 2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。 3. 岗位管理:配置系统用户所属担任职务。 4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。 5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。 6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。 7. 参数管理:对系统动态配置常用参数。 8. 通知公告:系统通知公告信息发布维护。 9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 10. 登录日志:系统登录日志记录查询包含登录异常。 11. 在线用户:当前系统中活跃用户状态监控。 12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。 14. 系统接口:根据业务代码自动生成相关的api接口文档。 15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。 16. 缓存监控:对系统的缓存信息查询,命令统计等。 17. 在线构建器:拖动表单元素生成相应的HTML代码。 18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。 ## 在线体验 - admin/admin123

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值