Skip to content

qJerry/Code-Box

Repository files navigation

Code-Box

Code-Box, born for error codes.

背景

在业务开发中,经常会出现以下现象:

  • xxx失败了,帮忙看看什么问题
  • 怎么会出现这个错误
  • 这个提示不友好,得改
  • 错误信息,该前端处理,后端处理,还是中台处理?
  • 多个服务之间错误码一致,错误内容不一致
  • 。。。


基于以上,我就下定决心,想做一款错误码系统,解决以上问题。这个系统,我称它为Code-Box 码盒。

什么是错误码?

错误码,对于很多人而言就是一串数字,它关联了系统上的各种错误信息。

错误码带给我们的作用是什么?

  • 告知我们哪个系统哪个模块出了问题;
  • 告知我们具体是什么问题;
  • 通过决策和话术转换回显合理的错误内容给用户。

错误码服务的人群

  • 对于服务间的调用,即针对技术人员


image.png

  • 对于客户端的调用,即针对非技术人员


image.png

错误码类型

image.png

错误码设计

错误码设计原则是,尽可能做到简洁。故我将错误码分成两部分:系统码(前4位)+错误码(后4位)
系统码和错误码区间区间 需通过后台申请。
image.png
由于要区分错误码类型,我定义了指定的区间进行分配,剩下未分配的区间,待后续动态扩展

例如,我所在部门假设会有50个项目来开发,那么我可以申请区间为00010000-00500000的错误码。当然后续由于业务扩展,又增加了新的项目,亦可以重新申请新的错误码区间!

领域模型

我考虑了两种场景,对内错误码API和开放错误码API。
基础的模型有:运营后台、错误码系统、错误码服务

对内错误码

贯彻“错误码无侵入”的理念,对内设计的领域模型,主要有业务系统—>错误码SDK<—>错误码内部API

开放错误码

我们仅需要将错误码API接口开放即可,并 提供一套错误码API文档
image.png

数据库设计

image.png

项目架构

码盒项目基于Springboot + Spring cloud + Mysql搭建而成,项目架构比较简单。
image.png

运营后台

  • 创建业务部门、业务系统
  • 申请端口、系统码、错误码区间
  • 修改错误码信息、及其错误描述
  • 售后排查功能

错误码服务

  • 内部错误码API接口
  • 外部错误码API接口
  • 错误码文档可视化

错误码提取

支持在编译期间,从业务中自动提取出错误码内容

错误码SDK

接入业务系统,通过配置中心配置,开启错误码同步及检测功能,并支持开启周期性更新错误码,错误日志同步...

错误码话术转换

待定。。。


业务流程

image.png
从上图看出,我这里区分了4个角色:项目负责人、产品、技术、用户

负责人

这是接入码盒的第一步

  • 创建业务部门:根据部门信息,对应创建一条部门记录
  • 创建业务系统:根据系统信息,对应创建一条系统记录,并自动生成一个系统码,4位组成
  • 申请配置:这里不仅可以申请错误码区间,还可以申请域名,端口等,这样可以协同管理跨部门的信息


当申请配置成功后,即可进行下一步

技术线

引进码盒SDK即可,但是配置方式有以下几种

配置错误码文件

这是最简单的一种接入方式。技术人员在具体的业务项目中引入码箱SDK,并在资源文件下定义code.json,内容参考如下

[
  {
    "code": 101,
    "message": "参数有误",
    "detail": "请检查入参:必填参数是否为空,长度超出规定限制长度 或 是否不符合格式"
  },
  {
    "code": 102,
    "message": "系统繁忙",
    "detail": "可能发生了网络或者系统异常,导致无法判定准确的转账结果。此时,商户不能直接当做转账成功或者失败处理,可以考虑采用相同的out_biz_no重发请求,或者通过调用“(alipay.fund.trans.order.query)”来查询该笔转账订单的最终状态"
  },
  {
    "code": 103,
    "message": "根据监管部门的要求,请补全您的身份信息解除限制",
    "detail": "根据监管部门的要求,请补全您的身份信息解除限制"
  }
]

配置注解

常见的项目,会将错误码定义在枚举类中,增加了可读性,以及便于迭代。
这里针对此业务错误码枚举类,增加了自定义注解 @CodeBoxData 的支持,如下。当然有些项目错误码多,需要按业务进行区分,即有多个枚举类,也一样在每个枚举类上添加 @CodeBoxData 注解。

配置注解的目的,也是为了生成错误码信息到资源文件下的code.json文件中。
至于怎么生成,这里主要借鉴了lombok、mapstruct等的思路,它们基于注解处理器,给我们提供了很多丰富的功能。
在编译期间,码盒的注解处理器将会将枚举类的内容动态添加到code.json。接着等项目启动,SDK将会将生成的错误码同步到码盒系统。

产品线

码盒提供了针对产品经理的一个解决方案,在公司产品经理和开发人员经常有这样几个苦恼:

  1. 开发人员定义的错误信息太技术,导致涌出部分售后问题,引发产品不满:“这不是我设计的!”;
  2. 修改错误信息,必须改代码,重新发布,引发开发人员不满:“又来!”;
  3. 错误信息应该从哪里处理,前端?后端?中台?,引发开发人员疑惑:“是你,是你,还是你?”;


以上问题,在码盒上统统解决,当发现错误信息会带来售后问题而需要优化时,仅需要在码盒后台修改即可!

业务接入

前提

业务项目基于Springboot + Spring cloud 框架

下载码盒项目

https://github.com/qJerry/Code-Box

执行数据库脚本(MYSQL)

image.png

更改码盒内部API配置文件

数据库配置、端口配置、注册中心配置

spring:
  datasource:
    hikari:
      username: root
      password: 123456
    url: jdbc:mysql://localhost:3306/code_box?characterEncoding=utf-8&serverTimezone=GMT%2B8

server:
  port: 8501

eureka:
  client:
    service-url:
      defaultZone: http://localhost:1002/eureka/

引入SDK

<dependencies>
  <dependency>
    <groupId>com.github.qJerry</groupId>
    <artifactId>CodeBox-Sdk</artifactId>
    <version>1.0-SNAPSHOT</version>
  </dependency>
</dependencies>

添加自定义注解@CodeBoxData

在错误码枚举类上添加自定义注解,枚举类的参数参考如下。

注意:如上所说,错误码分为系统码(前4位)+错误码(后4位),在业务项目上,错误码无需考虑系统码,故在定义上只要定义后4位即可。

@Getter
@CodeBoxData
public enum BusinessCodeEnum {

    // 设备:1000-1999
    EQUIPMENT_NOT_EXIST(1000, "设备不存在", ""),
    
    // 用户:2000-2499
    USER_LOGIN_AGAIN(2000, "请重新登录", "当前缓存信息已过期,需要重新登录");

    Integer code;
    String message;
    String detail;

    BusinessCodeEnum(Integer code, String message, String detail) {
        this.code = code;
        this.message = message;
        this.detail = detail;
    }
}

业务项目配置文件添加码盒配置

code:
  business:
    id: 1	// 业务部门id
    system:
      id: 1	// 业务系统id
  refresh:
    open: false	// 是否开启周期性任务
    cron: 0 0/5 * * * ?	// 调度周期
  sync-log: true // 是否同步错误日志

实际使用

在每个需要用到错误码的地方,直接调用SDK的 ResultVO.err() 输入具体的错误码即可,如下

public ResultVO getCode(String name) {
  if(Strings.isNullOrEmpty(name) || ! name.equals("Jerry")) {
  	return ResultVO.err(10101L);
	}
	return ResultVO.suc();
}

当然,SDK也内置了全局异常处理器CodeBoxGlobalException,直接传入错误码即可。

throw new CodeBoxGlobalException(code);

框架特色

99%无侵入

为了尽可能做到不侵入业务代码,我制作了一个SDK,并添加了自定义注解或者直接配置文件的形式进行接入

自定义注解处理器

支持对于在业务错误码枚举类上添加了自定义注解的类,将在编译期间,将其拉取到资源文件下的code.json中,业务技术方无需手写code.json文件,只需添加注解,即可快速完成接入的一大步。

动态字节码技术(对外透明化)

内部封装了一个错误码工具类,使用了ASM动态字节码功能,在项目启动期间和周期性刷新错误码期间,将会动态添加或更新错误码到SDK的错误码枚举类中,对外透明化,业务仅需提供一个错误码作为入参,即可获取详细的错误码内容。
出发点:
可能有些人包括我一开始会直接使用redis缓存来存放错误码信息。但从实际使用上看,错误码更多的是静态数据,一般不会去频繁改动,这时候放置于缓存就有点浪费资源了。故我在做自定义注解处理器的时候,就想到了使用动态字节码技术,在运行期间放置或修改错误码信息。

周期性刷新错误码

当在后台修改对应的错误码信息后,若开启了周期性刷新,则会定时同步最新数据到本地~~

个性化配置

可以配置是否要同步错误码日志到平台、配置接入码盒的方式、配置是否要定时更新后台同步的错误码信息等等

日志排查功能

当配置了同步错误码日志到平台后,即可在后台查看具体的错误信息,并给出具体的解决方案。

错误日志导出



项目状况

已完成事项

已完成码盒服务、码盒SDK的开发

未完成事项

运营后台相关功能。

github地址

https://github.com/qJerry/Code-Box

About

Code-Box, born for error codes.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published