就在本周排查一个生产环境请求丢失问题的,我私下感觉纯粹就在浪费时间,也只能是私下。问题描述:调用方通过开放平台的接口报了一个null。而且调用方自己打印的有日志,云网关那边也有日志,开放平台也有日志,上游也有日志。开放平台提供的SDK的错误日志用的e.printStackTrace()。
几个人靠对日志去看,同一秒多次请求很正常,而且每个服务器的时间有可能不一样。也没有requestId之类的东西,让你确定是同一个请求。请求到底真正发出去没有,也是个问题。这个时候显得日志很重要,打印好日志很重要,尤其是跨系统排查问题显的更加重要。
解决问题不能靠猜,需要有上下文,别人说的上下文就一定是上下文吗?你确定这个请求就是报错的请求吗?如果不能确定,就先不要猜,也不要出那些所谓的解决方案。
这里再整理系统异常处理的原则和处理规范,应该注意的事项:
- 不要吞掉Exception,不要在业务代码中进行捕获异常, 即 Dao, Manage、Service, Controller 层的所有异常都全部抛出到上层. 这样不会导致业务代码中的一堆 try-catch 导致业务代码混乱。
- 哪一层都不捕获。自个处理完,抛到最外层, 最外层统一捕捉。
- 处理好每一层的异常,返回统一的结果集 ( 错误码 错误描述 )。
- 统一框架层处理。
- 需要封装成自己的业务Exception定义为Runtime类型。
- 任何的报错需要在在返回的header上面标注一个错误代码,方便调用方处理合适的异常,包括抛出合理的业务错误代码。以及记录请求的各种参数。
- 中间件的一些异常,需要带上自己的错误处理, 如果不能完全捕捉。异常处理尽量不要太宽泛。
- 鉴权的异常单独处理。
一个错误描述的基本信息应该包含:
- 编码
- 描述
- 状态
- 来自于那个系统及 系统的那一层,表单验证层or业务逻辑层or数据库层。那个系统可以给每个系统的统一AppKey。
- requestId,尤其是夸系统调用,夸微服务调用的时候显的很重要
- 严重程度:R1、R2、R3等
没有具体的根据去分析问题,找出问题算侥幸。大家都知道记叙文三要素是时间、地点、人物。以及六要素包括时间、地点、人物、(事件的)起因、经过和结果。当出现问题的时候,通过异常处理,把我们需要的关键信息描述清楚这样的异常处理才有价值。好像看似有些系统有异常处理,好像跟没有差别不大。减少技术支持时间,减少排查问题的时间才是好的异常处理。
精进自省:我生来就是高山而非溪流 ,我欲于群峰之巅俯视平庸的沟壑。我生来就是人杰而非草芥,我站在伟人之肩藐视卑微的懦夫。