测试环境上是一个三节点consul集群,使用haproxy代理,prometheus配置该集群用来服务发现
今天查看prometheus系统日志发现如下报错
Nov 24 15:59:56 localhost prometheus[71048]: level=error ts=2020-11-24T07:59:56.891Z caller=consul.go:484 component="discovery manager scrape" discovery=consul msg="Error refreshing service" service=service-name tags="unsupported value type" err="Get http://xxxx:xx/v1/catalog/service/service-name?index=20653&stale=&wait=30000ms: EOF"
首先调用这个consul的api,确实是EOF,然后记录下报错的频率,严格的30s一次。
之后查看日志中提示的consul.go:484,如下代码:
怀疑是index版本的问题,降低index调用api,正常调用,同时看到watchTimeout为30s。
排除prometheus问题,之后绕过haproxy,调用consul的api,显示正常
同时注意到,lastindex的返回要比历史版本的慢很多,怀疑是haproxy的超时问题,发现haproxy超时时间只有10s。
修改haproxy的超时时间为60s后,一切正常。
为什么最新版本的数据要等到watchTimeout后返回呢?
consul会尝试等待被请求资源发生变化,如果在wait指定的时间内1) 对于历史版本数据,被请求资源发生变化, 请求直接返回新的X-Consul-Index和新的body体2) 最新版本的数据,被请求资源未发生变化,则请求会一直阻塞,直到wait指定的时间耗尽,请求最终会返回。只是此时X-Consul-Index不发生变化,body体不变。长轮训减少了频繁轮训的所造成的不必要的带宽和服务器资源开销,用在服务发现上,即时性也能有所保证,还是很合适的