Eureka开发快速剔除失效服务


同一个服务部署了多个实例,在通过网关调用时会随机调用其中一个。但是,当某个服务挂掉之后,依然在注册中心中,依然会随机被调用到,调用时便会超时报错,为了快速的剔除掉挂掉的服务,于是有下面几种主动下线的方法:


1.直接停掉服务

默认情况下,如果Eureka Server在90秒没有收到Eureka客户的续约,它会将实例从其注册表中删除。但这种做法的不好之处在于, 客户端已经停止了运行,但仍然在注册中心的列表中。 虽然通过一定的负载均衡策略或使用熔断器可以让服务正常进行,但有没有方法让注册中心马上知道服务已经下线呢?


2.为了让注册中心马上知道服务要下线, 可以向eureka 注册中心发送delete请求

格式为 http:{ip:port}/eureka/apps/{application.name}/{在eureka上注册成功的实例ID}

下面是下线一个hello-service的例子。

img

用curl 发送delete 请求:

curl -X DELETE http://localhost:1111/eureka/apps/HELLO-SERVICE/localhost:hello-service:8080

或者用postman 发送delete请求

img

值得注意的是,Eureka客户端每隔一段时间(默认30秒)会发送一次心跳到注册中心续约。如果通过这种方式下线了一个服务,而没有及时停掉的话,该服务很快又会回到服务列表中。

所以,可以先停掉服务,再发送请求将其从列表中移除。


3.客户端主动通知注册中心下线

如果你的eureka客户端是是一个spring boot应用,可以通过调用以下代码通知注册中心下线。

DiscoveryManager.getInstance().shutdownComponent();

例子如下,

@RestController
public class HelloController {
    @Autowired
    private DiscoveryClient client;
 
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String index() {
        java.util.List instances = client.getInstances("hello-service");       
        return "Hello World";
    }
    
    @RequestMapping(value = "/offline", method = RequestMethod.GET)
    public void offLine(){
        DiscoveryManager.getInstance().shutdownComponent();
    }   
}