乐趣区

关于服务器:系统高可用之健康检查和健康度量那些事

一、前言

随着人们的生存程度的一直进步,人们对身体健康越来越器重,很多人都做过体检,个别公司都会有一年一度的体检福利,衰弱体检是妇孺皆知了。

随着互联网的疾速倒退,同类同质产品之间的竞争越来越大,产品之间一个重要的差别就是用户体验。影响用户体验的,除了产品设计因素外,技术层面也是一个重要的影响因素,次要体现在服务的可用性和响应速度。晋升服务可用性和响应速度如此重要,为了实现这样的指标,必须要有相应的伎俩,其中健康检查就是保障服务可用性和疾速响应一个十分重要的前提。

健康检查有哪些项目、指标和办法呢?此文带你一一揭晓。

二、什么是健康检查

衰弱体检是指通过医学伎俩和办法对受检者进行身体检查,理解受检者健康状况、晚期发现疾病线索和衰弱隐患的诊疗行为。而零碎的健康检查是利用技术手段检测网络、主机、利用、服务等一系列对象是否衰弱或可用的过程。

三、为什么须要做健康检查

互联网产品对用户体验提出了很高的要求,但经常因为技术侧起因,产生服务响应慢或者服务不可用等一系列影响用户体验的问题,导致业务中断,影响支出,公司品牌和口碑也会受到微小的负面影响。

影响服务不可用和响应慢的因素很多,可能是服务硬件损坏、光纤被挖断,可能是申请量过大导致数据库 CPU 负载、磁盘 IO 过高,又可能是某同学埋了雷,新上线的性能第一次运行就产生了 OOM……

要保证系统高可用,咱们应该怎么做呢?有人说,零碎节点冗余打消单节点故障不就行了吗。说的没错,打消单节点是零碎高可用的罕用伎俩。打消单节点有一个很重要的前提是发现问题节点,把问题节点踢除或者把流量切换到其余失常节点。

如何“发现问题节点”,就是零碎健康检查须要做的事件。

四、如何做健康检查

议论如何做健康检查前,首先要弄明确的是要查看的对象到底是谁。对象能够网络连接,能够是一个小小的性能组件,能够是一个过程,能够是服务集群,也能够是机房单元。所以,要做到“高可用”,首先要弄清楚要做哪层面的高可用,哪些对象可能存在单点问题,要把“对象”搞清楚。

那么,健康检查如何做呢?通常有两种形式:被动和被动。

4.1 被动模式

由查看方作为被动方,定时被动发动健康检查申请,申请的报文内容或者格局通常是独立设计的,被衰弱的对象作简略自检后返回响应。举个例子:

check interval=3000 rise=2 fall=5 timeout=1000 type=http;
check_http_send "HEAD /check.do HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;

配置距离 2000 豪秒定时向后盾 web 服务器 http://(ip:port)/check.do 接口 …

4.2 被动模式

被动健康检查不设计独立的健康检查申请,而是以失常连贯状况或者业务申请的响应作为指标来掂量查看对象的衰弱状态。例如 nginx 官网开源版本的被动健康检查配置:

server 127.0.0.1:8080       max_fails=3 fail_timeout=30s;

Nginx 是基于连贯探测,如果在 30s 内尝试连贯 3 次失败,则认为后端 web 服务不可用。

4.3 打消单点

下面谈到,要实现高可用就要打消单点故障,最简略间接的计划加备服务节点,通过定时心跳健康检查发现主服务节点宕机后,备服务节点把主的工作接管过去,客户端把申请流量切换到备服务节点。

主服务节点与备服务节点之间通过专用的心跳线进行健康检查,因为网络分区等起因它们可能无奈收到对方心跳,这时备节点会认为主节点已宕机,主节点也认为备节点已宕机,但其实主从两节点状态都是失常的,客户端能失常拜访到主从两节点,呈现“双写”,这种景象在业界称为“脑裂(split-brain)”。

呈现脑裂会导致数据凌乱的劫难事件产生,影响业务的正确性,这时引入第三方机构进行仲裁能够无效防止脑裂的产生。呈现脑裂会导致数据凌乱的劫难事件产生,影响业务的正确性,这时引入第三方机构进行仲裁能够无效防止脑裂的产生。

4.4 第三方仲裁

既然主从单方无奈确认对方的存活,呈现争议时能够由第三方仲裁节点做出决定,到底谁是主由它说了算,第三方仲裁节点个别是由 Zookeeper 这种高可用计划来实现。

五、健康检查例子

5.1 网络设备

Keepalived 是一款保障集群高可用的服务软件,其性能相似于 heartbeat,用于避免单点故障。然而它个别不会独自呈现,而是与其它负载平衡技术(如 LVS、HAProxy、Nginx)一起工作来达到集群的高可用。

它的健康检查也蕴含两个方面,一个是 Keepalived 组件之间的健康检查(通过 VRRP 心跳报文),如下图所示

另一个是 Keepalived 组件与本地负载平衡组件的健康检查,配置如下:

vrrp_script check_nginx_running {
    script "/usr/local/bin/check_running"(定义脚本)interval 10(脚本执行的距离)weight -10(脚本执行的优先级)}

其中,利用的健康检查形式通过自定义脚本实现。

Keepalived 组件之间通过 VRRP 协定进行健康检查,如果主服务器宕机,备服务器通过 VRRP 协定选举成为新的主服务器,把虚构 IP 从旧的主服务器上争抢过去,实现高可用。

VRRP 报文是封装在 IP 报文上的,反对各种下层协定,网络设备通常也是应用 VRRP 协定实现主备高可用切换,如交换机、路由器、防火墙等。

当网络设备产生故障时,VRRP 机制可能选举出新的网络设备承当数据流量,从而保障网络的牢靠通信。

5.2 网络连接

挪动设施连贯互联网通过 NAT 形式,挪动 App 的 PUSH 推送须要与服务器放弃长连贯,但大部分挪动网络运营商都在连贯一段时间没有数据交互时,会淘汰 NAT 列表中的对应连贯,造成连贯中断。为了放弃网络连接的“衰弱”可用,咱们能够在连贯建设后,App 与服务器相互定期发送 Ping Pong 心跳信息来放弃连贯的继续无效。

以上是应用层的连贯健康检查计划,操作系统也反对底层网络的连贯健康检查即 Keepalive。TCP Keepalive 能够在连贯无流动一段时间后,发送一个空的探测报文,使 TCP 连贯不会被客户端或者防火墙等两头网络设备敞开。Linux 能够通过以下三个参数对 Keepalive 的距离、频率和阈值和进行配置:

net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_keepalive_probes = 9

5.3 主机与过程

主机之间的可达性能够通过 Ping 命令进行辨认,Ping 命令应用的是 ICMP 协定,它能辨认从客户端到指标主机整个门路的网络连通性。Ping 通常用于手工测试某台主机是否启动和网络是否联通。

ICMP 是网络层协定,与具体过程是没关系的,无奈通过 Ping 辨认过程是否存在。但过程有端口,有过程信息,能够通过 telnet 端口或 ps 命令检测过程是否存在。过程可能会因为内存不足被 kill 或者其余起因异样敞开,能够通过 cron 定时脚本检测辨认后主动拉起,这种计划对老破旧我的项目中只能单实例部署的利用的可用性晋升十分无效。

5.4 中间件 -RocketMQ

NameServer 是 RocketMQ 的路由核心,NameServer 中保护着 Producer 集群、Broker 集群、Consumer 集群的服务状态和路由信息。当有新的 Consumer 退出集群时,除了上报本身信息外,还获取各个 Broker 的地址、Topic、队列等信息,这样就能晓得它生产的 Topic 音讯存储到哪个 Broker 和队列上。

NameServer 能够部署多个,NameServer 之间互相独立不互通。Producer、Broker、Consumer 服务启动时须要指定多个 NameServer,服务的信息会同时注册到多个指定的 NameServer 上,达到高可用。

每个 Broker 节点与所有 NameServer 会放弃 TCP 长连贯,每隔 30s 给 NameServer 发送心跳报文,通知 NameServer 本人还活着。而每个 NameServer 每隔 10s 检查一下各个 Broker 的最近一次心跳工夫,如果发现某个 Broker 超过 120s 都没发送心跳报文,就认为这个 Broker 曾经宕机了,会敞开对应的网络连接 channel,并将其从路由信息里移除。

5.5 应用层 – Spring Boot Actuator

一个服务实例或者过程会通过定期的心跳包向其余服务来报告它的存活,但有这个心跳包还是不够的,不足以反映它的健康状况。比方磁盘空间有余了,服务曾经无奈再写数据了,但它还能响应心跳包;服务依赖 Redis,但 Redis 服务出了问题连贯不上,但它还能响应心跳包;服务的某些性能依赖分布式存储服务,但分布式存储服务不可用了,但它仍然能响应心跳包。咱们能够看到,要确定一个服务实例是否存活并且“衰弱”,还是有很多方面须要思考的。Spring Boot Actuator 能比拟好的解决这个问题,它能反映整个服务的健康状况,包含它所依赖的子系统的健康状况。

Spring Boot Actuator 是 Spring Boot 的一个子项目,Actuator 提供 Endpoint(端点)给内部应用程序进行拜访和交互。Actuator 包含许多性能,比方健康检查、审计、指标收集等等,可帮忙咱们监控和治理 Spring Boot 应用程序。Health 就是其中一个 Endpoint,它提供了对于 Spring Boot 利用的根本衰弱状况信息,容许其余云服务或者 k8s 等定时检测到利用的健康状况,对异常情况及时作出响应。

如果某微服务利用应用到了 MySQL、Amazon S3、Elastic Search、DynamocDB 这些资源零碎,它的健康检查后果就应该蕴含所有这些子系统的健康状况:

Actuator 的健康检查由 HealthIndicator 接口实现,HealthIndicator 接口只有一个 health() 办法,返回值是 Health 衰弱对象。

@FuncationalInterface
public class HealthIndicator {
 
    /**
     * Return an indication of health.
     * @result the health for
     */
    public Health health();}

Health 对象有状态 status 和 details 两个字段,status 默认有 UNKNOWN、UP、DOWN 和 OUT\_OF\_SERVICE 四个值,用户能够自定义和扩大,details 是一个 KV 构造,用户能够随便自定义要返回的数据值。

@JsonInclude(Include.NON_EMPTY)
public final class Health extends HealthComponent {
 
    private final Status status;
 
    private final Map<String, Object> details;
   
    ...
 
}

Actuator 内置了很多罕用的 HealthIndicator:

用户能够依据理论状况自定义,比方:

@Override
public Health health() {int errorCode = check(); // perform some specific health check
    if (errorCode != 0) {return Health.down().withDetail("Error Code", errorCode).build();}
    return Health.up().build();
}

默认状况下 health 的状态是启用且对外开放的,通过 http://locahost:8080/actuator…“UP”},这是一个汇总的状态,具体的衰弱信息能够通过配置项 management.endpoint.health.show-details=always 关上,一个残缺的蕴含 details 的健康检查信息如下:

汇总的衰弱状态由 HealthAggregator 汇总而成的,汇总的算法是:所有子系统的衰弱状态按 DOWN、OUT\_OF\_SERVICE、UP、UNKNOWN 这个程序进行排序取最后面一个状态值。

比方 ehCache 是 UP,MySQL 是 UNKNOWN,diskSpace 是 OUT\_OF\_SERVICE;那么排序下来就是:OUT\_OF\_SERVICE、UP、UNKNOWN,取第一个就是 OUT\_OF\_SERVICE,即服务不可用。

六、总结

高可用是一个很简单的工程问题,它是由一系列的子问题形成,健康检查和衰弱度量只是其中一个。业务要放弃间断不中断,零碎要保障继续运行,就要保障全链路所有参加的节点都是高可用的,避免出现单点故障。

如何及时发现不衰弱或故障的节点并告警,如何在节点呈现不衰弱或故障时及时 failfast/failover 防止产生雪崩效应,健康检查在其中扮演着十分重要的作用。

作者:vivo 互联网服务器团队 -Chen Jianbo

退出移动版