springcloud中微服务的优雅停机(已验证)

 大部分项目部署中,为了方便,可能都直接使用kill -9 服务的pid来停掉服务。

但是由于Eureka采用心跳的机制来上下线服务,会导致服务消费者调用此已经kill的服务提供者然后出错。

可以采用以下方式来解决:

核心是先调用方法主动通知Eureka注册中心服务下线,然后再停掉服务。

本文会介绍几种eureka 注册中心服务下线的方式

最不可取的就是直接使用kill命令停掉服务。

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

1、直接关闭服务

kill -9 没有善后

kill -15  有善后 会发送down状态到eureka server

kill java进程【不建议】

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

2、向eureka 注册中心发送delete 请求,只是取消注册服务, 当发送心跳时还是会注册到eureka

格式为   eureka地址/eureka/apps/服务名称/实例名称

请求方式为delete

下面是取消注册一个服务的例子。

 下图是用postman 发送delete请求

3.通过eureka变更服务状态的方式实现服务上下线,不会再发送心跳注册到eureka server

4. 客户端主动通知注册中心下线,下线后不会再注册到eureka了

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

1import org.springframework.web.bind.annotation.RequestMapping; 2import org.springframework.web.bind.annotation.RequestMethod; 3import org.springframework.web.bind.annotation.RestController; 4 5import com.netflix.discovery.DiscoveryManager; 6import com.shm.common.model.RespVO; 7import com.shm.common.util.RespUtil; 8 9@RestController 10public class OfflineController { 11 12 13 @RequestMapping(value = "/offline", method = RequestMethod.GET) 14 public RespVO<Object> offLine(){ 15 DiscoveryManager.getInstance().shutdownComponent(); 16 return RespUtil.success(); 17 } 18 19 20}

5、设置服务的状态,可通过状态变更来实现再eureka的上下线

pom中加入

1actuator的包 2 3<dependency> 4 <groupId>org.springframework.boot</groupId> 5 <artifactId>spring-boot-starter-actuator</artifactId> 6 </dependency>

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

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

 

看下执行后的效果:

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

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

如果要再上线:

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

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

SpringCloud服务如何在Eureka安全优雅的下线

Springcloud服务如何在Eureka安全优雅的下线如果直接kill9Springcloud的服务,因为Eureka采用心跳的机制来上下线服务,会导致服务消费者调用此已经kill的服务提供者然后出错,处理这种情况有2中方案。一、利用SpringBootActuato的管理端点(推荐)1、pom中引用Actuato<de

SpringCloud注册中心高可用搭建

SpringCloud的注册中心可以由Eureka、Consul、Zookeeper、ETCD等来实现,这里推荐使用SpringCloudEureka来实现注册中心,它基于Netfilix的Eureka做了二次封装,完成分布式服务中服务治理的功能,微服务系统中的服务注册与发现都通过这个注册中心来进行管理。引入EurekaServer依赖

Golang注册Eureka的工具包goeureka发布

1.简介提供Go微服务客户端注册到Eureka中心。点击:github地址(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2FSimonWang00%2Fgoeureka),欢迎各位多多star!(已通过测试验证,用于正式生产部署)2.原理