记一次第三方数据库性能瓶颈优化方案

首先用一张图说明一下各个系统直接的调用关系

系统详细说明如下

系统A:框架使用springboot开发,对外提供http接口,数据通过RPC(这里指HSF,以下统一用HSF)调用系统B

系统B:框架使用springboot开发,对外暴露HSF接口,数据通过HSF访问系统C获取

系统C:框架不明,对外支持HSF调用,最终获取DB数据返回

问题描述

用户访问系统A中的一个订单下载功能,数据大概在600条左右,在系统A中原方式是通过分页查询(每次查询10条)查询60多次数据库在用户端出现的问题如下图

当时首先想到的问题是增加服务器的连接时间(连接时间改为3分钟),优化查询(每次改为查询50条)

然而改完之后速度提升不是很明显,而且还出现新的问题

1、超时问题依旧存在

2、有时文件可以下载,但是数据不全,有时少50条,有时少150条

出现这种情况的解决方案是在系统中加入大量的日志排查原因,最终发现系统A在访问系统B获取的分页数据,有时候有数据,有时候又没有数据,只能在系统B中继续跟踪日志排查,发现系统B在访问系统C时有超时情况,当超时时系统返回的空数据。

系统C属于第三方的系统,我们无法在其中做出优化,虽然系统C的负责人声称DB已经做了优化,性能较原来有十倍提升(反正我是不信的)

所有到目前为止该下载功能还存在两个问题

1、系统调用时间过长

2、系统可能数据不全

由于系统C没有优化空间,对于这两个问题我们分别给出了优化方案

方案一:使用多线程同时对分页进行数据查询

方案二:使用重试机制保证数据的完整(目前最多重试三次),当然这也没法完全保证数据完整,但也不能无限去重试,否则又会导致tomcat或者nginx连接超时

虽然这不是完整方案,但也是目前情况下给出的可以实施的方案了,具体实现代码如下

多线程并行使用的是java8提供的IntStream类实现,在系统A中实现

long start = System.currentTimeMillis();     
final List<OrderVo> synchronizedResult =Collections.synchronizedList(Lists.newArrayList());       
int totalPages = "获取总页码数";
IntStream.range(2, totalPages+1).parallel().forEach(i->{
	orderQueryParam.setPageIndex(i);
	PageableList<OrderVo> subResult = queryPage(orderQueryParam);
	if (CollectionUtils.isNotEmpty(subResult.getList())) {
		synchronizedResult.addAll(subResult.getList());
	}
});
log.info("queryPage result use {}ms", System.currentTimeMillis()-start);

查询数据重试代码在系统B中实现,代码如下

//传入isRetry控制查询是否需要重试:DEFAULT_RETRY=3
int retry =isRetry ? DEFAULT_RETRY : 1;
PagerList<Order> pagerList =null;
while(retry-->0) {
	try {
		pagerList = systemCService.listOrders(params);
		if(pagerList != null && CollectionUtils.isNotEmpty(pagerList.getDatas())) {
			break;
		}
	}catch(Exception e) {
		log.error("queryPage error :",e);
	}
}

ok,代码设计完成,在预发测试,测试结果:600多条数据用时30多秒(优化前nginx设置3分钟依旧超时),数据与查询出来的数据条数一致,问题算是解决。

但这种方案又有新的问题产生

1、使用多线程访问系统C是否有风险,系统C是否会出现压力过大导致系统宕机等问题

2、多线程异步查询出的数据和在页面看到的数据顺序不一致

对于这两个问题暂时先保留,后续继续给出方案吧

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值