1、概述
本次课程主要介绍的内容如下:
- Java异常体系
- 异常处理
- 日志规约
- 错误码规约
- 异常与日志综合实践
2、Java异常体系
2.1 Java异常处理流程
- finally里发生的异常如何正确捕获和处理?
- finally里发生了异常,没有捕获处理,也没有处理原异常,jvm会怎么处理2个异常呢?
2.2 Java异常处理机制
try代码块中抛出多种异常该怎么处理?
- 加多个catch捕获所有可能的异常进行处理,每种异常处理流程不一致时采用这种
- 分析多个异常是不是某一类子异常,并且后续处理办法是一致的,可以只抛出父类异常
- Error 一般跟java虚拟机有关,比较致命的错误,如系统崩溃,虚拟机出错误等,通常应用程序无法处理的,Error也是不可检查的
- 运行时异常 是RuntimeException类及其子类异常,例如空指针异常,数组越界异常,除0异常等等,这类异常是不可检查的(编译器无法预计你写的程序逻辑有没有错误),程序可选择捕获或不捕获处理,一般都是由于程序逻辑错误引起的,用户也可以自定义可预测的业务运行时异常
- 非运行时异常 是RuntimeException以外的异常,如IOException、SQLException以及用户自定义异常等,这类异常是可检查的(可预计会发生的异常,而一旦发生就必须捕获处理的),编译器会检查它,要求必须catch,否则不可编译通过
异常处理有一条强制规约:在调用rpc或者二方包,或者动态生成类相关方法时,捕获异常必须使用Throwable,因为有可能抛出Error或者Exception
2.3 异常处理设计与实践
• 异常抛出与捕获的原则
• Java异常体系之try...catch...finally流程解析
- 强制规约:不要在finally里写return语句 try里的return不是立即返回结果,而是先放函数栈中,待finally语句块执行完后才返回,如果finally里有赋值给返回值变量,并且有return,则会忽略try里的返回值,如果没有return,则即使有赋值语句,也不会忽略try返回值
• JDK7资源关闭新姿势之try with resource流程解析
• 特殊异常NPE场景及其处理对策异常抛出与捕获的原则
3、日志规约
3.1 日志的功能
3.2 日志时效规约
- 记录用户敏感信息或操作日志为何要至少存储6个月,并多机备份?用什么级别日志输出?
- 相关法律规定的,有一些金融方面要求保存可以更长,这是监管检查的原因;还有当发生一些纠纷的时候,可以拿出比较长时间的有效数据进行检查,作为证据,打官司等等处理;联机存储是为了防止丢失,人为损坏数据等原因;最好使用warn级别
3.3 日志记录规约
- 系统应依赖使用日志框架(SLF4J,JCL)的API而不是具体日志库的
- Slf4j绑定到各种日志库的流程
- 在日志输出时,字符串变量之间的拼接方式使用占位符方式
- 日志打印时禁止直接使用JSON工具将对象转换成String
- 尽量用英文来描述日志错误信息 - 推荐
3.4 logback框架使用
- 核心配置对象及其属性分类
-关键类图分析
- 线程模型分析
3.5 日志通知
3.6 日志输出规约
3.7 扩展日志规约日志
4、错误码规约
4.1 错误码规约
5、异常处理与日志综合实践
- 在Controller层统一捕获异常
- 不是每一层都处理,都是往上层抛出,一般需要对异常信息,日志进行包装处理在抛出去
- 在分布式部署多台机器时,异常日志则需要每层单独记录的,便于追溯来源和链路跟踪
- 全局异常处理组件GlobalExceptionHandler的定义和使用
- API层异常设计实践
- Service层异常设计实践
- DAO数据处理层异常、日志实践
- 使用MDC实现轻量级调用链路追踪
7.用有限的异常类处理业务中复杂多变的无限可能
- 降低系统的维护难度,过度设计,冗余手段