一、背景
consul既可以作为服务注册中心,也可以作为分布式配置中心。当它作为服务注册中心的时候,java微服务之间的调用,会定期查询服务的实例列表,并且实例的状态是健康可用。
如果发现被调用的服务,注册到consul的实例,没有一个是健康可用的时候,就会出现HystrixRuntimeException错误。
调用用户服务出现的异常示例:
HystrixRuntimeException: UserFeignService#customClassWithMems(Integer,String,Boolean) failed and fallback failed.
所以,我们要及时发现不健康的实例,本文就讨论下如何做好consul服务的监控及告警。
二、生产环境的consul集群
- 设计思路
1、生产环境下,consul采用HTTP Basic认证,访问 https://consul.xxx.net,输入用户名和密码。
后期的http请求,会在http header增加字段Authorization:Basic xxx,就不用每次交互都需要输入用户名和密码。
2、只能剔除同一个agent下的实例,所以提供UI的consul node,暴露到外网,同时不让服务注册到该node。这样更加安全,从外网无法剔除其他node上的服务。
- API网关对外网域名路由,启用HTTP Basic Auth
输入用户名和密码,校验成功,在http header会增加这么一个Key,
Authorization:Basic SGhvxxx2346SUdZcjlsO2V5O1==
所以,我们在请求consul api的时候,必须在http header增加上面的Key-Value键值对。
- 除了上面的http基本认证,我们还会要求访问consul得有token
示例:
curl -X PUT http://192.168.10.51:8500/v1/agent/service/deregister/user-service-192-168-5-16-8003?token=4db4d360-e5vc-4a36-723e-5x370e9f2432
至此,我们把背景和准备知识都铺垫完成,第三部分,我将把具体如何做监控的过程,详细描述。
三、监控脚本
# Consul Address
CONSUL_ADDR="https://consul.xxx.net"
# Consul acl token
CONSUL_ACL_TOKEN="4db4d360-e5vc-4a36-723e-5x370e9f2432"
# http basic auth (base64 the username and password)
HTTP_HEADER="Authorization:Basic SGhvxxx2346SUdZcjlsO2V5O1=="
# send alert message
ALERT_SYSTEM_INTERFACE="http://192.168.80.180:31767/api/v1/consul/alert"
# Get a list of all services from Consul
SERVICES=$(curl -H "${HTTP_HEADER}" -s "${CONSUL_ADDR}/v1/catalog/services?token=${CONSUL_ACL_TOKEN}" | jq -r 'keys[]')
# Loop through each service and check its health
for SERVICE_NAME in ${SERVICES}; do
HEALTHY_COUNT=$(curl -H "${HTTP_HEADER}" -s "${CONSUL_ADDR}/v1/health/service/${SERVICE_NAME}?token=${CONSUL_ACL_TOKEN}&passing=true" | jq '. | length')
if [ "${HEALTHY_COUNT}" -eq 0 ]; then
echo "WARNING!!! All instances of ${SERVICE_NAME} are unhealthy."
ALERT_MSG="{\"consulAddress\":\"online consul\",\"content\":\"All instance of ${SERVICE_NAME} are unhealthy.\",\"serviceName\":\"${SERVICE_NAME}\"}"
curl -X POST -H "Content-Type:application/json" -d "${ALERT_MSG}" "${ALERT_SYSTEM_INTERFACE}"
fi
done
四、告警接口
- http调用示例
curl -X POST -H "Content-Type:application/json" \
-d "{\"consulAddress\":\"online consul\",\"content\":\"All instance of user-service are unhealthy.\",\"serviceName\":\"user-service\"}" \
"http://192.168.80.180:31767/api/v1/consul/alert"
- 接口设计
## Consul健康告警
**接口地址**:`/api/v1/consul/alert`
**请求方式**:`POST`
**请求数据类型**:`application/json`
```javascript
{
"consulAddress": "192.168.10.61:8500",
"content": "",
"serviceName": "user-service"
}
请求参数:
参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 | schema |
---|---|---|---|---|---|
consulAlertDTO | consulAlertDTO | body | true | ConsulAlertDTO | ConsulAlertDTO |
consulAddress | consul地址 | true | string | ||
content | 内容 | false | string | ||
serviceName | 服务名称 | true | string |
接口的实现,这里就不进行详述了。
当发现某个服务没有一个健康可用的实例时,相关人员将收到告警消息。