美文网首页码农的世界『互联网架构』IT@程序员猿媛
『互联网架构』软件架构-java日志异常(18)

『互联网架构』软件架构-java日志异常(18)

作者: IT人故事会 | 来源:发表于2019-02-28 22:42 被阅读5次

    原创文章,欢迎转载。转载请注明:转载自IT人故事会,谢谢!
    原文链接地址:『互联网架构』软件架构-java日志异常(18)

    上次说了日志,不知道老铁遇见过没有,日志打印了一大堆,真的去找导致异常和错误的一条没有。出现这个问题的根本原因是什么?就是因为系统没有一个规范的统一的异常规范。有的老铁发现异常后,直接e.printStackTrace() 打印出来堆栈就结束了,其实这样是很危险的。如果前期对异常没有统一的处理,后期在进行统一和调整真心非常非常的困难,异常跟我们的业务逻辑耦合的非常深的。调整统一过来非常非常的难。所以在设计系统的刚开始就必须设计的完善。如果对刚开始的系统异常和业务异常没有规范化,就算后期分布式进行监控的时候也是很困难的,监控系统无法知道是系统异常还是业务异常。无法准确的通知开发人员和运维人员。报警都不知道怎么报警,例如:一个密码输出错误的可能就引发报警,这样的结果是什么?报警量特别特别的大。如果不报警,到时候真出问题了,就玩完了。是不是 进退两难,说也不是,不说也不是。

    场景回顾

    • 老铁你遇到过不?

    是不是总结的很经典。反正都不是我的锅,大家都是成年人了。

    出现异常我们该怎么办

    其实反映了问题,如果用户存在问题,只要提示明确,用户都不会反映到电话客服那里。如果还需要用户来反馈,说明系统异常设计的都不合理,我们监控系统没有做到位,用户都知道这个问题了,我们系统还不知道。监控系统需要做到的就是在用户反馈之前先知道。如果异常定义的很棒很坚挺的话,看到提示都知道问题出在哪里了!目前很多系统要定位一个问题需要花很长的时间。才能定位到哪里出的问题。现在咱们就搞明白,到底哪里发生了问题,达到一个目标,快速的响应,快速的知道,对应的问题,定位到问题的根本原因,对方传错了,有明确的指示。不应该把他带到线上,带上生产环境下,应该在上线之前就应该抹杀掉。

    系统异常设计的出发点

    1. 良好的异常信息提示,开发运维人员能快速定位
    2. 响应外部调用异常时,应能明确指明是内部异常还是调用条件不满足导至。
    3. 响应用户操作异常时,能友好的提示用户。

    异常分类

    内部异常

    响应没办法按照用户期待的结果返回。

    • 资源环境导致(系统环境异常、数据库连接超时、第三方服务响应超时)
    • 第三方服务错误响应

    已经调入到第三方系统上去了,第三方的系统本身软件有bug,导致的

    • 第三方响应结果错误

    按照约定返回1和0,结果返回了-1。

    • 外部传入参数非法

    别人调用自身的系统,明确的告诉它参数传递错误。

    • 错误的编码逻辑

    调用参数,本来传递1-10,结果你传递了11。

    • 错误的配置

    上线代码链接的是测试数据库

    • 异常的业务数据(业务数据缺失)

    代码传递错误,custId 和 userId写反了。

    业务异常

    用户操作错误导致的,比如:密码错误。

    • 用户操作错误

    捕获异常。

    • 业务条件不满足

    业务的时候提前规范。

    系统中正确的捕获这类异常,并抛出

    1.方法入参进行合法性验证

    • 对系统外部提供的接口(调用后立马验证,不要走了一段逻辑在进行验证),是必须要进行参数验证(必须)
    • 系统内部对外外层提供接口,进行验证
    • 工具类进行参数验证
    • public 方法要进行验证
    • private 方法(不建议参数验证)

    2.第三方响应结果合法性验证

    • 获取第三方法结果后,根据你们的约定进行验证

    3.业务处理前,对业务业务前置条件进行验证

    • 业务处理前,验证业务条件(验证佘额、验证这个帐户有没有被公安门锁定)
    • 要考虑性能成本(验证身份证号码是不是存在的)

    4.业务处理后,对处理结果进行验证

    • 验证对方帐户是不是到帐了,转出帐户是不是成功扣款

    5.对于可能会出现异常的代码进行 try catch 捕获

    • 尝试恢复处理
    • 直接抛出
    • 转换后抛出

    系统出口统一拦截处理

    统一拦截的目的是确定出去的异常是可控的,调用方能够明白异常的信息,这里出口是指系统对外统一响应逻辑,一般我们可分三类场景。

    1. Web Response

    h5,pc页面

    • 内部异常

    引导至异常提示页

    • 业务异常

    返回对应提示消息至前端

    • 未知异常

    尝试进行识别,如果识别不了,转换成异常编码

    2. Http API接口响应

    • 内部异常

    返回接口不可用消息

    • 参数错误

    基于API文档中的异常列表进行响应返回。表明参数非法,需要调用方法加强参数合法性校验

    • 业务错误

    基于非约定返回对应code与消息

    3. RPC Service接口响应

    • 内部异常

    返回服务不可用消息

    • 参数错误

    基于接口文档进行响应,直接返回异常堆栈

    • 业务错误

    直接返回异常堆栈

    checkedException 与uncheckedException 声明原则

      1. 如果是参数非法抛出,返回结果非法(即软件BUG) uncheckedException
      1. 如果你认为调用方程序员需要有意识地采取措施,那么抛出检查型异常。
      1. 程序产品有明确的条件约束的要求,可声明检测型业务异常

    统一对异常进行分类处理

    • 异常转换
    • 异常信息处理
    • 逻辑断言
    • 参数合法性验证
    • 返回结果合法性验证

    异常捕获

    统一对异常进行拦截处理

    • 目的:防止不明确的异常流出系统
    • RPC Service 响应拦截
    • Web Control 响应拦截
    • Http API 响应拦截

    常见的错误的异常处理方式

    • 直接勿略异常
    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 { 
    }
    
    
    • 给每个异常处理都定义一个Code,用一个统一异常替代所有业务异常
    public class ServiceException extends RuntimeException { 
    
    public ServiceException(Exception e) { 
      super(e); 
    } 
    
    public ServiceException(String message) { 
      super(message); 
    } 
    } 
    
    
    

    错误:
    1 、必须明确定义业务异常
    2、 尽可能申明成checkedException 3要带上具体的业务数
    正确方式:定义明确的业务异常

    PS:健壮的系统异常的判断尤为重要,不要认为开发完成就完成了,其实在开发过程中,就像装修一样『前门』很光鲜,『后门』也得控制好。万一别人没从『前门』进来,要求让带个钥匙进门,结果拿个斧子进『后门』呢?

    相关文章

      网友评论

        本文标题:『互联网架构』软件架构-java日志异常(18)

        本文链接:https://www.haomeiwen.com/subject/wvynkqtx.html