服务注册发现consul之五:Consul移除失效服务的正确姿势

时间:2022-07-21 11:56:00

spring cloud微服务不定期会出现网络请求失败的错误。于是看了下后台日志,发现有几个请求会报如下的异常:

Caused by: feign.RetryableException: Connection refused (Connection refused) executing POST http://oauth/oauth/token******
at feign.FeignException.errorExecuting(FeignException.java:)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:)
at feign.hystrix.HystrixInvocationHandler$.run(HystrixInvocationHandler.java:)
at com.netflix.hystrix.HystrixCommand$.call(HystrixCommand.java:)
at com.netflix.hystrix.HystrixCommand$.call(HystrixCommand.java:)
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:)
... more

(调用流程是user服务调用oauth服务)
一开始很奇怪,为什么有的请求可以成功,有的不可以。因为服务编排用的是Docker Compose,所以第一反应是编排服务的时候,oauth的hosts忘加了(后来才想起来请求用的是Feign,根本不需要管hosts,RestTemplate才需要,mdzz)。在docker-compose.yml里加上以后,并没有卵用。
然后到Consul上看了一下,oauth服务确实是在线的。(不过后面的passing数量不是2,是6,这里因为已经移除了失效的,所以只剩下2个)

服务注册发现consul之五:Consul移除失效服务的正确姿势
然后就开始怀疑人生了,为什么服务在线却访问不到呢,用Eureka的时候才出现过这个问题,难道Consul也有?那我辛辛苦苦切换过来还有什么意义!然后我就盯着那个数字6看,产生了一个疑问:哪里来的6个oauth实例?这个时候才想到,可能是Feign负载均衡拿到了“假”的oauth实例,所以才请求失败。点开Consul的Node列表看了一下,发现有6个oauth躺在那里,然而只有2个是可用的。

不应该啊,Consul不应该把无效的服务注销掉吗?

这是因为:当在Spring Cloud应用中使用Consul来实现服务治理时,由于Consul不会自动将不可用的服务实例注销掉(deregister),这使得在实际使用过程中,可能因为一些操作失误、环境变更等原因让Consul中存在一些无效实例信息,而这些实例在Consul中会长期存在,并处于断开状态。它们虽然不会影响到正常的服务消费过程,但是它们会干扰我们的监控,所以我们可以实现一个清理接口,在确认故障实例可以清理的时候进行调用来将这些无效信息清理掉。

在consul的官网上:https://www.consul.io/api/agent/service.html (果然遇到问题就应该先去找官方文档啊!)

解决办法:调用deregister接口

服务注册发现consul之五:Consul移除失效服务的正确姿势

用PUT请求Consul 的这个deregister接口,附上实例的id就可以成功注销掉实例了(注意是实例的id,不是服务名,即服务名+一段唯一字符串。有ACL认证的Consul需要在Header上加token,否则会报permission denied)如下图:

服务注册发现consul之五:Consul移除失效服务的正确姿势

示例:put方式访问http://1XX.XX.xx.250:8500/v1/agent/service/deregister/trade-1xx-xx-206-101-18090
服务注册发现consul之五:Consul移除失效服务的正确姿势

接着看到这个服务的实例数量……难道要一个一个请求吗?

服务注册发现consul之五:Consul移除失效服务的正确姿势

当然不是,配合下面这个实例列表接口,批量删除吧!

服务注册发现consul之五:Consul移除失效服务的正确姿势
示例:查看list service如下:http://1XX.XX.XX.250:8500/v1/agent/services
服务注册发现consul之五:Consul移除失效服务的正确姿势
上面是列出所有的service。
 
服务注册发现consul之五:Consul移除失效服务的正确姿势
可以用下面的
http://172.29.206.250:8500/v1/health/state/critical,返回的json中都是失败的service,再删除它。