作者:十眠
为什么有了无损下线,还需要无损上线?无损上线可以解决哪些问题?
本篇文章将一一回答这些问题。
无损上线功能不得不说是一个客户打磨出来的功能
我们将从一次发布问题的排查与解决的过程说起。
阿里云内部某应用中心服务在发布过程中出现了大量的 5xx 超时异常。初步怀疑是无损下线问题,于是很快便接入了 MSE 提供的无损下线功能。但是接入无损下线功能后继续发布,应用的发布过程依然存在大量的超时报错。根据业务方同学的反馈,大概应用在启动后 5 秒左右,会有大量超时请求。
于是拉了相关的同学开始排查。应用的调用情况如下:gateway - > A -> C 。

发布的应用为 C 应用,发布过程中出现大量超时报错。我们通过相关日志与应用的启动情况,整理如下线索:
第一阶段:xxx.xxx.xxx.60 (C 应用)下线阶段
第二阶段:xxx.xxx.xxx.60 (C 应用)上线阶段
同时搜 C 应用的机器 XXX.XXX.XXX.60 的报错相关的日志,共 237 条日志
其中最早的 time: 2020-07-30 20:29:26,524
其中最晚的 time: 2020-07-30 20:29:59,788
观察这些迹象可以初步得出结论:
这时候怀疑是上线期间的问题,同时排查服务端相关日志,发在报错期间,服务端线程被打满:

问题定位为上线过程中的问题,与无损下线无关。
我们帮助用户解决问题的思路:帮助用户发现问题的本质、找到问题的通用性、解决问题、将解决通用问题的能力产品化。
发现用户 Dubbo 版本比较低,缺少自动打线程堆栈的能力:
这是每次发布必现的问题,通过观察线程池满时的 JStack 日志,有助于我们定位问题。
初步观察 JStack 日志,发现不少线程阻塞在 taril/druid 等异步连接资源准备上:

同时我们云上也有有客户遇到过,应用启动后一段时间内 Dubbo 线程池满的问题,后经过排查由于 Redis 连接池中的连接未提前建立,流量进来后大量线程阻塞在 Redis 连接建立上。
连接池通过异步线程保持连接数量