Consul7-註銷掉consul無效服務

       當我們在Spring Cloud應用中使用Consul來實現服務治理時,由於Consul不會自動將不可用的服務實例註銷掉(deregister),這使得在實際使用過程中,可能因爲一些操作失誤、環境變更等原因讓Consul中存在一些無效實例信息,而這些實例在Consul中會長期存在,並處於斷開狀態,這些斷開的實例有時候會影響服務的請求,所以我們需要刪除這些無效的服務。所以這一篇注意來了解下如果出現無效的服務,我們怎麼來註銷掉這些無效的服務。下面是整理的consul的一系列的博文:

Consul1-window安裝consul

Consul2-使用consul作爲服務註冊和發現中心

Consul3-使用consul作爲配置中心

Consul4-linux安裝consul以及集羣搭建

Consul5-springboot2使用consul做爲配置中心

Consul6-springboot2基於consul的服務調用

Consul7-註銷掉consul無效服務

參考資料:

通過接口刪除無效服務和節點:https://blog.csdn.net/harris135/article/details/77720686
通過代碼刪除無效服務:http://blog.didispace.com/consul-deregister/

 下面開始我們的正文吧!!!

一 刪除consul的client節點

       我們知道consul分爲server和client模式 ,一般我們在實際使用的時候應用是直接通過consul的client節點連接的,client節點會加入server節點同步server的一些基本數,實際請求時,client相當於一個轉發的功能。當我們存在誤操作的時候client節點掛掉了,但是在consul-ui界面還是可以看到這個節點,consul的ui界面沒有提供刪除這個client節點的功能,但是提供了api,我們可以通過提供的api來刪除這個無效的client節點

linux下執行:eg:
     curl http://xx.xx.xx.xx:8500/v1/agent/force-leave/jack-client-dev
     jack-client-dev是client節點名稱,名稱可以通過類似這樣的http://xx.xx.xx.xx:8500/ui/#/dc1/nodes路徑查看,其實就是在consul的ui界面點擊NODES
   http://xx.xx.xx.xx:8500 是consul的服務地址,ip加端口,或者域名

 

   二 刪除consul無效的服務

     上面是刪除無效的consul的client節點,這裏是刪除無效的consul服務,什麼是consul無效的服務?比如我們使用spring cloud的時候,註冊到consul上的服務,使用consul的服務註冊與發現,那麼註冊到consul的服務我們在這裏就說是consul的服務。當我們的服務掛掉了,但是consul-ui上還是可以看到這個服務,只是狀態是falling的。如果有正常服務還有失敗的服務,進行服務調用的時候,可能出現就會出現問題。這時候就需要刪除這些無效的服務。consul同樣提供了相關的api:

linux下執行:eg:

curl -X PUT http://xx.xx.xx.xx:8500/v1/agent/service/deregister/print-provider-10-10-112-21-9082-6dda57dbbdf15725e1d99bb57c7aff0e
 
http://xx.xx.xx.xx:8500是consul的服務地址
print-provider-10-10-112-21-9082-6dda57dbbdf15725e1d99bb57c7aff0e是服務id,可以通過http://xx.xx.xx.xx:8500/v1/agent/checks地址查看所有的服務

這時候可能有人會問了,什麼是服務id,服務id就是使用springcloud的時候,我們的服務向consul註冊的id,比如下面配置的instance-id就是這個服務的id:

server:
  port: 8082
spring:
  application:
    name: consul5
  cloud:
    consul:
    #配置consul服務器的host
      host: localhost
      #配置端口
      port: 8500
      config:
      #配置默認文件名
        default-context: ${spring.application.name}
        #是否啓用consul配置
        enabled: true
        #配置文件格式
        format: YAML
        #配置基本文件,默認值config
        prefix: jack
        #配置文件名,默認data
        data-key: data
      discovery:
      #是否啓用服務發現
        enabled: true
        #配置健康檢查路徑
        health-check-path: /actuator/health
        #配置健康檢查時間間隔
        health-check-interval: 15s
        #配置實例id
        instance-id: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
        #配置服務註冊
        register: true
        #服務停止時取消註冊,http://www.imooc.com/article/286883?block_id=tuijian_wz
        deregister: true
        #表示註冊時使用ip而不是hostname
        prefer-ip-address: true
        #健康檢查失敗多長時間取消註冊
        health-check-critical-timeout: 30s
  profiles:
    active: dev

 

三  使用代碼移除服務

上面第二步中我們刪除根據服務id來刪除服務,但是每次只能刪除一個服務,但是實際中我們同一個服務名可能有多個服務id(每次啓動服務都會重新生成一個服務id),難道每次都要一個一個刪除這些無效的服務嗎?這樣太麻煩了,這裏我們就可以使用代碼來解決了,提供一個方法,輸入服務名就可以刪除這個服務名下所有的無效服務id了,eg:

@RestController
@RequestMapping("consul")
public class ConsulController {
    private static final Logger LOGGER = LoggerFactory.getLogger(ConsulController.class);
    @Autowired
    private ConsulClient consulClient;
    @RequestMapping(value = "/deregister/{serviceNmae}",method = RequestMethod.POST)
    public ResponseResult deregisterService(@PathVariable String serviceNmae) {
        List<HealthService> response = consulClient.getHealthServices(serviceNmae, false, null).getValue();
        for(HealthService service : response) {
            // 創建一個用來剔除無效實例的ConsulClient,連接到無效實例註冊的agent
            ConsulClient clearClient = new ConsulClient(service.getNode().getAddress(), 8500);
            service.getChecks().forEach(check -> {
                if(check.getStatus() != Check.CheckStatus.PASSING) {
                    LOGGER.info("unregister : {}", check.getServiceId());
                    clearClient.agentServiceDeregister(check.getServiceId());
                }
            });
        }
        return ResponseResult.success("移除"+serviceNmae+"成功");
    }

http://xx.xx.xx.xx:端口/consul/deregister/服務名

移除成功的返回信息,你們可以根據自己的定義。

比如我要刪除consul5這個服務名,就可以這樣調用這個接口了:

http://xx.xx.xx.xx:端口/consul/deregister/consul5

 

 

學習交流羣:331227121

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章