上次说了日志,不知道老铁遇见过没有,日志打印了一大堆,真的去找导致异常和错误的一条没有。出现这个问题的根本原因是什么?就是因为系统没有一个规范的统一的异常规范。有的老铁发现异常后,直接e.printStackTrace() 打印出来堆栈就结束了,其实这样是很危险的。如果前期对异常没有统一的处理,后期在进行统一和调整真心非常非常的困难,异常跟我们的业务逻辑耦合的非常深的。调整统一过来非常非常的难。所以在设计系统的刚开始就必须设计的完善。如果对刚开始的系统异常和业务异常没有规范化,就算后期分布式进行监控的时候也是很困难的,监控系统无法知道是系统异常还是业务异常。无法准确的通知开发人员和运维人员。报警都不知道怎么报警,例如:一个密码输出错误的可能就引发报警,这样的结果是什么?报警量特别特别的大。如果不报警,到时候真出问题了,就玩完了。是不是 进退两难,说也不是,不说也不是。
是不是总结的很经典。反正都不是我的锅,大家都是成年人了。
其实反映了问题,如果用户存在问题,只要提示明确,用户都不会反映到电话客服那里。如果还需要用户来反馈,说明系统异常设计的都不合理,我们监控系统没有做到位,用户都知道这个问题了,我们系统还不知道。监控系统需要做到的就是在用户反馈之前先知道。如果异常定义的很棒很坚挺的话,看到提示都知道问题出在哪里了!目前很多系统要定位一个问题需要花很长的时间。才能定位到哪里出的问题。现在咱们就搞明白,到底哪里发生了问题,达到一个目标,快速的响应,快速的知道,对应的问题,定位到问题的根本原因,对方传错了,有明确的指示。不应该把他带到线上,带上生产环境下,应该在上线之前就应该抹杀掉。
响应没办法按照用户期待的结果返回。
别人调用自身的系统,明确的告诉它参数传递错误。
用户操作错误导致的,比如:密码错误。
统一拦截的目的是确定出去的异常是可控的,调用方能够明白异常的信息,这里出口是指系统对外统一响应逻辑,一般我们可分三类场景。 1. Web Response h5,pc页面
返回接口不可用消息
基于API文档中的异常列表进行响应返回。表明参数非法,需要调用方法加强参数合法性校验
基于非约定返回对应code与消息
返回服务不可用消息
基于接口文档进行响应,直接返回异常堆栈
直接返回异常堆栈
统一对异常进行拦截处理
try { new String(source.getBytes("UTF-8"), "GBK"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); }
try { new String(source.getBytes("UTF-8"), "GBK"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("环境不支持UTF-8",e) }
public class DuplicateUsernameException extends Exception { }
public class ServiceException extends RuntimeException {
public ServiceException(Exception e) { super(e); }
public ServiceException(String message) { super(message); } }
错误: 1 、必须明确定义业务异常 2、 尽可能申明成checkedException 3要带上具体的业务数 正确方式:定义明确的业务异常
PS:健壮的系统异常的判断尤为重要,不要认为开发完成就完成了,其实在开发过程中,就像装修一样『前门』很光鲜,『后门』也得控制好。万一别人没从『前门』进来,要求让带个钥匙进门,结果拿个斧子进『后门』呢?