项目中使用SpringCloud时,Eureka作为注册中心基本是标配了,作为AP的一个实现策略,基本能够满足项目的需要。在微服务的世界中,每个模块发布是常有的事,那么如何安全地发布呢?

直接关闭服务

这种方式简单粗暴,直接造成的影响就是部分模块调用时出错,如果有多台服务器的话,一台一台地重启还是可以的,前提是调用端得有自己的重试策略,比如使用Feign作为客户端调用接口的话可以配置ribbon的重试策略,而且被调用方得做好幂等策略,防止重试调用时出现重复数据的问题。

主动关闭Eureka客户端

这种方式相对于直接关闭服务来说,优雅了许多,可以通过监控(ELK或log)查看是否下线后还有流量进来,等到完全没有流量进来后再进行发布。因为Eureka注册中心在收到某个客户端下线后不会马上通知所有的注册的客户端,而是等到客户端进行心跳的时候再将下线的数据返回。通过这种方式下线的话,可以在某个服务下线后防止其他服务调用此服务失败。在项目中可以使用如下方式关闭客户端:

1
2
3
4
5
6
7
8
9
@Autowired
private DiscoveryClient client;

@ResponseBody
@GetMapping("/eurekaUnRegister")
public String shutDown() {
eurekaClient.shutdown();
return "eurekaUnRegistering";
}

直接调用/eurekaUnRegister即可让当前服务下线,记得做好权限控制哦。假设目前有user和order两个微服务,上线后eureka服务中可以看到两个服务已经注册上线:

调用eurekaUnRegister接口:

可以从服务注册中心中看到order服务已经下线,但是order进程还是在的,不影响接口的正常调用。

设置服务的状态

以上的方式都能实现服务的下线,但是有的时候只想要下线某个服务,却不需要发布,等待事情处理完成后上线此服务,则以上方式就做不到了。这时可以通过设置微服务的状态来完成此功能。项目中整合了actuator的话就非常简单了,在项目启动的时候可以看到控制台的输出:

/actuator/service-registry 可以已Get的方式获取当前服务的状态,以Post的方式修改当前服务状态,如将服务设置为Down状态,这样其他微服务接收到此状态后将不调用此服务。将order服务状态设置为Down:

等到流量都没有进来后,需要发布的话直接发布接口,不需要发布可以直接上线当前服务:

这样一个服务的上线和下线就优雅的完成了,如果项目中没有使用Actuator框架,可以模仿Actuator框架的实现方式,详见类:ServiceRegistryEndpoint

总结

以上三种方式都可以实现微服的下线,第三种方式最为优雅,可以主动下线和上线,在没有新流量进来后可以随时发布,这样在也不用等到半夜12点发布了。跟通宵发布说拜拜。

文章中的代码已提交到:
github:https://github.com/cmlbeliever/SpringCloudBucket
码云:https://gitee.com/cmlbeliever/springcloud
工程中包含了微服务的常用实现方式, 欢迎star与fork