• 业务系统异常设计


    本文讨论的前提是在捕获了异常的情况下进行的说明。

    1、  直接使用原生异常。直接抛出 Exception 或者 RuntimeException。

      在业务代码层,直接抛出异常信息。这里不限定RuntimeException还是其他。

      好处是,简单方便直接。

      坏处是,部分调用方需要显式的抛出异常,且提示语不方便管理。

    2、  项目包装RuntimeException。

      直接继承RuntimeException,做一些简单的封装,类似如下代码

      开发同学在使用时,直接new一个即可。总共两个构造方法可选,或者直接使用静态方法,生成包含对应detail的异常信息。其中常用的错误码、错误信息,都用一个静态类或者是枚举保存。我猜测大部分信息都采用的这种方式,而且这样的方式也满足一般的管理系统。

      好处是方便,有一定的标准。

      坏处是多个模块的开发者维护同一个枚举容易出现冲突,容易出现一个错误码被多次使用。

    3、  多语言。

      如果公司业务发展较快,明天要进军泰国市场,后天要进军沙特阿拉伯市场,那就得在枚举全部新增一套提示语。虽然这样的改动不难,但没啥技术含量。

      所以我们将保存错误信息的枚举类进行改造,如下图

     

      重写toString方法

     

      这样就会带来问题,因为每次都需要新增加或者维护异常信息,都需要维护枚举类现有的几套语言。

      好处是方便,比较容易管理,支持多语言。

      坏处当然是浪费开发的时间,且一旦出现提示语不对,还需要重新发版,费时费力。

    4、  可配置的异常提示信息。

      那既然现在的痛点是在维护上,我们何不考虑做成可配置?

      以将异常信息放在数据为例,先看两张表。

     

     

      此时,发生异常,若代码抛出异常,必须带上exception_code,异常处理service去包装异常信息,一方面返回异常信息给用户,一方面将异常信息入库。

      以springboot 为例

     

      异常信息的包装策略此处不展开,各位可以自己想想如何包装。

      这里好处就是异常信息可以随时调整,十分灵活,开发进行排查时也能有的放矢,不用去整个日志系统一遍一遍的去搜。

      坏处可能就是写的代码有点多,搞这么复杂一时半会也没啥用。

    5、  分布式系统的异常信息传递。

      这里会与全链路日志追踪有交叉的地方。

      举个栗子,我在手机qq查看联系人性别:

      a)         打开手机qq(开始读取消息)

      b)         打开联系人列表(读取在线状态)

      c)         读取各种群消息(未收到的群消息)

      d)         搜索联系人(本地搜索+服务器搜索)

      e)         点开联系人详情页(获取用户通用基本信息、用户允许查看的隐私信息、用户背景图、qq会员系统、qq等级系统、各种钻、各种特权、头像挂件、个性签名、空间是否更新、最近常听)

      f)          查看用户性别

      而各个请求,可能又会去请求其他系统。

      任何一个系统调用失败,都可能会导致功能出现各种各样的问题。

      所以我们需要在异常信息中,传递一些必要信息,如 唯一请求编号、异常编码、异常机器ip等必要信息。假如调用链路是  S –> M -> Z -> E -> A -> H ,一旦E出现了异常并返回给Z,根据异常里面包含的信息,便能马上定位的机器,开始处理,而不是从链路的最开始一台一台机器去排查。

      最后补一个问题,自定义异常处理了,那非自定义异常该怎么办呢?

  • 相关阅读:
    树莓派开机启动
    树莓派连接18b20测温度
    树莓派VNC
    树莓派python 控制GPIO
    树莓派笔记
    用nohup执行python程序时,print无法输出
    mysql 函数应用
    mysql 正则表达式判断是否数字
    mysql select into 不支持
    tushare
  • 原文地址:https://www.cnblogs.com/brave-rocker/p/12643202.html
Copyright © 2020-2023  润新知