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

abd5e48c10a51a538ff8d50fa4ba4bc3.png

问题

互联网产品高速迭代,通常伴随着高频次的版本发布。部署新版上线需要重启服务,直接 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 版本

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334254.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

苹果电脑 Mac OS X 系统诞生的故事和发展历史

文章目录CoplandNeXTRhapsodyOS XPublic Beta (Kodiak)Mac OS X v10.0 (Cheetah)Mac OS X v10.1 (Puma)Mac OS X v10.2 (Jaguar)Mac OS X v10.3 (Panther)Mac OS X v10.4 (Tiger)Mac OS X v10.5 (Leopard)Mac OS X v10.6 (Snow Leopard)Mac OS X Lion2001 年 3 月 24 日&#x…

Mac OS 的历史

文章目录概述1980年代前20世纪80年代20世纪90年代2000年以后概述 纵观电脑之历史,操作系统与计算机硬件的发展息息相关。 操作系统之本意原为提供简单的工作排序能力,后为辅助更新更复杂的硬件设施而渐渐演化。 从最早的批处理模式开始,分…

java 反射 速度_Java反射,但速度更快

java 反射 速度在编译时不知道Java类的最快方法是什么? Java框架通常会这样做。 很多。 它可以直接影响其性能。 因此,让我们对不同的方法进行基准测试,例如反射,方法句柄和代码生成。 用例 假设我们有一个简单的Person类&#x…

macOS 内核之 OS X 系统的起源

文章目录一、苹果公司早期(1972-1991)二、苹果在操作系统上的尝试(1991-1997)2.1 Star Trek 项目 (1992-1993)2.2 Copland-Mac OS 8 (1994-1996)三、收购与转折(1996-1997)四、NeXT 篇章4.1 NEXTSTEP(1985-1997)4.2 OpenStep(1993-1997)五、Mach 的历史5.1 Rochester’s Intell…

docker create_Docker动手教程2.2:容器基本操作2

内容摘要暂停/取消暂停容器删除容器进入容器创建容器暂停/取消暂停容器暂停容器命令:docker pause 容器ID/容器名注意STATUS列,被暂停的容器的状态依旧是“Up”,但是后面括号显示为“Paused”。取消暂停命令:docker unpause 容器I…

关于 Mac OS X 内核技术来源

Mach(Multiple Asynchronously Communication Hosts) 是一个由卡内基梅隆大学开发的操作系统内核,Mach的开发是为了取代BSD的UNIX核心。 Mach 内核的设计目标之一是要兼容 Unix 系统。 当初他们的设想是,真正的操作系统可以作为一…

用C语言编程画出图形,C语言图形编程(六) -图形程序设计实例:零件图形的绘制...

实例:一个零件图形的绘制有一个零件图,如下:对图3-1中的零件图形,如何根据它所标注的尺寸,按照适当的顺序有步聚地画出该图形,这首先要分析此零件图形的几何关系,了解构成这个图形各线段的性质&…

mfc怎么获取进程的线程数_Python多线程获取小米应用商店App,看看我是怎么做到的

一、【项目背景】小米应用商店给用户发现最好的安卓应用和游戏,安全可靠,可是要下载东西要一个一个的搜索太麻烦了。而且速度并不是很快。今天小编就教大家利用多线程爬取小米应用商店的游戏模块,快速获取我们想要的软件安装包。二、【项目目标】目标 &a…

Linux Distribution Timeline for 2010(Linux 2010 年发行版时间线/族谱/发展图)

此图来自维基百科(wikimedia),具体地址为:https://commons.wikimedia.org/wiki/File:Linux_Distribution_Timeline.svg?uselangzh-hans#filehistory

git强制推送_Git 常用命令

Git 常用命令总结1. GIT 工作区add commitworking directory ------- index(stage) ---------- HEAD | | | | | | 工作目录 暂存区 …

golang 泛型_Golang 1.x版本泛型编程

本文介绍了Golang 1.x版本的泛型编程。往期回顾:浅谈动态追踪技术Go是一门天生为服务器程序设计的简洁的语言,因此Go的设计原则聚焦在可扩展性、可读性和并发性,而多态性并不是这门语言的设计初衷,因此就被放在了一边。虽然在2.0版…

jwt令牌_JWT令牌的秘密轮换

jwt令牌当您使用JSON Web令牌 ( JWT )或需要对有效载荷信息进行签名或加密的任何其他令牌技术时,设置令牌的到期日期很重要,因此,如果令牌到期,则可以假定这可能被视为安全漏洞,您拒绝使用此令牌…

jasperreports_JasperReports:棘手的部分

jasperreports如果您使用Java进行编程的时间足够长,则有可能需要为业务用户生成报告。 就我而言,我已经看到几个项目使用JasperReportsLibrary来生成PDF和其他文件格式的报告。 最近,我荣幸地观察了Mike和他的团队使用上述报告库以及他们所面…

电脑运行adb闪退_adb+python进阶使用

之前文章有提到过使用python加adb刷视频,今天带来进阶版——无线多台手机。首先要使用adb连接多台手机,手机和电脑肯定要在统一局域网内。1.打开手机开发者模式,并通过USB接口链接电脑。2.打开cmd:输入adb tcpip 5555, 会得到相关…

java office在线编辑_国外10个最受欢迎的 Java 开发的 CMS 系统

CMS是Content Management System的缩写,意为"内容管理系统",它具有许多基于模板的优秀设计,可以加快网站开发的速度和减少开发的成本。CMS的功能并不只限于文本处理,它也可以处理图片、Flash动画、声像流、图像甚至电子…

apache kafka_Apache Kafka简介

apache kafka什么是Apache Kafka? Apache Kafka是一个分布式流系统,具有发布和订阅记录流的功能。 在另一方面,它是企业消息传递系统。 它是一个快速,水平可扩展和容错的系统。 Kafka有四个核心API, 生产者API&#x…

人脸特征值能存放在sql server中吗_SQL运行内幕:从执行原理看调优的本质

原文链接:https://www.cnblogs.com/arthinking/p/13205303.html相信大家看过无数的MySQL调优经验贴了,会告诉你各种调优手段,如:避免 select *;join字段走索引;慎用in和not in,用exists取代in&a…

rest资源设计_REST资源何时应获得其自己的地址?

rest资源设计在纯粹的REST方法中,所有端点(起始端点除外)都是不透明的,因此不需要发布其各种详细信息。 即使使用这种方法,本文中的要点也很重要,因为服务器逻辑将必须确定何时需要结束点。 介绍 在REST体…

ckeditor回显带标签_Spring Boot中带有CKEditor的AJAX

ckeditor回显带标签1.概述 在本文中,我们将介绍如何在Spring Boot中使用CKEditor 。 在本教程中,我们将导入一个包含大量数据的XML文档,对使用GET请求将一组数据加载到CKEditor实例的能力进行编程,并执行POST请求以保存CKEditor的…