trpc.group/trpc-go/trpc-go@v1.0.3/healthcheck/README.zh_CN.md (about) 1 [English](README.md) | 中文 2 3 ## 前言 4 5 进程启动并不代码服务已经初始化完成,比如需要在启动时进行热加载的服务。 6 长时间运行的服务,最终可能进入不一致状态,无法对外正常提供服务,除非重启。 7 类似于 K8s [readiness](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes) 和 [liveness](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-a-liveness-http-request),tRPC 也提供了服务的健康检查功能。 8 9 ## 快速上手 10 11 tRPC-Go 的健康检查内置于 `admin` 模块;需在 `trpc_go.yaml` 中开启: 12 ```yaml 13 server: 14 admin: 15 port: 11014 16 ``` 17 就可以通过 `curl "http://localhost:11014/is_healthy/"` 来判断服务的状态。HTTP 状态码与服务状态的对应关系如下: 18 19 | HTTP 状态码 | 服务状态 | 20 | :-: | :-: | 21 | `200` | 健康 | 22 | `404` | 未知 | 23 | `503` | 不健康 | 24 25 ## 详细介绍 26 27 「快速上手」一节,我们认为只要 admin 的 `/is_healthy/` 调通,整个服务就是健康的,用户不用关心 server 下面有哪些 service,这适用于大部分默认场景。 28 对于需要设置特定 service 状态的场景,我们在代码层面提供了 API: 29 ```go 30 // trpc.go 31 // GetAdminService gets admin service from server.Server. 32 func GetAdminService(s *server.Server) (*admin.TrpcAdminServer, error) 33 34 // admin/admin.go 35 // RegisterHealthCheck registers a new service and return two functions, one for unregistering the service and one for 36 // updating the status of the service. 37 func (s *TrpcAdminServer) RegisterHealthCheck(serviceName string) (unregister func(), update func(healthcheck.Status), err error) 38 ``` 39 比如,在下面的例子中, 40 ```go 41 func main() { 42 s := trpc.NewServer() 43 admin, err := trpc.GetAdminService(s) 44 if err != nil { panic(err) } 45 46 unregisterXxx, updateXxx, err := admin.RegisterHealthCheck("Xxx") 47 if err != nil { panic(err) } 48 _, updateYyy, err := admin.RegisterHealthCheck("Yyy") 49 if err != nil { panic(err) } 50 51 // 当你不再关心 Xxx,希望它不影响整个 server 的状态时,可以调用 unregisterXxx 52 // 在 Xxx/Yyy 的实现中,通过调用 updateXxx/updateYyy 更新它们的健康状态 53 pb.RegisterXxxService(s, newXxxImpl(unregisterXxx, updateXxx)) 54 pb.RegisterYyyService(s, newYyyImpl(updateYyy)) 55 pb.RegisterZzzService(s, newZzzImpl()) // 我们不关心 Zzz 56 57 log.Info(s.serve()) 58 } 59 ``` 60 用户有三个 service,但只为 `Xxx` 和 `Yyy` 注册了健康检查。这时用户可以单独获取 service `Xxx` 的状态,通过在 url 后追加 `Xxx` 即可:`curl "http://localhost:11014/is_healthy/Xxx"`。对于未注册的 service `Zzz`,其 HTTP 状态码为 `404`。 61 62 因为我们为 `Xxx` 和 `Yyy` 注册了健康检查,整个 server 的状态(即 `curl "http://localhost:11014/is_healthy/"`)将由 `Xxx` 和 `Yyy` 共同决定。只有当 `Xxx` 和 `Yyy` 都是 `healthcheck.Serving` 时,server 的 HTTP 状态码才是 `200`。当 `Xxx` 和 `Yyy` 至少有一个是 `healthcheck.Unknown`(这是使用 `admin.RegisterHealthCheck` 注册的 service 的默认初始状态)时,server 的 HTTP 状态码为 `404`。否则,server 的 HTTP 状态码为 `503`。 63 64 简单地说,你只需要记住,只有当所有注册了健康检查的 service 都为 `healthcheck.Serving` 时,整个 server 才是 `200`。 65 66 ## 和北极星心跳上报配合 67 68 [`naming-polarismesh`](https://github.com/trpc-ecosystem/go-naming-polarismesh) 的心跳上报可以和健康检查配合。 69 70 对于未显式注册健康检查的 service,其心跳会在 server 启动后立刻开始,和旧版本北极星行为是一致的。 71 72 对于显式注册了健康检查的 service,只有当 service 状态变为 `healthcheck.Serving` 时,才会开始第一次心跳上报。服务运行中,如果 service 状态变为 `healthcheck.NotServing` 或者 `healthcheck.Unknown`,就会停止心跳,直到再次变更为 `healthcheck.Serving` 才恢复(变更的瞬间,会立即发起一次心跳上报)。