异步处理耗时请求

最近做一个项目,需要把excel导入到数据库中,一般的流程是后台poi解析excel,后台做校验,数据补全等逻辑再转换为json数据,返回到前台,前台点击确认导入后,再保存到后台。但是这样做有几个问题? 假设数据量很大或者校验,数据补全等特别耗时间,夸张的,甚至得几十分钟,这个请求可能就会被浏览器认为是超时请求,有的同学可能会说,小意思,我把浏览器超时时间设置的长一点不就好了,这个办法没有根本的解决问题,因为不可能要求每个用户都去改浏览器超时时间,即使可以,一般nginx反向代理也有超时设置,总不能把这个时间也改的很大吧,第二个问题?如何能保证用户保存的json数据是服务器返回给它的呢?懂前端的用户可能会把json给改了,但是一般我们不想这样,因为假设是一些特别重要的数据,这些数据只能根据他导入的excel得到,我们可能会把他上传的excel给保存起来,甚至还需要需要做做数字签名。第三个问题?如果用户量很大的话,每个请求占用时间太长,最终会导致线程池被耗尽,服务器无法响应。既然有如此多的问题,我们该如何解决呢,我有个解决思路,异步请求+redis,大题思路是这样,用户上传的excel后,我异步(开个新线程)的去执行excel解析,等解析完,把结果存储到redis里面,当开启线程后,我直接给浏览器返回一个uuid, 不必等线程执行完,才返回,最后浏览器拿着这个uuid轮询的去redis里面取结果。

下面是这种想法的简单实现:

1用到的技术有:JSR-311+ssj框架

2假设添加一个Person的操作非常耗时

package com.mochasoft.bjlt.controller;

import com.mochasoft.bjlt.cucpm.core.liantong.service.IPersonService;
import com.mochasoft.bjlt.cucpm.utils.Tools;
import com.mochasoft.data.resteasy.core.CustomMediaType;
import com.mochasoft.latte.commons.utils.R;
import com.mochasoft.latte.data.redis.repository.RedisRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import javax.ws.rs.*;

@Controller
@Path(value = "/")
@Slf4j
public class PersonController {

    @Autowired
    private IPersonService personService;
    @Autowired
    private RedisRepository redisRepository;

    /**
     * 增加人员信息
     * @return
     */
    @POST
    @Path("person")
    @Consumes("application/json")
    @Produces(value = CustomMediaType.APPLICATION_JSON_UTF_8)
    public R add(Person person) {
        try {
            String uuid = Tools.uuid();
            //此方法为异步方法,加@Async注解,并把结果存储到redis中
            personService.save(person);
            redisRepository.setEX(uuid,60*30,R.error(301, "创建人员信息未完成"));
            return R.ok().put("data",uuid);
        } catch (Exception e) {
            log.error("异步创建人员信息异常",e);
            return R.error();
        }
    }
    @GET
    @Path("personInRedis")
    @Produces(value = CustomMediaType.APPLICATION_JSON_UTF_8)
    public R queryPersonInRedis(@QueryParam("key") String key) {
        try {
            return (R) redisRepository.get(key);
        } catch (Exception e) {
            log.error("查询redis里的人员信息异常",e);
            return R.error();
        }
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值