所有内容摘自阿里巴巴的《Java开发手册-嵩山版》
父文章 代码结构-可维护性代码_fei33423的专栏-CSDN博客
根据traceId计算分布式根因
意义:
在分布式环境下,系统越来越复杂,错误码对于问题的快速定位和溯源起着至关重要的作用.
1.给分布式系统开发者监控用 2.给用户提示用,对前端/业务层开发者友好. 3.快速定位根原因哪个系统用
设计原则
* 对外要屏蔽系统和细节
* 对内要快速定位
所以会有两个信息,一个是封装后的错误码(动态映射,对外可整理成文档解释),一个是root错误码
错误五信息
堆栈(stack_trace)、错误信息(error_message)、错误码(error_code)、提示信息(user_tip),系统 是一个有效关联并互相转义的和谐整体,但是请勿互相越俎代庖。 还有一个核心是堆栈的hashCode .结构化核心 结构化异常日志, 如何做好error日志结构化,便于日志监控过滤._个人渣记录仅为自己搜索用的博客-CSDN博客
分布式传递
类似trace结构体, root信息一定要有. (包含三信息,堆栈不对外传递,在本层日志打印)
错误的格式
系统 输入/内部/外部 , 错误码|RootException, 其中输入系统名,外部系统名具体是谁,我们并不关心. 外部分为, 超时,参数错误. 超时多,再下钻分析是自己的机房超时,还是外部系统超时,在具体看某个维度.
输入错误,内部,外部rpc有Exception, rootException就是当前系统.
外部resultCode rootException就是外部系统,有外部的root.
三个Exception:
RpcParamException extends CommonException ; InnerException extends CommonException ; OutException extends CommonException
CommonException extends Exception{
CommonFail fail;
}
/**仅OutException有可能存在rootFail*/
OutException{
CommonFail rootFail;
}
RpcResult{
CommonFail rootFail;
String code;
String msg;
}
CommonFail{
String system;
String code;
String msg;
// 国际化的key
String userTipsKey;
String[] params;
}
错误码的定责/告警
看rootException是自己, 看类型,内部和外部的就可以告警. 再看下面的配置.
小考题? 外部的Exception是否一定要error. 要看rootException.
错误的打印? error Or Warn
不是和异常码强关联,而应该是根据入口api+错误码来确认是否warn or error. 动态配置的. 同一个错误码,在不同的场景下有些可能是业务性的,有些可能是正常的.
案例: 一般出现业务校验失败都是有问题的, 应该主动查询提醒用户,禁止点击. 但往往改造成本较大, 而且从懒惰法的角度来说也是合理的, 故还是需要动态的warn掉.
错误的兼容
传统很多系统都是code和msg两个字段,并不会传递rootException. 也只打印code和msg.
把system信息append到Code中. outException处理时要判断下游是否传递的是system名的rootException信息,如果是则不append. 对外抛仅仅抛root,不是抛本系统的封装异常,如果有必要可以封装掉,但往往封装掉会增加异常定位的时间.
附录
【强制】错误码不能直接输出给用户作为提示信息使用。
说明:堆栈(stack_trace)、错误信息(error_message)、错误码(error_code)、提示信息(user_tip)是一个有效关联并互相转义的和谐整体,但是请勿互相越俎代庖。 错误码在不同的场景中error_message可以是不同的.
【推荐】错误码之外的业务独特信息由 error_message 来承载,而不是让错误码本身涵盖过多具体业务属性。
【推荐】在获取第三方服务错误码时,向上抛出允许本系统转义,由 C 转为 B,并且在错误信息上带上原有的第三方错误码。
【参考】错误码即人性,感性认知 + 口口相传,使用纯数字来进行错误码编排不利于感性记忆和分类。
说明:数字是一个整体,每位数字的地位和含义是相同的。
反例:一个五位数字 12345,第一位是错误等级,第二位是错误来源,345 是编号,人的大脑不会主动地拆开并分辨每位数字的不同含义。