美文网首页consul
《Consul踩坑记》一、Consul移除失效服务的正确姿势

《Consul踩坑记》一、Consul移除失效服务的正确姿势

作者: xjh_ubuntu | 来源:发表于2017-11-23 17:44 被阅读5557次

    前阵子有用户反映App在登录的时候,不定期会出现网络请求失败的错误。于是看了下后台日志,发现有几个请求会报如下的异常:

    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
    

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

    consul.png

    然后就开始怀疑人生了,为什么服务在线却访问不到呢,用Eureka的时候才出现过这个问题,难道Consul也有?那我辛辛苦苦切换过来还有什么意义!
    然后我就盯着那个数字6看,产生了一个疑问:哪里来的6个oauth实例?这个时候才想到,可能是Feign负载均衡拿到了“假”的oauth实例,所以才请求失败。点开Consul的Node列表看了一下,发现有6个oauth躺在那里,然而只有2个是可用的。
    不应该啊,Consul不应该把无效的服务注销掉吗?于是搜了一波Consul注销无效服务,找到一篇程序猿DD的博客《Consul注销实例时候的问题》,里面写道:

    当我们在Spring Cloud应用中使用Consul来实现服务治理时,由于Consul不会自动将不可用的服务实例注销掉(deregister),这使得在实际使用过程中,可能因为一些操作失误、环境变更等原因让Consul中存在一些无效实例信息,而这些实例在Consul中会长期存在,并处于断开状态。

    这下一切都说得通了!

    然而按照博客上说的方法试了一下,还是没有成功地注销掉实例。原因是要注销的是状态failing的实例,可是那6个oauth实例都说自己是passing的。这又是为什么呢。
    不过这个问题并没有解决。看了下能正常注销的服务代码,发现oauth缺少了一个healthCheckInterval的配置,可能是这个原因。有遇到的朋友可以分享一下。

    之后又试了好几种注销服务的方式,都没能成功。知道了问题原因,却不能解决,真的是很难过☹️。我的临时做法是在Feign请求的时候指定了服务实例的ip地址。😂

    然后,十九大过去了,我可以fq了,又用Google搜了一遍,很快找到了答案:https://www.consul.io/api/agent/service.html (果然遇到问题就应该先去找官方文档啊!)

    解决方案

    deregister.png

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

    health check.png

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


    consul.png

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


    list service.png

    相关文章

      网友评论

        本文标题:《Consul踩坑记》一、Consul移除失效服务的正确姿势

        本文链接:https://www.haomeiwen.com/subject/ehuzvxtx.html