关于架构设计:应用不停机发布的思考与初识-IDCF

7次阅读

共计 7148 个字符,预计需要花费 18 分钟才能阅读完成。

利用公布,简略来说就是将已开发实现的零碎性能部署到生产环境,并可失常对用户提供服务。

传统的利用公布步骤个别采纳“三步曲”:

  • 第一步:进行利用
  • 第二步:更新利用
  • 第三步:启动利用

那你必定会问,从进行利用始终到启动利用期间,零碎性能是不是无奈失常应用?

没错。在利用公布过程中,可能会呈现页面白屏、拜访超时等各种异样,而且个别会继续很久,所以公布工夫基本上都集中在凌晨,考究点的可能就配上一句敌对提醒“零碎正在保护,请稍后拜访!”。

这种状况大部分都呈现在传统行业,起因可能是感觉没有必要,因为:

  • 传统行业的业务个别都集中的日间,也就是说凌晨根本没有业务,或者非重要业务
  • 就算凌晨无奈应用这些性能,感觉也没关系,第二天再来就是了,客户又不会跑了

但真的是这样吗?现在越来越多的传统行业,都在向互联网服务模式转型,其服务次要特点:“全天”不间断为客户提供“优质”的“线上”服务,拆分一下关键词

  • “全天”代表着任何工夫
  • “优质”代表着客户体验
  • “线上”代表着线上自助

所以说,一个优质的客户服务势必会对服务可用性提出更高的要求,而传统的停机公布岂但会对客户造成应用影响,还会变向对企业造成非间接经济损失。

例如:客户体验降落导致的客户散失

仅此而已?非也!作为已经也同样是一名运维工程师的我来说,凌晨公布粗茶淡饭,还时不时来一次长达 8 小时的“短途之旅”,身材就间接被掏空,加上第二天还在“补血”中,还会被各种骚扰电话轰炸,这几乎就是一场噩梦。

由此可见,利用不停机公布的重要性,通过它能够帮忙咱们:一是在利用公布过程中线上服务继续可用,晋升服务可用性,二是可在白天或是任何工夫公布,晋升运维人员的机动性。

那么咱们须要怎么做,能力实现利用不停机公布呢,那接下来就让咱们进入正题。

part 1

利用不停机公布,从字面上很好了解,就是利用公布过程中服务不中断。

但认真回忆一下,原先利用公布过程中,反正服务会中断,那就在利用公布实现后,通过网络屏蔽内部流量的形式,先进行外围或罕用性能的外部验证,在确保没有问题后,再解除网络屏蔽,并对外提供服务。

那当初呢?利用公布后间接对外?不须要进行外部或小流量验证?想必每个人的答案都有所不同。对此,能够对利用不停机公布能力,简略定义三个成熟度。

成熟度 成熟度能力
成熟度一级 利用公布过程服务不中断
成熟度二级 利用公布过程服务不中断,单利用性能可先进行外部 / 小流量验证
成熟度三级 利用公布过程服务不中断,多利用(联动)性能可先进行外部 / 小流量验证

注:不同的成熟度对技术能力的要求会有所不同,倡议通过逐渐演进的形式来晋升成熟度,并在演进过程中对不同的技术能力进行验证,从而不断完善。

有人会说蓝绿公布,或有人会说滚动公布,灰度公布就能够实现以上能力。但其实,这些答案并不精确,或者说并不全面,它们虽有交加,但无奈涵盖。

既然提到公布模式,那咱们先来简略比拟一下几种公布模式的优缺点。

蓝绿公布 滚动公布 灰度公布
资源老本 生产等比例资源投入,老本较高 根本无需额定资源投入,老本较低 根本无需额定资源投入,老本较低
回滚时长 两套环境间接切换,时长较短 依据滚动速率决定,时长较长 灰度局部实例回滚,时长适中
技术难点 资源齐全隔离,技术难点较低 需制订滚动策略,技术难点适中 引入流量路由能力,技术难点较高
影响范畴 影响所有用户,影响面较大 影响所有用户,影响面较大 影响大量用户,影响面较小

注:大部分的技术文章里都会提到,可通过以上任何一种公布模式,做到用户无感知的利用公布,但在理论状况下,并不齐全足够,还须要通过一些辅助伎俩组合在一起能力实现。

联合以上公布模式的优缺点,如果你的组织在基础架构技术能力上曾经十分成熟,那么灰度公布肯定是最佳之选,但如果还处于初级阶段,那可能并不是,而蓝绿公布的资源投入较高,也不是一种十分好的抉择。

剩下的只有滚动公布,但滚动公布的公布策略会比较复杂,特地在容器环境下,同一利用多个服务实例的滚动策略还须要独自来实现。

所以,后期能够抉择一种折中的形式,即:独自搭建一套预发验证环境,利用架构需对齐生产环境,但容量方面能够最小化,个别一个利用至多 2 个服务实例。

这样,咱们就能够在对生产环境做利用公布前,当时对生产预验证环境进行利用公布,公布后仅对外部用户可见,验证通过后,再对生产环境采纳全量利用公布。

part 2

利用不停机公布是一项综合性能力,当明确好一种公布模式后,就须要逐渐辨认会波及到哪些技术组件,以及明确技术组件在整个解决方案中所负责的职责边界,从而使它们可能互相协同工作。

如下列举了一些次要的技术组件:

技术组件 职责边界
利用治理平台 次要负责管制整个利用公布流程,以及集成并调度不同的技术组件,协同实现利用不停机公布
负载平衡(4 层) 次要负责服务申请的流量接入,可依据所辨认的流量特色,负载散发到不同的负载平衡(7 层)
负载平衡(7 层) 次要负责服务申请的流量路由,可依据所辨认的流量特色,路由散发到同一利用的不同实例
容器 / 虚拟机平台 次要负责容器 / 虚拟机资源管理,包含容器 / 虚拟机的创立、更新、销毁等
域名解析零碎 次要负责域名地址治理,包含域名的注册、更新、解析等,以及提供用户拜访利用或利用间拜访等寻址能力
注册核心 次要负责服务资源管理,包含服务的注册、更新、登记等,以及提供服务申请方发现服务提供方的能力

在明确技术组件后,还须要对技术组件进行正当的架构布局,以适配不同的网络架构要求。

本次次要将对负载平衡进行特地阐明,一方面它是负责解决流量的核心技术组件,另一方面网络架构的不同,对它的部署架构影响可能也是最大的。

在传统的网络架构环境中,出于对网络安全或其余思考因素,通常会划分出多个不同的网络区域,网络区域间的拜访须要通过开设防火墙拜访策略才能够进行互通。

但这种形式必然会对应用服务间间接进行点对点拜访的形式造成影响,次要起因是虚拟机或容器环境中,利用的 IP 地址可能会发生变化,导致无奈提前明确防火墙拜访策略。

所以,个别都会思考应用负载平衡(代理模式)来解决这个问题。

倡议后期优先选择计划三,尽管链路较长会小幅影响性能,但此部署计划绝对较为成熟,一方面能够防止流量负载不均的问题,另一方面对于利用的革新老本也会绝对较低。

注:除网络区域隔离会遇到这种状况外,在某些网络架构中,不同的容器集群间也同样无法访问,所以也同样实用。

另外,除必要状况下,也应尽量减少跨网络区域或跨容器集群间的拜访,例如:优先容器集群内路由拜访,跨网络区域频繁交互的应用服务倡议迁徙至同一网络区域等。

负载平衡通常能够分为 4 层模式和 7 层模式,其中 4 层更关注流量负载,而 7 层更关注流量路由。

个别倡议将负载平衡(4 层)和负载平衡(7 层)进行分层部署,以充分发挥它们的强项。

倡议后期优先选择计划二,尽管无奈实现多容器集群间的全局流量调度,但对于以后可观测性和排障能力还不够健全的组织,通过物理隔离升高运维难度也是一种不错的抉择。

综上架构决策,最终的全局流量链路大抵如下,默认状况下,数据中心间流量隔离,即:单数据中心流量收敛,但可依据理论状况进行选择性放行。

part 3

利用不停机公布的根底是服务路由,在这里,咱们能够把应用服务分为两种角色,服务申请方或服务提供方,而服务申请方通过不同的寻址形式,最终拜访到服务提供方的模式,能够称之为服务路由。

服务路由能够分为南北向和东西向。

  • 南北向:服务申请方—> 负载平衡(4 层)—> 负载平衡(7 层)—> 服务提供方
  • 东西向:服务申请方—> 服务提供方

不难发现,其次要区别就是,南北向服务申请方需借助负载平衡(代理模式)拜访服务提供方,而东西向服务申请方间接拜访服务提供方。

注:域名解析后果会缓存在本地,可缓解域名解析服务压力,但缓存工夫应依据不同的服务水平进行评估,否则将会缩短解析地址切换及故障转移时长。有条件的话倡议采纳 httpdns 来解决本地缓存问题。

但不论是南北向还是东西向,服务提供方在被拜访前,得让服务申请方感知或可见,常见的形式次要有两种,一种是不依赖注册核心的,而另一种则是依赖注册核心的。

如果以后利用架构上暂未应用微服务框架,即:不依赖注册核心,服务提供方能够手动或主动将服务在负载平衡上进行服务注册,服务申请方间接调用负载平衡。

如果以后利用架构上曾经应用微服务框架,即:依赖注册核心,服务提供方能够在注册核心上进行服务注册,服务申请方在注册核心进行服务发现,或者由负载平衡在注册核心进行服务发现,服务申请方间接调用负载平衡。

注:在多注册核心的场景下,可通过对立注册核心实现异构注册核心的服务发现

另外,咱们还会对同一利用的不同服务实例进行分组,分组策略可依据不同的条件来决定,例如:不同环境、不同版本等。

假如依据不同环境(预生产环境和生产环境)这个条件,能够把部署在预发验证环境的应用服务分为预发组,把部署在生产环境的应用服务分为线上组。

而后通过配置路由策略,下发到负载平衡或应用服务,就能够实现简略的服务路由了。

例如:不同分组间默认状况下不容许服务路由,但非凡场景下容许预发组服务路由至线上组。

注:若服务申请方是前端页面或客户端,也能够对前端流量也进行分组,例如:依据网络环境,将接入公司 WI-FI 网络环境的流量辨认成预发组

part 4

利用不停机公布的外围是利用如何优雅进行,光有服务路由可能还不够,它尽管曾经解决了大部分问题,但离胜利还差最初一步。

后面咱们提到过利用公布要做到用户无感知,那如果利用公布过程中呈现瞬断或短时间中断,而用户又正好在应用,那算不算用户就感知到了呢?

不过,如果你感觉线上服务中断 5 分钟也能够忍耐,那我只能呵呵了。但我置信大部分具备互联网服务模式的头部公司,别说公布一次服务进行 5 分钟,可能就连 5 秒钟也无法忍受。

那咱们先来剖析一下为什么会呈现瞬断或短时间中断:

  • 服务申请解决还没实现,利用就被强行进行(例如:运维必备大招之 kill -9 过程),导致解决中的申请无奈失常返回
  • 服务提供方尽管已进行,但未告诉服务申请方,服务申请方依然持续拜访已进行的服务提供方,导致出现异常

针对以上两种状况,还须要分南北向和东西向进行探讨。

在南北向,服务申请方与服务提供方间是通过负载平衡进行服务路由,所以,在利用公布时,须要在负载平衡上进行一些非凡解决。

1) 在负载平衡上,逐个对应用服务实例进行流量屏蔽,该屏蔽只会影响新的申请,期待服务申请解决实现后,再执行如下操作:

  • 容器:销毁服务实例,创立新版本服务实例
  • 虚拟机:更新服务实例,更新后解除屏蔽

注:商业化的负载平衡个别都反对优雅下线 / 上线

2)因服务申请方的申请都会先通过负载平衡,而负载平衡的成员节点只有确保至多有 1 个服务实例存在即可,该场景不须要告诉,因而不实用。

在东西向,服务申请方与服务提供方间是间接进行服务路由的,所以,在利用公布时,须要别离在服务申请方和服务提供方进行一些非凡解决,而这些解决形式受限于利用框架,这里先介绍一种罕用框架,即:Springboot+Eureka 利用框架

  • 在服务提供方上实现 Shutdown hook,即:期待服务申请解决实现后,再进行利用进行。
  • 在服务提供方进行前,需告诉所有服务申请方,并在实现告诉后再进行利用进行。

其中第 2 点看上去仿佛很简略,但实际上会比较复杂,对此我做了一些降级,用于衡量收益价值和革新老本。

实现成果 革新老本
形式一:最多中断 5 秒 对容器 / 虚拟机平台进行大量革新
形式二:不中断(不告诉) 对容器 / 虚拟机平台进行革新
形式三:不中断(告诉) 对容器 / 虚拟机平台进行革新;对注册核心 / 对立注册核心进行革新

形式一:最多中断 5 秒

step1:依赖 spring-boot-starter-actuator 组件,裸露 /shutdown 端点

management:
  endpoint:
    shutdown:
      enabled: true
  endpoints:
    web:
      exposure:
        include: shutdown

step2:调整 Eureka 配置参数,该调整会别离减少 Eureka 客户端和服务端性能压力

配置项 配置形容 缺省值 倡议值
eureka.client.registry-fetch-interval-seconds Eureka 客户端获取服务注册信息频率 30 4
ribbon.ServerListRefreshInterval Eureka 客户端 ribbon 刷新工夫 30 1
eureka.server.useReadOnlyResponseCache Eureka 服务端是否应用只读缓存 true false

step3:容器销毁服务实例或虚拟机更新服务实例前,申请如下地址进行应用服务实例进行

curl -X http:// 应用服务地址 /actuator/shutdown

形式二:不中断(不告诉)

step1:依赖 spring-boot-starter-actuator 组件,裸露 /shutdown 和 /service-
registry 端点

management:
  endpoint:
    shutdown:
      enabled: true
  endpoints:
    web:
      exposure:
        include: shutdown,service-registry

step2:调整 Eureka 配置参数,该调整会别离减少 Eureka 客户端和服务端性能压力

配置项 配置形容 缺省值 倡议值
eureka.client.registry-fetch-interval-seconds Eureka 客户端获取服务注册信息频率 30 4
ribbon.ServerListRefreshInterval Eureka 客户端 ribbon 刷新工夫 30 1
eureka.server.useReadOnlyResponseCache Eureka 服务端是否应用只读缓存 true false

step3:容器销毁服务实例或虚拟机更新服务实例前,申请如下地址进行应用服务实例下线

curl -X http:// 应用服务地址 /actuator/service-registry?status=DOWN

注:此时,服务提供方依然能够提供服务,但再次获取服务实例的服务申请方不会再获取该服务实例

step4:服务申请方最多期待 5 秒后会更新服务列表,所以,在实现以上操作后,能够休眠 5 秒钟,再申请如下地址进行应用服务实例

curl -X http:// 应用服务地址 /actuator/shutdown

注:eureka.client.registry-fetch-interval-seconds+ribbon.ServerListRefreshInterval= 5 秒

形式三:不中断(告诉)

step1:依赖 spring-boot-starter-actuator 组件,裸露 /shutdown 和 /service-registry 端点

management:
  endpoint:
    shutdown:
      enabled: true
  endpoints:
    web:
      exposure:
        include: shutdown,service-registry

step2:调整 Eureka 配置参数,该调整会减少 Eureka 服务端性能压力

配置项 配置形容 缺省值 倡议值
eureka.server.useReadOnlyResponseCache Eureka 服务端是否应用只读缓存 true false

step3:容器销毁服务实例或虚拟机更新服务实例前,申请如下地址进行应用服务实例下线

curl -X http:// 应用服务地址 /actuator/service-registry?status=DOWN

注:此时,服务提供方依然能够提供服务,但再次获取服务实例的服务申请方不会再获取该服务实例

step4:在注册核心上记录以后正订阅该服务实例的服务申请方列表,并依据列表告诉它们立刻从新获取最新的服务实例,告诉实现后再申请如下地址进行应用服务实例

curl -X http:// 应用服务地址 /actuator/shutdown

以上三种形式,能够联合价值收益和革新老本进行衡量,承受瞬断的能够抉择形式一,而对技术有极致谋求的能够抉择形式三,如果两个都不是,那就抉择形式二吧。

注:每个应用服务的 Eureka 配置参数并不一定可能齐全对立,这样可能就会造成大量配置管理老本的减少,但如果能够对立,那形式二还是不错的抉择。

Part 5

在具备以上条件能力后,利用公布不停机的根本框架已成型,但这样利用公布就能实现不停机了?

那有这么简略,咱们在开发上还须要遵循一些标准,但合乎这些标准的话,可能会减少咱们的一些开发成本。

因而,并不是说每次利用公布都强行须要实现不停机公布,而是应该进行正当的取舍。不过,一个好的零碎设计必然能做到既能遵循开发标准,也不会减少太多开发成本。

如下列举了一些罕用的开发标准,理论状况可按需调整,其目标是为了不论是接口更新还是数据库更新等,都应尽量做到向上兼容。

写在最初

感激你能够很急躁的读到这里,整篇文章次要围绕利用不停机公布进行了思考,从为什么要做,能带来什么价值,始终到应该怎么做,要关怀哪些方面,进行了简要阐明,次要目标是为了能让大家,对利用不停机公布有一个大略的框架意识。

实现利用不停机公布的伎俩,也并非仅有文章中说的那些形式,波及到的技术组件可能也不止这些,但其解决思路根本都差不多,具体的技术实现形式,能够联合本身的架构环境再进行适配和调整。

起源:技术微妙物语

作者:陈俊
申明:文章取得作者受权在 IDCF 社区公众号(devopshub)转发。优质内容共享给思否平台的技术伙伴,如原作者有其余思考请分割小编删除,致谢。

玩乐高,学麻利,规模化麻利联合作战沙盘之「乌托邦打算」,12 月 25-26 日登陆深圳,将“多团队麻利协同”基因内化在研发流程中,为规模化晋升研发效力保驾护航!!🏰⛴公众号回复“乌托邦”可加入

正文完
 0