Consul7-注销掉consul无效服务
当我们在Spring Cloud应用中使用Consul来实现服务治理时,由于Consul不会自动将不可用的服务实例注销掉(deregister),这使得在实际使用过程中,可能因为一些操作失误、环境变更等原因让Consul中存在一些无效实例信息,而这些实例在Consul中会长期存在,并处于断开状态,这些断开的实例有时候会影响服务的请求,所以我们需要删除这些无效的服务。所以这一篇注意来了...
当我们在Spring Cloud应用中使用Consul来实现服务治理时,由于Consul不会自动将不可用的服务实例注销掉(deregister),这使得在实际使用过程中,可能因为一些操作失误、环境变更等原因让Consul中存在一些无效实例信息,而这些实例在Consul中会长期存在,并处于断开状态,这些断开的实例有时候会影响服务的请求,所以我们需要删除这些无效的服务。所以这一篇注意来了解下如果出现无效的服务,我们怎么来注销掉这些无效的服务。下面是整理的consul的一系列的博文:
Consul5-springboot2使用consul做为配置中心
Consul6-springboot2基于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
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)