下载中心实现总结

下载中心实现总结

背景:业务要求,需要一个全量导出数据库并生成excel表格的功能。因为数据量大,使用poi生成excel的速度也很慢,直接返回用户体验很差,所以打算开发一个下载中心来支持后台生成。

实现:使用redis链表做一个简单的消息队列(系统采用多容器来做,消息队列可以简单实现各容器上下载任务负载均衡),传递的消息为后台启动函数的名称、参数等,数据库维护一张表简单记录下载信息,用于展示。

每次点击生成excel,向redis提交一个相关任务信息,更新数据库,各个容器都有一个后台任务,它们会去尝试消费这个信息,某个容器拿到信息后,通过反射机制,拿到具体的函数、参数,然后执行该任务。

任务执行完成后,会将生成的文档上传到我司内部的一个平台,返回一个id,通过该id可以下载到该文档,同时更新数据库,用户通过查询数据库获取id再下载文档。

一、通过反射恢复任务(记得抛异常)

Class clazz = Class.forName(className);//className:类名
Method method = clazz.getMethod(methodName, classes);//methodName:方法名,classes:该方法入参的参数类型数组
Object o = clazz.newInstance();//使用newInstance方法new一个对象
method.invoke(o, params);//params:方法的参数。执行函数
  • tips:如果项目是基于Spring的,请不要使用newInstance方法直接new一个对象实例!因为new出来的对象如果有依赖注入的话,那么这些注入都是空,请再传一个参数,使用getBean()的方法来获取对象实例

二、实例化

  • 项目里是把函数的类名、参数类型、参数值等都序列化为Json字符串
  • 但是在将Json字符串反序列化为类名、参数类型、参数值等时,因为,参数值比较多,且存在自定义对象
  • 我们是使用List来存放的,反序列化的时候,无论使用Gson还是JsonUtil,反序列化的fromJson( Json字符串,List),都会把自定义的对象转成一个LinkedTreeMap类型,从而导致参数不匹配而报错。
  • 这个时候我们需要遍历一下刚刚转出来的List,将里面的对象转回Json,然后根据一同传进来的各个参数的类型,再使用fromJson(构成List的 Object对象 , 具体的类名 ),才可以转成原来的参数。
  • String json;//Json字符串,里面是具体参数值
    List<Object> l = new Gson().fromJson(json,List<Object>);
    List<Object> params = new LinkedList<>();
    for(Object o : l){
        String tempjson = new Gson().toJson(o);
        params.add(new Gson().fromJson(tempjson,类名));
    }
    
posted @ 2022-04-29 23:17  ElloeStudy  阅读(116)  评论(0编辑  收藏  举报