一、前言

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

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

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

二、什么是健康检查

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

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

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

影响服务不可用和响应慢的因素很多,可能是服务硬件损坏、光纤被挖断,可能是申请量过大导致数据库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 = 7200net.ipv4.tcp_keepalive_intvl = 75net.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衰弱对象。

@FuncationalInterfacepublic 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:

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

@Overridepublic 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