问题

互联网产品高速迭代,通常伴随着高频次的版本发布。部署新版上线需要重启服务,直接 kill 服务进程可能会造成服务短暂不可用,从而影响到正在使用的用户。

Spring Cloud 项目中一般会用到 Ribbon 作为负载均衡,那么是不是只要保证每个服务部署多台服务器,发布时采用 Rolling Update 分批次部署,保证一部分服务器正常提供服务的同时发布另一部分服务器,Ribbon 就能自动切换,保证服务的不间断?然而并不是。

产生原因

所有服务的状态保存在注册中心,即 Eureka Server。一个服务要想获取其他服务的实例列表和状态,需要通过 Eureka Client 定时从 Eureka Server 中获取并缓存下来,默认时间间隔是30秒。Eureka Client 和 Eureka Server 是通过 HTTP 协议通信,请求由 Eureka Client 发起,而不是基于长连接或者 Eureka Server 主动推送,所以无法立即知道其他服务状态变更。

即使同一个服务部署多台机器,每台机器依次发布,当其中一个服务实例重启时,服务调用方是无法第一时间知道的,所以还是会调用到这台暂时无法提供服务的实例上。这样会造成短暂的访问失败,这段时间也会对正在使用产品的用户造成一定的影响。

解决方案

基于以上的原因,在部署应用时应该按照以下步骤进行(为了简单起见,假设一个应用部署两个实例):

  1. 将服务的一个实例在注册中心的状态设置为 DOWN
  2. 等待一段时间,直到其他服务缓存刷新,不再调用到这台服务器上
  3. 停止服务,更新代码,重新启动,等待,直到启动成功

完成后,再重复以上步骤部署另一个实例。

第一步:修改服务实例状态为 DOWN

有两种方案可以修改实例的状态,选择其一即可:

  1. 直接调用 Eureka Server API 修改:PUT /eureka/apps/{appID}/{instanceID}/status?value=DOWN
  2. 调用服务实例对应的 actuator endpoint:/service-registry

我更偏向使用方法二,对应的命令:

curl -H "Content-Type:application/json" -X POST http://{host:port}/actuator/service-registry?status=DOWN

如果 actuator endpoint 加了 Spring Security Basic 认证,则还需要加上用户名和密码:

curl -H "Content-Type:application/json" -X POST -u {username}:{password} http://{host:port}/actuator/service-registry?status=DOWN

第二步:等待其他服务缓存刷新

具体要等多久,其他调用者的请求才会不再访问到这台状态为 DOWN 的实例?这里涉及到三个配置项:

  • eureka.client.registryFetchIntervalSeconds Eureka 客户端每隔多久去 Eureka 服务器拉取最新的注册信息,默认值 30(秒)。
  • ribbon.ServerListRefreshInterval Ribbon 的缓存刷新间隔时间,默认 30000(毫秒)。Eureka 客户端拉取到最新注册信息后,Ribbon、Feign 等组件不会立即生效,是因为 Ribbon 还有一层缓存。
  • eureka.server.responseCacheUpdateIntervalMs Eureka Server 返回最新的注册信息的接口缓存刷新时间间隔,默认 30000(毫秒)。有时候会看到 Eureka 页面和 /eureka/apps 接口的服务状态不一致,就是因为 /eureka/apps 接口默认会有 30 秒缓存。

在默认情况下,当一个服务状态改为 DOWN,最长可能需要 30+30+30 秒,所有的缓存才会刷新,其他调用者才不会调用到这个状态为 DOWN 的实例。这就意味着修改服务实例状态为 DOWN 后需要等待 90 秒,才能进行下一步操作。

为了让部署时间缩短,可以将以上三个配置项都修改为5秒:

Eureka Server:

eureka:server:responseCacheUpdateIntervalMs: 5000

Eureka Client(即各个服务):

ribbon:ServerListRefreshInterval: 5000
eureka:client:registryFetchIntervalSeconds: 5

完成以上配置,部署时将实例状态设为 DOWN 后,只需要等待 15 秒即可停止进程:

sleep 15s

第三步:实例部署

这一步主要需要注意

  • 尽量不要使用 kill -9 pid 强制杀掉进程,而应该使用 kill pid 或者 kill -15 pid 关闭进程。使用 kill pid 或者 kill -15 pid 关闭进程之前,Eureka Client 会给 Eureka Server 请求删除自己,后续服务再次启动后会重新注册为 UP 状态。如果使用 kill -9 pid 强制杀掉进程,Eureka Client 没有办法注销自己,Eureka Server 就不知道该实例已下线,直到长时间收不到心跳才会删除该实例。如果在 Eureka Server 删除实例之前实例启动了,那么它的状态还是会保持 DOWN 状态。如果确实需要用到 kill -9 pid 强制杀掉进程,那么服务重启后需要再通过第一步的方式将实例状态设为 UP。
  • 服务启动后,需要等待并确认启动成功后,才可以开始部署下一台服务器。这里我们可以定时去请求 Spring Boot 提供的 actuator endpoint /health 接口,例如每隔 1 秒请求一次,直到接口可以正常访问,即可认为服务启动成功。

本文基于 Spring Boot 2.1.x 及 Spring Cloud Greenwich 版本

my.ini修改后服务无法启动_Spring Cloud Eureka 服务实现不停机(Zero-downtime)部署相关推荐

  1. eureka 客户端服务启动了又失败了_Spring cloud Eureka服务注册与发现详解

    一.Eureka概述 (1)Eureka是什么 Eureka是一个用于服务注册与发现的框架,本身是一个基于Rest的服务. (2)Eureka的组件有哪些? Eureka的组件可分为Eureka Se ...

  2. blog微服务架构代码_Spring Cloud微服务架构代码结构详细讲解

    上一篇我们介绍了spring cloud云服务架构 - particle云架构代码结构,简单的按照几个大的部分去构建代码模块,让我们来回顾一下: 第一部分: 针对于普通服务的基础框架封装(entity ...

  3. 服务器修改密码sql打不开了,服务器管理员密码修改后SQL_Server_2008无法启动

    服务器管理员administrator密码修改后SQL_Server_2008无法启动 其实很简单,我发现在网上找这个相关的问题,什么说法都有,把人绕的晕头转向的 我来教大家如何解决这个问题: 首先我 ...

  4. 引入springcloud报错。common依赖找不到_微服务架构:spring cloud之服务注册和服务发现...

    SpringCloud主要提供的模块包括:服务发现(Eureka),断路器(Hystrix),智能路有(Zuul),客户端负载均衡(Ribbon),Archaius,Turbine,Eureka为微服 ...

  5. my.ini修改后服务无法启动_教你发布vue+.netCore项目到服务器

    最近一直在做项目,发布部署的事情都是同事或者老大做的,无奈什么事都要自己尝试经历后才能记住,所以发布的事情轮到我了,由于是第一次发布部署项目到一个新的服务器环境,难免会遇到各种各样的问题,总结下来,希 ...

  6. springcloud项目的启动顺序_Spring Cloud微服务项目完整示例,含注册中心,网关,断路器等等...

    Spring Cloud微服务项目完整示例 目的是为了演示基于Spring Cloud微服务框架,搭建一个接近业务实际场景的项目,只实现了后端项目,前端可以使用VUE或者其他框架. 后端框架包括注册中 ...

  7. cassss服务未启动_systemd时代的服务管理

    systemd时代的服务管理 使用systemd做服务管理时,需要了解一些基本知识: 了解systemd可管理哪些服务 了解systemd所管理服务的状态 了解systemctl管理服务的基本命令 学 ...

  8. 计算机环境安全容器服务未启动怎么解决,音频服务未运行|音频服务未启动 - 音频服务未运行的解决办法 - 安全专题...

    最近许多网友在使用电脑时遇到了"音频服务未运行"的错误提示,出现这种提示的原因有很多,症状也不尽相同.今天我们就针对不同的"音频服务未运行"症状进行分析解答,希 ...

  9. mysql错误1053 服务没有及时响应启动或控制请求_windows服务安装启动报错误1053:服务没有及时响应启动或控制请求...

    用.net 开发了一个C#语言的windows服务,在本地和测试环境,安装启动都正常,在新的线上环境报错,不能启动-报出-错误1053:服务没有及时响应启动或控制请求. 后来发现时线上.NET FRA ...

最新文章

  1. 服务器端linux发行版的选择
  2. java整理软件--- Java OCR 图像智能字符识别技术,可识别中文,但是验证码不可以识别...已测识别中文效果很好...
  3. 深潜百米,采用半缆通信技术的Gladius水下无人机能够征服海洋吗?
  4. 技术面试官的一些建议
  5. 设计模式 ---适配器模式
  6. android 判断 string 是否是字母数字,Android中判断字符串中必须包含字母或者数字...
  7. 10桌面管理文件收纳_二十余件精选桌面好物推荐,让学习工作生活满满正能量!...
  8. 项目部署—Linux命令安装redis
  9. spring异常处理-HandlerExceptionResolver
  10. 友盟统计集成_友盟+智能超链U-Link,助力开发者拥有更极致的分享体验_互联网_科技快报...
  11. 个人开源项目之快速检索算法
  12. 计算机在工业工程中的应用,在工业工程中信息技术的应用原稿(全文完整版)...
  13. svm分类代码_SVM的原理及实现垃圾邮件分类代码解析:
  14. 服务器版dll修复工具,dll修复工具
  15. 程序员用C/C++打造车牌识别系统!同学眼中只有膜拜!
  16. HTML基础入门教程
  17. scratch作品导出html5,抓取scratch源码,使用二进制方式保存。
  18. rpc调用 java_RPC调用的简单实现
  19. Thinkpad SL400开启蓝牙
  20. 关于使用克莱姆法则和矩阵消元法解线性方程组的效率的比较

热门文章

  1. java-ee-api_刷新器-Java EE 7概览
  2. 香草 jboss 工具_如何为JBoss Developer Studio 8设置BPM和规则工具
  3. 高效应用程序的7个JVM参数
  4. netbeans 定制代码_将NetBeans代码模板弯曲到我的意愿
  5. 适用于Java开发人员的Elasticsearch:命令行中的Elasticsearch
  6. openshift用户管理_OpenShift Express Web管理控制台:入门
  7. java web服务_将Java服务公开为Web服务
  8. teamcity_TeamCity工件:HTTP,Ant,Gradle和Maven
  9. Lucene查询(搜索)语法示例
  10. morphia_Morphia和MongoDB:不断发展的文档结构