Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rpc中传递错误的实践 #66

Open
Petelin opened this issue Jul 19, 2021 · 0 comments
Open

rpc中传递错误的实践 #66

Petelin opened this issue Jul 19, 2021 · 0 comments

Comments

@Petelin
Copy link
Owner

Petelin commented Jul 19, 2021

在业务开发中,错误码是一个高频使用的,极其重要的,但却往往被忽略。 不做系统规划和设计的错误码会使得稍后的监控,告警,重试,业务处理都变的及其复杂,甚至做不到。

rpc错误

错误至少要分成这么两类

  • 系统错误:ServiceUnavailable
    • 框架错误,比如序列化
    • mesh错误,超时,鉴权
  • 业务错误
    • 业务正常错误(余额不足) FundNotEnough ...(业务自己添加)
    • 业务非预期错误(下游非预期失败)ServiceInternalError

一个很重要的区别:

  • ServiceUnavailable 用来描述请求还没有触及到服务端业务代码时发生了错误。这个需要有具体的原因,但是业务往往不需要特殊处理,遇到了就重试即可。

  • ServiceInternalError 用来描述请求到了server的用户代码,但是处理过程中出现了非预期错误(比如下游非预期崩溃,自己也不能处理)

一种实现方式时,rpc client侧和server侧都引入一个err middleware pkg,比如直播用的werror code.byted.org/webcast/werror

错误从server到client段的流程

  1. server用户代码返回 return werror.RequestInvalid.WithCustomMessage("你这个请求不合法,因为xxx")
  2. kitex的中间件发现是werror,把RequestInvalid的唯一code,4001018放到resp.BaseResp.Code
  3. 通过网络传输resp到client
  4. client middleware解析到4001018,通过werror.GetErrorFromStatus(4001018) (本地+网络动态更新+反射)返回一个werror给调用方
  5. 调用方可以通过werror.RequestInvalid.Is(err)来判断,也可以用
    switch err: case werror.RequestInvalid:的方式来批量判断

下面是非业务错误

  1. 请求在网络中失败,或者到服务器但是没有被用户代码处理
  2. client middleware解析到普通的errorkite error 或者http eerror) 统一使用werror.ServiceUnavailable.WithError(err)来封装这个错误
  3. 调用方发现是·ServiceUnavailable·就可以判定是服务不稳定了
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant