简介
在微服务架构中,微服务会存在多个实例,部署在多台主机中。因为网络、主机状态等诸多因素,单台主机上的服务出现问题的几率大大增加。这就要求我们能够监控每台主机、每个微服务实例的健康状态。Consul作为注册中心,提供了强大、灵活的健康监测。
快速上手
定义check的位置为/etc/consul.d/,格式跟定义服务一样,也是JSON。 下边我们定义两个check,分别为pingBaidu.json和web.json。内容如下:
{
"check": {
"name": "pingBaidu",
"script": "ping -c1 baidu.com >/dev/null",
"interval": "30s"
}
}
{
"service": {
"name": "web",
"tags": [
"springCloud"
],
"port": 80,
"check": {
"script": "curl localhost >/dev/null 2>&1",
"interval": "10s"
}
}
}
pingBaidu的健康检查,每隔30秒检查一次。 web的健康检查,每隔10秒执行一次。
checks有作用域。与服务绑定的check为应用级,不与服务绑定为全局。可以通过给check添加service-id来与服务进行绑定。
定义完成之后,启动consul:
./consul agent -dev -client 0.0.0.0 -enable-script-checks -config-dir=/etc/consul.d >consul.log &
上图中,pingBaidu执行成功,而web执行失败,因为我们并没有这个应用。
详细介绍
Consul支持五种健康检测的方式,分别为:Script+Interval、Http+Interval、TCP + Interval 、Time to Live (TTL)、Docker+ interval。接下来对每种方式进行详细介绍。
Script+Interval
这种方式中,通过执行外部脚本来进行健康检测。脚本按照指定时间来进行循环调用(比如30S调用一次)。脚本默认超时时间是30S,可以通过timeout来指定。
{
"check": {
"id": "mem-util",
"name": "Memory utilization",
"args": ["/usr/local/bin/check_mem.py", "-limit", "256MB"],
"interval": "10s",
"timeout": "1s"
}
}
Http+Interval
这种检查将按照预设的时间间隔创建一个HTTP GET请求。HTTP响应代码来标识服务所处状态:任何2xx代码视为正常,429表示警告——有很多请求;其他值表示失败。Http默认的超时时间为Interval中指定的时间,最大时间为10秒。
{
"check": {
"id": "api",
"name": "HTTP API on port 5000",
"http": "https://localhost:5000/health",
"tls_skip_verify": false,
"method": "POST",
"header": {"x-foo":["bar", "baz"]},
"interval": "10s",
"timeout": "1s"
}
}
TCP + Interval
将按照预设的时间间隔与指定的IP/Hostname和端口创建一个TCP连接。服务的状态依赖于TCP连接是否成功——如果连接成功,则状态是“success”;否则状态是“critical”。如果一个Hostname解析为一个IPv4和一个IPv6,将尝试连接这两个地址,第一次连接成功则服务状态是“success”。 如果希望通过这种方式利用外部脚本执行健康检查,那么脚本应该采用“netcat”或者简单的socket操作。 默认情况下,TCP checks中,请求超时时间等于调用请求的间隔时间,最大10秒。也是可以自由配置的。
{
"check": {
"id": "ssh",
"name": "SSH TCP on port 22",
"tcp": "localhost:22",
"interval": "10s",
"timeout": "1s"
}
}
Time to Live (TTL)
这种checks为给定TTL保留了最后一种状态,checks的状态必须通过HTTP接口周期性更新,如果外部接口没有更新状态,那么状态就会被认定为不正常。
这种机制,在概念上类似“死人开关”,需要服务周期性汇报健康状态。比如,一个健康的APP可以周期性的将状态put到HTTP端;如果app出问题了,那么TTL将过期,健康检查将进入Critical状态。用来为给定check更新健康信息的endpoint都是pass endpoint和fail endpoint。(参见agent http endpoint)
TTL checks同时会将其最后已知状态更新至磁盘,这允许Agent通过重启后恢复到已知的状态。通过TTL端上一次check来维持健康状态的有效性。
{
"check": {
"id": "web-app",
"name": "Web App Status",
"notes": "Web app does a curl internally every 10 seconds",
"ttl": "30s"
}
}
Docker+ interval
这种检查依赖于调用封装在docker容器内的外部程序。运行的docker通过docker Exec API来触发外部应用。
我们期望,consul Agent用户访问Docker HTTP API或UNIX套接字。Consul使用$DOCKER_HOST来确定Docker
API端点。应用程序将运行,并对在容器内运行的服务执行健康检查,并返回适当的退出代码。Check按照指定的时间间隔调用。
如果在同一个host主机上有多重shell,那么同样需要配置shell参数。 输出限制在4K以内,输出大于4K将截断。
{
"check": {
"id": "mem-util",
"name": "Memory utilization",
"docker_container_id": "f972c95ebf0e",
"shell": "/bin/bash",
"args": ["/usr/local/bin/check_mem.py"],
"interval": "10s"
}
}
总结
每种定义中,name是必填的,其他事选填的,包括id。id在agent范围内必须是唯一的,如果没提供id,默认会用name作为ID。