实用技巧:Spring Cloud中,如何优雅下线微服务?

标签: Spring Cloud Spring Cloud | 发表时间:2018-12-09 12:15 | 作者:
出处:http://www.itmuch.com/

在生产环境中,服务的上下线是不可避免的,我们希望能够优雅地下线微服务。本文基于Spring Boot 2.x + Spring Cloud Finchley讲解实际项目中优雅下线服务的四种方式,并探讨各方式的优缺点。

:Spring Boot 1.x + Spring Cloud Edgware及之前的方式相同,但配置有区别,本文不做讨论。

方式一:kill java进程【不建议】

使用方式:

     
1
     
kill java进程ID

该方式借助的是Spring Boot应用的Shutdown hook,应用本身的下线也是优雅的,但如果你的服务发现组件使用的是Eureka,那么默认最长会有90秒的延迟,其他应用才会感知到该服务下线, 这意味着:该实例下线后的90秒内,其他服务仍然可能调用到这个已下线的实例。因此,该方式是 不够优雅的 。

方式二: /shutdown 端点【不建议】

Spring Boot提供了 /shutdown 端点,可以借助它实现优雅停机。使用方式:

  • 在想下线应用的 applicationyml 中添加如下配置,从而启用并暴露 /shutdown 端点:

           
    1
    2
    3
    4
    5
    6
    7
    8
           
    management:
    endpoint:
    shutdown:
    enabled: true
    endpoints:
    web:
    exposure:
    include: shutdown
  • 发送POST请求到 /shutdown 端点

           
    1
           
    curl -X http://你想停止的服务地址/actuator/shutdown

该方式本质和方式一是一样的,也是借助Spring Boot应用的Shutdown hook去实现的。

方式三: /pause 端点【生产可用,但有一点缺陷】

Spring Boot应用提供了 /pause 端点,利用该端点可实现优雅下线。

使用方式:

  • 在想下线应用的 application.yml 中添加配置,从而启用并暴露 /pause 端点:

           
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
           
    management:
    endpoint:
    # 启用pause端点
    pause:
    enabled: true
    # 启用restart端点,之所以要启用restart端点,是因为pause端点的启用依赖restart端点的启用。详见:https://cloud.spring.io/spring-cloud-static/Finchley.SR2/single/spring-cloud.html#_endpoints
    restart:
    enabled: true
    endpoints:
    web:
    exposure:
    include: pause,restart
  • 发送POST请求到 /actuator/pause 端点:

           
    1
           
    curl -X POST http://你想停止的服务实例地址/actuator/pause
  • 执行后的效果类似下图:

    下线后的效果图

    如图所示,该应用在Eureka Server上的状已被标记为 DOWN但是应用本身其实依然是可以正常对外服务的。在Spring Cloud中,Ribbon做负载均衡时,只会负载到标记为 UP 的实例上。利用这两点,你可以:先用pause端点,将要下线的应用标记为DOWN,但不去真正停止应用;然后过一定的时间(例如90秒,或者自己做个监控,看当前实例的流量变成0后)再去停止应用,例如 kill 应用 ,当然如果你足够变态, kill -9 也可以

缺点&局限

缺点 描述
不同的版本配置不大一样 早期的Spring Cloud版本中,,pause端点是不依赖restart端点的,后来一个pull request导致pause端点必须依赖restart端点…个人给官方提issue,官方最后选择了继续依赖,我也是醉了……
无法和Eureka的健康检查配合使用 如果你的服务发现组件用的是Eureka,并且你的应用开启了健康检查( eureka.client.healthcheck.enabled = true那么 /pause 端点无效!!!

方式四: /service-registry 端点【生产可用】

使用方式:

  • 在想下线应用的 application.yml 中添加配置,从而暴露 /service-registry 端点:

           
    1
    2
    3
    4
    5
           
    management:
    endpoints:
    web:
    exposure:
    include: service-registry

    发送POST请求到 /actuator/service-registry 端点:

           
    1
    2
           
    curl -X "POST" "http://localhost:8000/actuator/service-registry?status=DOWN" \
    -H "Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8"

    实行后的效果类似如下图:

    下线后的效果图

    由图可知,使用 /service-registry 端点可实现类似 /pause 端点的效果。

缺点

暂时没有发现缺点。

拓展一下

在实际项目中,你可以做一个运维工具:

  • 运维工具读取服务发现组件中的所有服务。
  • 有一天你想下线某个服务的时候,就点击该示例的“优雅下线” 按钮,该按钮会请求到想要下线的服务的 /pause 端点或者 service-registry 端点(看你能不能容忍 /pause 端点的缺点),这样就可以把该实例在Eureka上标记为DOWN,流量过一段时间后就不会打到这个实例上。
  • 做一个流量检测工具(例如QPS统计,这种百度随便找下,最简单的一个过滤器 + map就可以做了),如果检测到当前实例确实已经没有流量进入,就在运维工具上点击另一个按钮,例如停止。真正停止应用。
    • 当然,如何停止应用又是另一个问题了,例如你可以请求实例的shutdown端点(Spring Boot提供了优雅下线的端点),或者用脚本kill,或者如果是容器可以借助一些探针……

相关 [技巧 spring cloud] 推荐:

大话 Spring Cloud

- - IT瘾-dev
研究了一段时间spring boot了准备向spirng cloud进发,公司架构和项目也全面拥抱了Spring Cloud. 在使用了一段时间后发现Spring Cloud从技术架构上降低了对大型系统构建的要求,使我们以非常低的成本(技术或者硬件)搭建一套高效、分布式、容错的平台,但Spring Cloud也不是没有缺点,小型独立的项目不适合使用.

实用技巧:Spring Cloud中,如何优雅下线微服务?

- - 周立的博客 - 关注Spring Cloud、Docker
在生产环境中,服务的上下线是不可避免的,我们希望能够优雅地下线微服务. 本文基于Spring Boot 2.x + Spring Cloud Finchley讲解实际项目中优雅下线服务的四种方式,并探讨各方式的优缺点. 注:Spring Boot 1.x + Spring Cloud Edgware及之前的方式相同,但配置有区别,本文不做讨论.

Spring Cloud限流详解 | Spring Cloud|周立

- -
限流往往是一个绕不开的话题. 本文详细探讨在Spring Cloud中如何实现限流. Zuul上实现限流是个不错的选择,只需要编写一个过滤器就可以了,关键在于如何实现限流的算法. 常见的限流算法有漏桶算法以及令牌桶算法. https://www.cnblogs.com/LBSer/p/4083131.html,写得通俗易懂,你值得拥有,我就不拽文了.

Spring Cloud Kubernetes指南

- -
当我们构建微服务解决方案时,SpringCloud和Kubernetes都是最佳解决方案,因为它们为解决最常见的挑战提供组件. 但是,如果我们决定选择Kubernetes作为我们的解决方案的主要容器管理器和部署平台,我们仍然可以主要通过SpringCloudKubernetes项目使用SpringCloud的有趣特性.

Spring Cloud 快速入门

- - IT瘾-tuicool
Spring Cloud 是一套完整的微服务解决方案,基于 Spring Boot 框架,准确的说,它不是一个框架,而是一个大的容器,它将市面上较好的微服务框架集成进来,从而简化了开发者的代码量. 本课程由浅入深带领大家一步步攻克 Spring Cloud 各大模块,接着通过一个实例带领大家了解大型分布式微服务架构的搭建过程,最后深入源码加深对它的了解.

Deploy the spring cloud project using jenkins

- - Telami
先简单记录下Jenkins部署maven聚合工程要点. Root pom配置成项目根目录的pom.xml. maven命令单独install 欲构建的项目. 选项后可跟随{groupId}:{artifactId}或者所选模块的相对路径(多个模块以逗号分隔). 表示同时处理选定模块所依赖的模块. 表示同时处理依赖选定模块的模块.

Spring Cloud Gateway(限流) | Wind Mt

- -
限流可以保障我们的 API 服务对所有用户的可用性,也可以防止网络攻击. 一般开发高并发系统常见的限流有:限制总并发数(比如数据库连接池、线程池)、限制瞬时并发数(如 nginx 的 limit_conn 模块,用来限制瞬时并发连接数)、限制时间窗口内的平均速率(如 Guava 的 RateLimiter、nginx 的 limit_req 模块,限制每秒的平均速率);其他还有如限制远程接口调用速率、限制 MQ 的消费速率.

快速突击 Spring Cloud Gateway

- - 掘金后端
认识 Spring Cloud Gateway. Spring Cloud Gateway 是一款基于 Spring 5,Project Reactor 以及 Spring Boot 2 构建的 API 网关,是 Spring Cloud 微服务生态的主要组件之一. Spring Cloud Gateway 主要负责接口请求的路由分发,并且支持对请求的安全验证,流量监控和流量控制等扩展操作.

Spring Cloud Gateway2.0实践报告

- - 掘金后端
你的点赞就是对我最大的支持. 原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处. 本文将从知识拓扑讲起,谈一下api网关的功能,以及spring cloud gateway的使用方法. 一、知识拓扑 (使用和原理) 二、网关的作用 三、Predicate,路由匹配 四、Filter,过滤器编写 五、自定义过滤器 六、常见问题 复制代码.

微服务框架Spring Cloud介绍 Part2: Spring Cloud与微服务

- - skaka的博客
之前介绍过 微服务的概念与Finagle框架, 这个系列介绍Spring Cloud.. Spring Cloud还是一个相对较新的框架, 今年(2016)才推出1.0的release版本. 虽然Spring Cloud时间最短, 但是相比我之前用过的Dubbo和Finagle, Spring Cloud提供的功能最齐全..