Consul注销实例时候的问题

}

if (ttlScheduler != null) {

ttlScheduler.remove(serviceId);

}

log.info(“Deregistering service with consul: {}”, serviceId);

client.agentServiceDeregister(serviceId);

}

}

我们可以看到,当应用关闭时候的注销操作是通过调用client.agentServiceDeregister(serviceId)来实现的。其中client是consul-api的com.ecwid.consul.v1.ConsulClient实例。而agentServiceDeregister方法则是对/v1/agent/service/deregister/<serviceID> 接口的实现,该接口主要用来从Consul Agent中根据serviceId来注销实例。

以此实现为范例,于是开始的思路是这样的:

  • 先通过consulClient.getHealthServices(serviceId, false, null)根据serviceId来获取服务实例清单

  • 遍历实例清单中有不是PASSING状态的实例,就调用client.agentServiceDeregister(serviceId)来剔除

具体实现如下:

@RestController

public class ApiController {

@Autowired

private ConsulClient consulClient;

@RequestMapping(value = “/unregister/{id}”, method = RequestMethod.POST)

public String unregisterServiceAll(@PathVariable String id) {

List response = consulClient.getHealthServices(id, false, null).getValue();

for(HealthService service : response) {

service.getChecks().forEach(check -> {

if(!check.getStatus().name().equals(Check.CheckStatus.PASSING.name())) {

logger.info(“unregister : {}”, check.getServiceId());

consulClient.agentServiceDeregister(check.getServiceId());

}

});

}

return null;

}

}

但是,在测试后发现该方法只能剔除同一个agent上的非PASSING实例。

Catalog误区


继续搜索了一下Consul的文档,发现了这个接口:/v1/catalog/deregister : Deregisters a node, service, or check。于是,尝试了用该接口来替换之前的consulClient.agentServiceDeregister(check.getServiceId());实现。

CatalogDeregistration catalogDeregistration = new CatalogDeregistration();

catalogDeregistration.setDatacenter(“dc1”);

catalogDeregistration.setNode(check.getNode());

catalogDeregistration.setServiceId(check.getServiceId());

catalogDeregistration.setCheckId(check.getCheckId());

consulClient.catalogDeregister(catalogDeregistration);

经过测试,该方法可以实现短暂的剔除,但是过一段时间之后这些被剔除的实例又都恢复回来了……也就是说这个接口完全没有什么卵用!

那么为什么会出现这种情况呢?我们可以在Github中找到这个维持了一年多的问题讨论:https://github.com/hashicorp/consul/issues/1188 。整个讨论过程非常曲折,虽然当前该问题还依然在open状态,但是一些回复也基本够我们去理解它的原因了。比如下面这条评论:

You cannot deregister a service from the agent on a different node, service only exists on the agent you have registered with. It also exists in the catalog on all nodes, but that is not related to the agent itself. And to be honest I don’t understand why there is a catalog/deregister endpoint at all, in my opinion catalog should be a read-only service list.

从该评论中,我们可以知道一个重要信息:**服务实例只能在注册的Agent上进行注销!**另外,对于/v1/catalog/deregister接口,目前还是有不少争议的,因为根本没啥用。

最终实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值