记一次对MC取数据时间不敏感Debug过程

故障描述:客户端线上页面偶现白页

Debug 过程流
0、第一反应是部分服务器挂了,很快排除。
1、CURL请求页面数据API,一直有数据。跟端上沟通,端上会有超时出现白页的情况。查接口果然超时。
2、如何处理?第一反应是如何做性能优化,而不是为什么会超时。当然,性能优化前提也是要分析超时原因,即性能瓶颈。【事后来看第一时间问为什么会超时的思维更高效】

3、性能分析优化BEGIN。
为了方便说明,先模拟场景并伪码描述一下主要实现逻辑

// 场景模拟:一个页面中有多个Tab, 每个Tab中有多个模块,每个模块中有多个商品信息。需要把页面中全部商品按价格降序排列。
// 功能描述:获取全部商品并排序
class Test
{
	// 在controller中
	public static function index()
	{
		$tab_ids = [1000, 2000, 3000, 4000, 5000];
		$mod_ids = [];
		foreach ($tab_ids as $tab_id) {
			// 调用获取一个tab下全部模块全部商品方法getSkus();
			$res[] = $this->getSkus();
		}

		// sort
		sortFunction();

		return [];
	}
	
	// 在model中
	public static function getSkus($tab_id)
	{
		// 获取到tab下全部模块$mod_ids
		foreach ($mod_ids as $mod_id) {
			// 取模块信息方法getData();
			调用一次 getData();
			又调用一次 getData();
			do something;
		}

		return 数据;
	}

	// 在data【library】中
	public static function getData($id)
	{
		获取MC中数据
		if (MC数据有效) {
			return MC数据;
		}

		取DB数据
		if (条件)) {
			set DB数据到MC;
		}

		return DB数据;
		
	}
}

3.1、分片打印代码执行时间,很快发现line 10 执行时间很长。然后分析发现getSkus()中调用了两次getData()。
3.2、想了个办法把两次getData()调用合并了。打印执行时间并没有快多少。
3.3、打印line 12中方法执行时间发现差不多都是200ms, 但是到第4次循环就突变成1s多了。
3.4、故障比较紧急,就临时处理了,在index中加了一层1分钟缓存。
3.5、问题暂时解决。性能分析优化END。
4、后来发现line 44从DB取数据后,没有满足写MC的条件,MC缓存是1天,于是知道问题症结是缓存每次都被穿透了。
5、总结:
对MC取数据时间不敏感。单次取MC达到200ms就应该意识到问题了。
解决问题想当然了,一开始没有打印循环内部单次执行的时间。【多几次循环时间开销真的不是想象的那么大】

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注