spring cloud 学习(7) - 生产环境如何不停机热发布?
业务繁忙的系统,原则上是不允许停机的,那么问题来了,如果真有严重的bug要修复,不得不发布,怎么做到不停机发布,对业务无感知呢?
eureka 提供了一系列rest url,可以对注册实例进行操作,比如:将服务离线/上线,注册/注销,动态修改meta元数据等,详情见本文最后的参考wiki。
不停机发布的思路:
通常spring-cloud微服务是以集群方式部署的,而且内网微服务,通过zuul网关来进行访问,再次搬出上一篇中的示意架构图:
zuul网关层一般只是用于路由转发等轻量级的处理,不会涉及太多复杂的业务逻辑,发布相对较少,经常修改的多半是背后的微服务,对于微服务的不停机发布,思路如下:
1、先将目标机的服务状态调整成“下线”
即:利用 PUT /eureka/apps/appID/instanceID/status?value=OUT_OF_SERVICE 这个rest接口
shell终端下,可以类似下面这样直接输入:
curl -X PUT -i -H "Authorization:Basic d2**G9zOndSVEwxaUpaRVp3MFBU****" http://10.1.2.3:7001/eureka/apps/DEMO-SERVICE/10.0.2.*:7031/status?value=OUT_OF_SERVICE
注:
-X PUT 表示这是PUT请求
-H 表示设置http头,如果背后的微服务,启用了basic auth安全认证,不加头的话,会提示没有权限,至于Authorization:Basic 后面的这一串密文是怎么来的,后面会讲到
http://10.1.2.3:7001/ 这是eureka-server所在的ip或域名
DEMO-SERVICE 是要下线的服务名称
10.0.2.*:7031 是服务实例的instanceId
参数下图:
当然,上面这个请求,也可以用postman之类的图形化工具来进行:
对于设置了Basic Auth的微服务,可参考上图,设置用户名、密码,然后点击Update Request,就得到了Header中的值(如下图)
调用成功后,再回到eureka server中观察,可以发现该服务已经下线:
注:下线后,还要经过几次心跳,zuul才会感知到这台节点的变化,建议下线后,先等待1-2分钟,这样新的请求,就不会通过zuul转发到这台目标机器。
2、对目标机进行常规发布
经常刚才的步骤,目标机上已经没有新请求进来,可以相对安全的进行程序更新发布
注:如果发布过程中,一般要先停止应用,建议用kill pid,不要带-9强杀,以防万一还有未执行完成的请求。另外,发布重启后,也建议等待1-2分钟,等应用彻底启动好,并注册到eureka server上,让zuul感知该节点已重新上线。
3、对其它节点重复1,2的操作。
其它技巧:
上一篇还提到了如何做灰度发布,其原理是通过meta-map元数据来实现,发布完成后,也可以通过eureka的rest url来动态修改元数据,让指定节点变成灰度机器,类似:
curl -X PUT -i -H "Authorization:Basic d2lucG9zOndSVEwxaUpaRVp1MFBUMm9=" http://10.0.19.71:7001/eureka/apps/DEMO-SERVICE/10.0.19.73:7031/metadata?gated-launch=true
参考文章:
https://github.com/Netflix/eureka/wiki/Eureka-REST-operations
- 码农的瑞士军刀-脚本语言
- shell基础学习总结(一) (r3笔记第63天)
- 关于sysdba,sysoper,dba的区别(r3笔记第62天)
- 使用句柄实现特定场景的无备份恢复 (r3笔记第61天)
- 关于dual表的破坏性测试(r3笔记第60天)
- 哈希现金(Hashcash)与“工作量证明”
- 关于oracle中的sql数据类型(r3笔记第59天)
- 使用awr来分析sesson leak问题(r3笔记第78天)
- 弹窗层效果的实现(非jQuery实现)
- 简单的导航栏实现
- js实现css3的过渡,需要注意的一点(浏览器优化)
- 居中详解
- 通过pl/sql计算程序的运行时间(r3笔记第77天)
- 操作系统存储管理和oracle数据库(第一篇) (r3笔记第76天)
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- SpringBoot使用Mybatis 快速入门
- 【CTR】ESMM:多任务联合学习
- 状态管理之Vuex (三) store利用module拆分
- MySQL 案例:无主键表产生的延迟
- 面试官真的会问:new的实现以及无new实例化
- Android Hilt实战初体验: Dagger替换成Hilt
- Linux系列之学会使用CURL命令
- 潘石屹用python解决100个问题 | 斐波那契数列
- [869]pandas的dataFrame的行列索引操作
- JSP的文件上传处理
- 将SAP CRM WebClient UI的表格导出成PDF
- java.lang.ClassNotFoundException org.w3c.dom.ElementTraversal
- docker一键部署SpringBoot项目
- 【Flutter 专题】95 图解 Dart 单线程实现异步处理之 Task Queue
- 首发基于OpenPAI细化部署 Hadoop 集群