0%

微服务架构模式_健康检查API模式

健康检查API模式

有时服务看上去正在运行,但它却无法处理请求。例如,新启动的服务实例可能尚未准备好接受请求。例如某个服务大约需要10秒钟来初始化消息和数据库适配器。

在它们准备好之前,部署基础设施将HTTP请求路由到服务实例是没有意义的。

此外,服务实例可能会失败却不自动终止。例如某个服务进程已经Hang住了。部署基础设施不应将请求路由到已失败但仍在运行的服务实例。

并且,如果服务实例无法恢复,则部署基础设施必须终止它并创建新实例。

使用健康检查时需要考虑两个问题。

第一个是接口的实现,它必须报告服务实例的健康状况。
第二个问题是如何配置部署基础设施以调用健康检查接口。

实现健康检查接口

实现健康检查接口的代码必须以某种方式确定服务实例的健康状况。

一种简单的方法是验证服务实例是否可以访问其外部基础设施服务。

具体做法取决于具体的基础设施服务,例如可以通过获取数据库连接,并执行测试查询来验证服务是否已连接到数据库。

调用健康检查接口

如果没有人调用它,健康检查接口就没有意义了。

部署服务时,必须配置部署基础设施以调用接口。如何执行此操作取决于部署基础设施的特定详细信息。

部署基础设施

  • Docker
  • Kubernetes
  • NDP
  • noah

springboot的健康检查

Spring Boot Actuator是健康检查库的一个很好的例子。

它实现了/actuator/health接口,实现此接口的代码负责返回健康状况检查的结果。通过使用约定优于配置(convention over configuration),Spring Boot Actuator基于部署基础设施实现了一组合理的健康检查。

例如,如果服务使用JDBC DataSource,则Spring Boot Actuator会配置执行测试查询的健康检查。
同样,如果服务使用RabbitMQ消息代理,它会自动配置健康检查,以验证RabbitMO服务器是否已启动。

还可以通过对服务实现其他健康检查来自定义此行为。可以通过定义实现HealthIndicator接口的类来实现自定义健康检查。此接口定义了一个health()方法,该方法由/actuator/health接口的实现调用。它返回健康检查的结果。

业务平滑上下线与健康检查

大部分的互联网业务场景下,需要对用户提供7x24小时服务。尤其是我们的应用发布频次频繁的情况下,降低发布时对用户的影响,提升用户体验。应用引入应用健康检查的支持。

所谓平滑上下线,也是应用提供相应的online,offline接口,由部署基础设施调用。从而让应用感知到上线,下线请求,主动将自己从注册中心摘除,防止新流量进入,并处理完已经接受的请求之后,平稳关闭。

基于k8s的部署平台

Kubernetes提供了自愈的能力,当容器崩溃,K8s能够自动重启这个容器。为了更好利用K8s故障自愈能力,并且实现优雅停机。业务需在代码中实现以下健康检查接口,提供HTTP访问。

健康检查一共需要实现4个HTTP接口,在发布过程与容器运行中起作用:

  • check接口**(存活探针)**:
    • 发布过程中检查业务进程是否启动完成
    • 作为K8s Liveness存活探针,在Pod运行过程中由kubelet执行探测,若探测失败达到阈值,容器将会被自动重启 【接口响应的状态码应大于等于200且小于400,视为探测成功】
  • online接口:
    • 发布过程中check接口返回200之后,启动脚本将自动调用online接口,online接口返回200意味着进程已就绪,可以接收流量了
  • status接口(业务探针):
    • 标识业务进程是否运行正常。发布过程中在online接口成功之前,status接口返回非200;online成功之后返回200
    • 作为K8s Readiness业务就绪探针,在Pod运行过程中由kubelet执行探测,若探测失败达到阈值,容器将不再接收流量 【接口响应的状态码应大于等于200且小于400,视为探测成功】
      • 参考后续网络配置文档:
      • 当使用K8s Service时,会被从service的endpoint中移除
      • 当使用Nginx Upstream时,会被从upstream中移除
  • offline接口:
    • 作为Pod prestop,在容器销毁前将会被调用,提供业务在容器销毁前的扩展钩子

业务启动流程

下图为业务启动过程中发布日志示例,依次是

  1. starting app:启动业务进程
  2. do check:轮询check接口,直至成功或超过次数限制
  3. check success:check接口返回成功,业务进程完成启动
  4. do online:调用online接口,激活系统
  5. online success:业务系统开始接收流量,status接口返回200

Nginx的健康检查

被动健康检查

Nginx自带有健康检查模块:ngx_http_upstream_module,可以做到基本的健康检查,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
upstream cluster{
server 172.16.0.23:80 max_fails=1 fail_timeout=10s;
server 172.16.0.24:80 max_fails=1 fail_timeout=10s;
   # max_fails=1和fail_timeout=10s 表示在单位周期为10s钟内,中达到1次连接失败,那么接将把节点标记为不可用,并等待下一个周期(同样时常为fail_timeout)再一次去请求,判断是否连接是否成功。
   # fail_timeout为10s,max_fails为1次。
 
}

server {
listen 80;
server_name xxxxxxx.com;
location / {
proxy_pass http://cluster;
}
}

Nginx只有当有访问时后,才发起对后端节点探测。如果本次请求中,节点正好出现故障,Nginx依然将请求转交给故障的节点,然后再转交给健康的节点处理。所以不会影响到这次请求的正常进行。但是会影响效率,因为多了一次转发,而且自带模块无法做到预警。

主动健康检查

主动地健康检查,nignx定时主动地去ping后端的服务列表,当发现某服务出现异常时,把该服务从健康列表中移除,当发现某服务恢复时,又能够将该服务加回健康列表中。

淘宝有一个开源的实现nginx_upstream_check_module模块官网:http://tengine.taobao.org/document_cn/http_upstream_check_cn.html