执行长时间任务(46及以后的版本)

场景描述

如果一个服务需要执行比较长的时间,没有任何返回,超过设置的超时时间后,前端就会收到504,在某些网络环境下,还会造成网络重试。

从46版本开始,系统支持在调用长时间服务时,实时返回执行进度,不造成超时,且界面上可以显示进度条。

实现思路

启用响应流模式,利用 ProgressiveTaskUtil 实时通知客户端处理进度,保持响应流的连续。

实现步骤

  1. 定义服务时,选中“启用响应流模式”

在服务中

  • 首先调用 ProgressiveTaskUtil.getCurrentTask 方法获取当前任务
  • 然后根据业务处理情况,择机调用当前任务的setPercent方法,设置后,前端即可收到设置的百分比
  • 最后正常返回数据

java代码如下:

public String longTimeService() throws Exception {
    ProgressiveTask<String> task = ProgressiveTaskUtil.getCurrentTask();
    for(int i=0;i<=100;i++) {
        Thread.sleep(100);
        JSONObject extInfo = new JSONObject();
        task.setPercent(i, "进度", extInfo);//后两个参数不能为空
    }
    Thread.sleep(100);
    return "OK";
}

涉及到的引用如下

import com.alibaba.fastjson.JSONObject;
import com.justep.util.progressive.ProgressiveTaskUtil;
import com.justep.util.progressive.ProgressiveTaskUtil.ProgressiveTask;
  1. 前端页面调用服务,在响应进度消息事件中,获取百分比

  2. 使用服务请求组件

      //在响应进度消息事件中,获取百分比
      onServiceRequest0Message = (event) => {
          this.comp("pageData").setValue("percent",event.message.percent);
      }
    
      //在请求成功事件中,获取返回数据
      onServiceRequest0Success = (event) => {
          message.info(event.data);
      }
    
  3. 使用 this.request

      onButton1Click = async (event) => {
          let {data} = await this.request({
              url:"$serviceName/main/fuwu/longtimeservice"
          })
          //在响应进度消息事件中,获取百分比
          data.on("message",(message)=>{
              this.comp("pageData").setValue("percent",message.percent);
          })
          //在请求成功事件中,获取返回数据
          data.on("done",(data)=>{
              message.info(data);
          })
      }
    

运行效果如下图所示

可以看到响应头中的 Content-Type 是 text/event-stream;charset=UTF-8

执行长时间任务(45及以前的版本)

场景描述

如果一个服务需要执行比较长的时间,没有任何返回,超过设置的超时时间后,前端就会收到504,在某些网络环境下,还会造成网络重试。

从46版本开始,系统支持在调用长时间服务时,返回执行进度,用于界面上显示进度条。

实现思路

在服务执行中不断返回response,前端就会认为服务正在执行,不会出现504

实现步骤

在java代码中,根据业务处理情况,择机返回response。本例使用循环,每1000条数据返回一次response,代码如下:

    //获取response
    HttpServletResponse response = SpringWebUtil.getResponse();
    //使用分块传输
    response.setHeader("Transfer-Encoding","chunked");

    //在业务处理中,择机返回response
    for (int i=0;i< users.size();i++) {
        //每1000条数据,返回一下,避免出现504
        if(i % 1000 == 0) {
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write((i+"\n").getBytes());
            outputStream.flush();
        }
    }

涉及到的引用如下

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import com.justep.util.SpringWebUtil;

运行效果如下图所示

results matching ""

    No results matching ""

    results matching ""

      No results matching ""