20万数据导出

参考

https://blog.csdn.net/weixin_33719619/article/details/88983710

https://www.csdn.net/tags/MtjacgxsMTM1NC1ibG9n.html

https://blog.csdn.net/qq_40127376/article/details/124032521

方向

考虑涉及到的软件及中间件等。

我这是个小项目。

浏览器(chrome) 固定超时时间为 5分钟。

nginx 做为负载均衡(7层) 有保持连接的时间,有跟后端建立连接的超时间,有跟后端连接后等待后端响应的时间,有后端向nginx发送数据的超时时间。

后端:

​ sql的优化, 使用索引等

​ 多线程执行sql,然后合并数据

​ 写入xlsx的工具的效率。

实操

java后端:

创建一个callable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ProfitTransProfitCallable implements Callable<List<TransProfitPo>> {

private TransProfitPo transProfitPo;

public ProfitTransProfitCallable(TransProfitPo transProfitPo) {
this.transProfitPo = transProfitPo;
}

@Override
public List<TransProfitPo> call() throws Exception {
logger.info("执行{}, {}", transProfitPo.getBeginTime(), transProfitPo.getEndTime());
return iProfitManaService.getTransProfitPoList(transProfitPo, true);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// 15天
ExecutorService executorService = new ThreadPoolExecutor(24,
24,
30L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(360));

Date beginTime = transProfitPo.getBeginTime();
DateTime beginDate = new DateTime(transProfitPo.getBeginTime());
DateTime endDate = new DateTime(transProfitPo.getEndTime());
List<Callable<List<TransProfitPo>>> tasks = new ArrayList<>();
List<Map<String, Date>> list = new ArrayList<>();
while (beginDate.isBefore(endDate)) {
Map<String, Date> map = new HashMap<>();
map.put("startDate", beginDate.toDate());
beginDate = beginDate.plusHours(1);
map.put("endDate", beginDate.toDate());
list.add(map);

if (list.size() > 360) {
throw new ServiceException("查询时间间隔过大");
}
}

for (Map<String, Date> item : list) {
TransProfitPo part = new TransProfitPo();
BeanUtils.copyProperties(transProfitPo, part);
part.setBeginTime(item.get("startDate"));
part.setEndTime(item.get("endDate"));
Callable callable = new ProfitTransProfitCallable(part);
tasks.add(MDCUtil.wrap(callable, MDC.getCopyOfContextMap()));
}

List<TransProfitPo> transProfitPoList = new ArrayList<>();
try {
List<Future<List<TransProfitPo>>> futures = executorService.invokeAll(tasks);
if (futures != null && futures.size() > 0) {
// 迭代结果
for (Future<List<TransProfitPo>> future : futures) {
transProfitPoList.addAll(future.get());
}
}
} catch (Exception e) {
throw new ServiceException("导出错误");
} finally {
// 关闭线程池
executorService.shutdown();
}

long startTime = System.currentTimeMillis();
logger.info("交易分润列表导出开始");
ExcelUtil<TransProfitPo> excelUtil = new ExcelUtil<>(TransProfitPo.class);
String dateToStr = DateUtils.parseDateToStr("yyyy-MM-dd", beginTime);
AjaxResult result = excelUtil.exportExcel(transProfitPoList,"交易分润"+dateToStr);
logger.info("交易分润列表导出结束{}", System.currentTimeMillis() - startTime);
return result;

这里是按时间,一小时一小时的查数据,然后合并数据,生成xslx文件

nginx配置:

只设置单个接口,不影响其他接口的响应超时。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
location /prod-api/backstage/profit/exportTransProfitPoList {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://trans-core/backstage/profit/exportTransProfitPoList;
# 设置连接的超时时间
keepalive_timeout 300;
# 跟后端建立连接的超时时间
proxy_connect_timeout 300;
# 等后端响应的超时时间
proxy_read_timeout 300;
# 后端数据回传超时时间
proxy_send_timeout 300;
}


20万数据导出
http://hanqichuan.com/2022/04/19/java/20万数据导出/
作者
韩启川
发布于
2022年4月19日
许可协议