服务注册发现consul之五:Consul移除失效服务的正确姿势
spring cloud微服务不定期会出现网络请求失败的错误。于是看了下后台日志,发现有几个请求会报如下的异常:
Caused by: feign.RetryableException: Connection refused (Connection refused) executing POST http://oauth/oauth/token****** at feign.FeignException.errorExecuting(FeignException.java:67) at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:104) at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76) at feign.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:108) at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:302) at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:298) at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46) ... 26 more
Caused by: feign.RetryableException: Connection refused (Connection refused):可能原因,1、被调用的服务重启了,如被docker kill了。2、注册中心上的健康检查失败
(调用流程是user
服务调用oauth
服务)
一开始很奇怪,为什么有的请求可以成功,有的不可以。因为服务编排用的是Docker Compose,所以第一反应是编排服务的时候,oauth
的hosts忘加了(后来才想起来请求用的是Feign,根本不需要管hosts,RestTemplate才需要,mdzz)。在docker-compose.yml
里加上以后,并没有卵用。
然后到Consul上看了一下,oauth
服务确实是在线的。(不过后面的passing
数量不是2,是6,这里因为已经移除了失效的,所以只剩下2个)
不应该啊,Consul不应该把无效的服务注销掉吗?
这是因为:当在Spring Cloud应用中使用Consul来实现服务治理时,由于Consul不会自动将不可用的服务实例注销掉(deregister),这使得在实际使用过程中,可能因为一些操作失误、环境变更等原因让Consul中存在一些无效实例信息,而这些实例在Consul中会长期存在,并处于断开状态。它们虽然不会影响到正常的服务消费过程,但是它们会干扰我们的监控,所以我们可以实现一个清理接口,在确认故障实例可以清理的时候进行调用来将这些无效信息清理掉。
在consul的官网上:https://www.consul.io/api/agent/service.html (果然遇到问题就应该先去找官方文档啊!)
参考《consul之:常用API接口》
解决办法:调用deregister接口
用PUT请求Consul 的这个deregister
接口,附上实例的id就可以成功注销掉实例了(注意是实例的id,不是服务名,即服务名+一段唯一字符串。有ACL认证的Consul需要在Header上加token,否则会报permission denied)如下图:
接着看到这个服务的实例数量……难道要一个一个请求吗?
当然不是,配合下面这个实例列表接口,批量删除吧!