mirror of
https://github.com/cheetahlou/CategoryResourceRepost.git
synced 2025-10-21 09:23:44 +08:00
mod
This commit is contained in:
150
极客时间专栏/持续交付36讲/发布及监控/19 | 发布是持续交付的最后一公里.md
Normal file
150
极客时间专栏/持续交付36讲/发布及监控/19 | 发布是持续交付的最后一公里.md
Normal file
@@ -0,0 +1,150 @@
|
||||
<audio id="audio" title="19 | 发布是持续交付的最后一公里" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/5b/06/5bccee22d7ef3fae5806360260343106.mp3"></audio>
|
||||
|
||||
你好,我是王潇俊。我今天分享的主题是:发布是持续交付的最后一公里。
|
||||
|
||||
在开始我今天的分享之前,我们先来搞清楚一个问题:部署和发布是不是一回事儿?
|
||||
|
||||
有一些观点认为,部署和发布是有区别的,前者是一个技术范畴,而后者则是一种业务决策。这样的理解应该说是正确的。应用被部署,并不代表就是发布了,比如旁路运行(dark launch)方式,对于客户端产品更是如此的。
|
||||
|
||||
但对互联网端的产品来说,这个概念就比较模糊了,所以从英文上来看,我们通常既不用deploy这个词,也不用 release 这个词,而是使用 rollout这个词。所以,从用词的选择上,我们就可以知道,发布是一个慢慢滚动向前、逐步生效的过程。
|
||||
|
||||
因此,我在《发布及监控》系列文章中提到的“发布”,均泛指 rollout 这样的过程。
|
||||
|
||||
## 发布,头疼的最后一步
|
||||
|
||||
无论是为新需求添加的代码,还是静态配置的变更,线上应用的任何变动都要经过发布这道工序才能最终落地,完成交付。通常,发布意味着应用重启、服务中断,这显然不符合如今系统高可用的需求。
|
||||
|
||||
同时,软件工程和经验也告诉我们,世界上不存在没有Bug的代码,即便经过详尽细致地测试,线下也很难百分之一百地复制线上的环境、依赖、流量,更难穷举千变万化的用户行为组合。
|
||||
|
||||
于是,发布变更,在许多时候是一件被标记为“高风险系数”的工作,工程师和测试人员经常在深夜搞得筋疲力尽,甚至焦头烂额。
|
||||
|
||||
进入持续交付的时代后,这个痛点只会更加突显,因为持续交付意味着持续发布。例如,在测试环境小时级的持续集成场景中,如果没有办法将发布过程流程化、自动化,显然会频繁打断最终的交付过程,大幅降低开发测试效率。
|
||||
|
||||
好在上帝创造了一个问题,一定会留下一套解决方案,更多的时候是许多套,我们的目标就是找到它,然后实现最佳实践。
|
||||
|
||||
## 发布的需求
|
||||
|
||||
你不妨先问自己一个问题,作为开发人员,或者其他研发角色,你理想中的发布是什么样的呢?
|
||||
|
||||
答案当然是:够快够傻瓜。最好点一下鼠标,就立刻能看到线上的变更,整个体验跟本地开发环境调试毫无区别。
|
||||
|
||||
更加贪心的同学甚至希望连点击鼠标都不用,而是每小时、每天、甚至每commit自动发布,希望系统神奇地将自己从SSH和乱七八糟的线上环境中解放出来。
|
||||
|
||||
另一方面,从运维的角度来讲,线上系统的稳定性和可用性则是第一考量。运维上线变更前,首先会思考如果这中间出了什么岔子该如何应对,找不到问题时能否快速回滚到之前的状态,整个过程如何最小限度地减少服务的宕机时间。对他们而言,完美的方案就像是能够稳如泰山地给飞行中的飞机更换引擎。
|
||||
|
||||
**因此,我们想要的应该是:一个易用、快速、稳定、容错力强,必要时有能力迅速回滚的发布系统。**
|
||||
|
||||
## 什么是好的发布流程?
|
||||
|
||||
好的系统依赖好的设计,而好的工作流方案可以显著减少需要考虑的问题集,有助于创造出高健壮性的系统。对于发布系统,单机部署方案和集群工作流同样重要。
|
||||
|
||||
**第一,把大象放进冰箱分几步?**
|
||||
|
||||
单机部署这件事说复杂很复杂,说简单也很简单。
|
||||
|
||||
复杂在于,不同技术栈的部署方式千差万别,脚本语言PHP和需要编译的Golang的上线步骤差很多;同样是Java,使用Tomcat和Netty的命令也完全不一样。
|
||||
|
||||
简单在于,发布过程高度抽象后其实就三个步骤:
|
||||
|
||||
<li>
|
||||
在目标机器上执行命令停掉运行中的服务;
|
||||
</li>
|
||||
<li>
|
||||
把提前准备好的变更产物传上机器覆盖原来的目录;
|
||||
</li>
|
||||
<li>
|
||||
运行命令把服务再跑起来。
|
||||
</li>
|
||||
|
||||
但只是按照这三步走,你很容易就能设想到一些反例场景:服务虽然停止,但新的请求还在进入,这些请求全部返回503错误;或者,假如有Bug或者预料之外的问题,服务根本起不来,停服时间就不可预知了。
|
||||
|
||||
更糟糕的是,假如此时情况紧急,我们想回滚到之前的状态,回滚时就会发现,由于之前的目录被覆盖了,基本回不去了。
|
||||
|
||||
**第二,靠谱的单机部署**
|
||||
|
||||
那么,比较完善的发布变更流程应该是怎样的呢?在我看来,可以抽象成五步:
|
||||
|
||||
<li>
|
||||
下载新的版本,不执行覆盖;
|
||||
</li>
|
||||
<li>
|
||||
通知上游调用方,自己现在为暂停服务状态;
|
||||
</li>
|
||||
<li>
|
||||
运行命令load变更重启服务;
|
||||
</li>
|
||||
<li>
|
||||
验证服务的健康状况;
|
||||
</li>
|
||||
<li>
|
||||
通知上游调用方,自己服务恢复正常。
|
||||
</li>
|
||||
|
||||
假设我们实现了一个程序,简单地顺序执行上面的算法,让我们一起来检验一下这套程序是否能满足发布的需求:快速、易用、稳定、容错、回滚顺滑。
|
||||
|
||||
- 易用:执行脚本就好,填入参数,一键执行。
|
||||
- 快速:自动化肯定比手工快,并且有提升空间。比如,因为有版本的概念,我们可以跳过相同版本的部署,或是某些步骤。
|
||||
- 稳定:因为这个程序逻辑比较简单,而且执行步骤并不多,没有交叉和并行,所以稳定性也没什么大的挑战。
|
||||
- 容错性强:表现一般,脚本碰到异常状况只能停下来,但因为版本间是隔离的,不至于弄坏老的服务,通过人工介入仍能恢复。
|
||||
- 回滚顺滑:因为每个版本都是完整的可执行产物,所以回滚可以视作使用旧版本重新做一次发布。甚至我们可以在目标机器上缓存旧版本产物,实现超快速回滚。
|
||||
|
||||
通过这个程序的简单执行过程,我们可以看到这套流程的简单实现,基本满足了我们对发布的需求。而且,可以通过添加更复杂的控制流,获得更大的提升空间。
|
||||
|
||||
我在这里提到的三个重要概念:版本、通知调用方、验证健康(又被称之为点火),可以说是实现目标的基石。我会在后续章节,详细介绍版本、通知调用方、验证健康这三方面的实现方式和取舍。
|
||||
|
||||
**第三,扩展到集群**
|
||||
|
||||
如今应用架构基本告别了单点世界,面向集群的发布带来了更高维度的问题。**当发布的目标是一组机器而不是一台机器时,主要问题就变成了如何协调整个过程。**
|
||||
|
||||
比如,追踪、同步一组机器目前发布进行到了哪一步,编排集群的发布命令就成为了更核心功能。好消息是,集群提供了新的、更易行的方法提高系统的发布时稳定性,其中最有用的一项被称为灰度发布。
|
||||
|
||||
**灰度发布是指,渐进式地更新每台机器运行的版本,一段时期内集群内运行着多个不同的版本,同一个API在不同机器上返回的结果很可能不同。** 虽然灰度发布涉及到复杂的异步控制流,但这种模式相比简单粗暴的“一波流”显然要安全得多。
|
||||
|
||||
不仅如此,当对灰度发布的进度有很高的控制能力时,事实上这种方式可以提供A/B测试可能性。 比如,你可以说,将100台机器分成4批,每天25台发布至新的版本,并逐步观察新版本的效果。
|
||||
|
||||
其实,**集群层面的设计,某种程度上是对单机部署理念的重复,只不过是在更高的维度上又实现了一遍。** 例如,单机部署里重启服务线程堆逐批停止实现,与集群层面的分批发布理念,有异曲同工之妙。
|
||||
|
||||
## 几种常见的灰度方式
|
||||
|
||||
灰度发布中最头疼的是如何保持服务的向后兼容性,发现苗头不对后如何快速切回老的服务。这在微服务场景中,大量服务相互依赖,A回滚需要B也回滚,或是A的新API测试需要B的新API时十分头疼。为了解决这些问题,业界基于不同的服务治理状况,提出了不同的灰度理念。
|
||||
|
||||
接下来,我将分别介绍蓝绿发布、滚动发布和金丝雀发布,以及携程在发布系统上的实践。
|
||||
|
||||
<li>
|
||||
**蓝绿发布**,是先增加一套新的集群,发布新版本到这批新机器,并进行验证,新版本服务器并不接入外部流量。此时旧版本集群保持原有状态,发布和验证过程中老版本所在的服务器仍照常服务。验证通过后,流控处理把流量引入新服务器,待全部流量切换完成,等待一段时间没有异常的话,老版本服务器下线。
|
||||
<ul>
|
||||
1. 这种发布方法需要额外的服务器集群支持,对于负载高的核心应用机器需求可观,实现难度巨大且成本较高。
|
||||
1. 蓝绿发布的好处是所有服务都使用这种方式时,实际上创造了蓝绿两套环境,隔离性最好、最可控,回滚切换几乎没有成本。
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>**滚动发布**,是不添加新机器,从同样的集群服务器中挑选一批,停止上面的服务,并更新为新版本,进行验证,验证完毕后接入流量。重复此步骤,一批一批地更新集群内的所有机器,直到遍历完所有机器。<br />
|
||||
这种滚动更新的方法比蓝绿发布节省资源,但发布过程中同时会有两个版本对外提供服务,无论是对自身或是调用者都有较高的兼容性要求,需要团队间的合作妥协。但这类问题相对容易解决,实际中往往会通过功能开关等方式来解决。</p>
|
||||
</li>
|
||||
<li>
|
||||
**金丝雀发布**,从集群中挑选特定服务器或一小批符合要求的特征用户,对其进行版本更新及验证,随后逐步更新剩余服务器。这种方式,比较符合携程对灰度发布的预期,但可能需要精细的流控和数据的支持,同样有版本兼容的需求。
|
||||
</li>
|
||||
|
||||
**结合实际情况,携程最终选择的方式是:综合使用滚动发布和金丝雀发布。** 首先允许对一个较大的应用集群,特别是跨IDC的应用集群,按自定义规则进行切分,形成较固定的发布单元。基于这种设计,我们开发了携程开源灰度发布系统,并命名为Tars 。其开源地址为:[https://github.com/ctripcorp/tars](https://github.com/ctripcorp/tars)
|
||||
|
||||
关于携程灰度发布的设计和实施,以及如何把灰度发布的理念贯穿到你的持续交付体系中,我会在后面的第22篇文章《发布系统架构功能设计实例》中详细介绍。
|
||||
|
||||
## 其他考量
|
||||
|
||||
处于持续交付最后一环的发布,实际上是非常个性化的,与实际实现相关,甚至是case by case的。因为每个上游系统的少许变更和设计瑕疵,层层下压最终都会影响到发布系统。这不但要求发布系统了解链条上绝大多数环节,知道发生了什么以便debug,甚至时常还需要为其“兜底”。
|
||||
|
||||
除此以外,软件工程中没有“银弹”,适用于所有场景的系统设计是不存在的。上面的设计有许多值得探讨的地方,比如发布时到底是使用增量、还是全量,单机切断流量使用哪种手段,集群发布的控制流设计,都是值得探讨的主题。这些内容,我将会在后面的文章中详细展开。
|
||||
|
||||
## 总结
|
||||
|
||||
作为《发布与监控》系列文章的开篇,我介绍了发布在持续交付中的位置和需求,并提出了一个可靠的单机部署流程的概念,即我们想要的应该是:一个易用、快速、稳定、容错力强,必要时有能力迅速回滚的发布系统。
|
||||
|
||||
明确了发布的需求后,我推演了集群发布中灰度发布的概念和常用方式,包括蓝绿发布、滚动发布和金丝雀发布,并分析了这三种发布方式,给出了携程选择的方案,希望可以帮你选择适合自己团队的发布策略。
|
||||
|
||||
## 思考题
|
||||
|
||||
你能详细地整理和描述出你的应用的单机部署过程吗?
|
||||
|
||||
欢迎你给我留言。
|
||||
|
||||
|
145
极客时间专栏/持续交付36讲/发布及监控/20 | Immutable!任何变更都需要发布.md
Normal file
145
极客时间专栏/持续交付36讲/发布及监控/20 | Immutable!任何变更都需要发布.md
Normal file
@@ -0,0 +1,145 @@
|
||||
<audio id="audio" title="20 | Immutable!任何变更都需要发布" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/f2/bf/f2b26181a6e4c93ffc301e8ba13b9bbf.mp3"></audio>
|
||||
|
||||
在专栏的第13讲[《容器技术真的是环境管理的救星吗?》](https://time.geekbang.org/column/article/12404)中,我们初步结识了不可变基础设施(Immutable Infrastructure),这里我们再一起回顾一下:
|
||||
|
||||
>
|
||||
在这种模式中,任何基础设施的实例(包括服务器、容器等各种软硬件)一旦创建之后便成为一种只读状态,不可对其进行任何更改。如果需要修改或升级某些实例,唯一的方式就是创建一批新的实例来替换它。
|
||||
|
||||
|
||||
这种思想与不可变对象的概念完全相同。
|
||||
|
||||
为什么我会说,不可变基础设施的思想对持续交付的影响非常深远呢?因为不可变的思想正是解决了持续交付一直没有解决的一个难题,即环境、顺序、配置这些基础设施在测试环节和生产环节的不一致性所带来的问题。
|
||||
|
||||
那么,今天我就来详细分析一下不可变基础设施的由来、影响,以及如何实现的相关内容。
|
||||
|
||||
## 从持续交付中来
|
||||
|
||||
如果你是一个程序员,其实很容易理解不可变基础设施的概念,以及其实现的方式。因为它就和Java中的不可变类完全相同:类实例一旦创建,就无法变更,而可以变更的是指向实例的引用。
|
||||
|
||||
其实早在2011年出版的《持续交付:发布可靠软件的系统方法》一书中,就曾提到“蓝绿发布”的概念:你需要更新一组实例,但并不是直接在原有实例上进行变更,而是重新启动一批对等的实例,在新实例上更新,然后再用新实例替换老实例。此时老实例仍旧存在,以便回滚。
|
||||
|
||||
其实,这完全就是对不可变类的物理实现,也就是一个典型的不可变模型。
|
||||
|
||||
这里,我抛出了“不可变模型”的概念,那么我们再垂直一些,再来看看由不可变模型转化到不可变基础设施,又会有哪些具体的要求。
|
||||
|
||||
综合起来一句话,就是:
|
||||
|
||||
>
|
||||
对任何的包、配置文件、软件应用和数据,都不做CRUD(创建、替换、更新、删除)操作。
|
||||
|
||||
|
||||
也就是说,对于已经存在的基础设施,不再在其上创造任何新的事物。根据不可变模型,推导得出取而代之的方法则是:
|
||||
|
||||
<li>
|
||||
构建一个新的基础设施;
|
||||
</li>
|
||||
<li>
|
||||
测试新的基础设施是否符合需求;
|
||||
</li>
|
||||
<li>
|
||||
将引用指向这个新的基础设施;
|
||||
</li>
|
||||
<li>
|
||||
保留原有基础设施以备回滚。
|
||||
</li>
|
||||
|
||||
虽然不可变模型的设想很好,但其中也会有一些特殊情况存在。比如,涉及数据的部分,特别是数据库,你不可能每次都重建一个数据库实例来达到“不可变”的目的。为什么呢?其根本原因是,数据库是有状态的。所以,从这里可以清楚地看到,**不可变(Immutable)的前提是无状态。**
|
||||
|
||||
## 不可变基础设施的神话
|
||||
|
||||
说到为什么会需要“不可变基础设施”这种方法论,还是挺有意思的。
|
||||
|
||||
首先是一个假设:如何保证两个实例的行为完全一致?最有效的方式是,在两个实例上以同样的顺序执行同样的变更。
|
||||
|
||||
然后,在2002年,Steve Traugott 写了一篇名为[《为什么顺序很重要》(Why Order Matters)](http://www.infrastructures.org/papers/turing/turing.html)的论文,虽然论文本身涉及了很多数学推理,有些难懂,但它却很好地解释了为什么大规模基础设施是不可变的,并证明了不可变的价值所在。
|
||||
|
||||
**第一,一致是最终的目标**
|
||||
|
||||
在论文中,作者讨论了发散、收敛和一致三种模型。
|
||||
|
||||
1. **发散,** 是我们通常会碰到的基础设施的管理模型。在这个模型中,基础设施随着我们的想法而变化,也就是我们想更新什么就更新什么,最终就会形成一种发散的形态。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/cc/c3/cc386bb76b29d7a802d5daad5afbd3c3.png" alt="" />
|
||||
|
||||
1. **收敛,** 是Puppet和Chef遵循的设计原则。随着时间推移,目标和实际需求汇聚,达到一致。通过这个模型,我们有了可扩展的基础设施的基础和实现。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/81/7f/811b23f808a992bbee073b042672887f.png" alt="" />
|
||||
|
||||
1. **一致,** 指的是整个基础设施始终把每一天当成是与第一天相同的模型。根据我们之前的假设,达到这一目的的关键点就在于,有序地正确执行从真正的第一天开始的所有变更。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/c3/42/c39eb9619decb5018eb33663b6fa7542.png" alt="" />
|
||||
|
||||
那么你就会有疑问,为什么会有一致模型?通过发散和收敛这两个模型,没办法解决实例完全一致的问题吗?答案是,确实不行。
|
||||
|
||||
即使我们知道发散是一种不良状态,我们可以通过定期的收敛,将基础设施不断地趋向所期望的目标。但其中也会碰到很多问题。
|
||||
|
||||
<li>
|
||||
**顺序问题**:你只有完全保证顺序的正确性,结果才会正确。但是,怎么保证顺序呢?特别是执行结果与你的预期不一致时,比如发生错误时,就会多出一些其他的处理步骤,直接影响原有的既定顺序。这也是为什么顺序那么重要的原因。
|
||||
</li>
|
||||
<li>
|
||||
<p>**频率问题**:假设你可以通过一些方法保证顺序,在面对大型基础设施时,应该如何制定收敛频率呢?最简单的回答,自然是越频繁越好。<br />
|
||||
那么你就会陷入巨大的陷阱中,你会发现完全无法支撑并发的收敛工作。而且收敛工作与设施的规模成正比,直接否定了系统的可扩展性。</p>
|
||||
</li>
|
||||
<li>
|
||||
**蝴蝶效应**:你始终无法确定一个绝对的基准点,认为是系统的初始或者当前应该有的状态。因为你始终还在收敛中,只是无限趋近。因此任何小偏差,都会引起将来重大的、不可预知的问题。这就是蝴蝶效应。
|
||||
</li>
|
||||
|
||||
但是,容器却通过分层镜像与镜像发布技术,解决了上面的顺序问题、频率问题和蝴蝶效应。所以说,容器是一个惊人的发明,**它使得每一次变更都成为了一次发布,而每一次发布都成为了系统的重新构建,** 从而使得“一致”模型的目标能够达成。
|
||||
|
||||
**第二,Immutable的衍生**
|
||||
|
||||
当然除了容器之外,Immutable 理念还有许多不同的衍生。比如,黄金映像、VDI(虚拟桌面)、Phoenix Server和基础设施即代码。
|
||||
|
||||
- 黄金映像,指的是将绝大部分不变的基础设施(包括操作系统、大多数软件、基本配置等),包含在映像内,只留很少一部分变更通过脚本执行解决;
|
||||
- VDI(虚拟桌面),指的是操作系统运行在后端的服务器上,用户只使用属于他自己的虚拟桌面,无法改变后端的系统内容;
|
||||
- Phoenix Server,指的是完全被破坏的服务器,能够从灰烬中自动进行恢复;
|
||||
- 基础设施即代码,指的是把基础设施的构建以代码的方式组织起来,从而通过运行代码可以完全构建出你想要的全部基础设施。
|
||||
|
||||
这些衍生技术都遵循Immutable的理念,曾在不同的场景下,比如快速灾备、快速恢复系统、增强系统健壮性等方面发挥了巨大的作用,从而收益。
|
||||
|
||||
但是,随着技术的发展,这些衍生技术不再能够适应我们对速度和扩展性的要求,加之容器技术的蓬勃发展,使得这一系列的难题都可以通过容器技术解决,因此我们已经完全可以把注意力放到容器上了。
|
||||
|
||||
## 回到持续交付中去
|
||||
|
||||
虽然我们一起从持续交付中走了出来,了解了不可变基础设施的种种,但最终我们还是要回持续交付中去,去解决构建持续交付平台的问题。那么,接下来我们就一起看看面对容器时代的新形式,持续交付要做哪些变化吧。
|
||||
|
||||
“不可变”模型的好处,已经显而易见。而对于容器时代的持续交付,也显然已经从原来单纯交付可运行软件的范畴,扩展为连带基础环境一起交付了,所以我们需要为此做好准备。
|
||||
|
||||
上文中,我已经总结了一句话,**每一次变更都是一次发布,而每一次发布都是系统重新构建,更形象点说,每一次发布都是一个独立镜像的启动**。所有持续交付的变化也都可以表现为这样一句话,那具体怎么理解呢。
|
||||
|
||||
**首先,任何的变更,包括代码的、配置的、环境的,甚至是CPU、内存、磁盘的大小变化,都需要制作成独立版本的镜像。**
|
||||
|
||||
**其次,变更的镜像可以提前制作,但必须通过发布才能生效。** 这有2个好处:
|
||||
|
||||
<li>
|
||||
重新生成新的实例进行生效,完全遵循不可变模型的做法;
|
||||
</li>
|
||||
<li>
|
||||
发布内容既包含代码也包含基础设施,更有利于DevOps的实施。
|
||||
</li>
|
||||
|
||||
**再次,一组运行中的同一个镜像的实例,因为“不可变”的原因,其表现和实质都是完全一样的,所以不再需要关心顺序的问题。因为任何一个都等价,所以也就没有发布或替换的先后问题了。**
|
||||
|
||||
**最后,根据“一致”模型的要求,我们需要记录系统从第一天发展到今天的所有有序变更。** 对Docker而言,不仅要能向上追溯层层Base镜像的情况,更建议将系统和软件的配置以Dockerfile的方式进行处理,以明确整个过程的顺序。
|
||||
|
||||
这些理念,不仅传统的持续交付中没有涉及,甚至有些还与我们日常的理解和习惯有所不同。比如,你通常认为一个集群中的不同服务器的配置是可以不一样的,但在“不可变”模型中,它是不被允许的。
|
||||
|
||||
当然,我在之前的[《容器技术真的是环境管理的救星吗?》](https://time.geekbang.org/column/article/12404)一文中也提到过,Immutable对持续交付的环境管理来说确实有点违反人性。所以,容器对持续交付的影响,可以说是利弊都有吧。
|
||||
|
||||
也因此,持续交付中遇到“不可变”,更应该去理解它的概念和用意,合理发挥其优势。
|
||||
|
||||
## 总结
|
||||
|
||||
首先,我分享了“不可变”模型的概念,以及它的由来,介绍了三个非常有价值的模型:发散模型、收敛模型和一致模型。
|
||||
|
||||
其次,我解释了为什么“不可变”如此重要的原因,也就是重复发散到收敛过程无法解决的三个问题:顺序问题、频率问题和蝴蝶效应。
|
||||
|
||||
最后,我针对“不可变”及容器,提出了持续交付面对的新问题,即:每一次变更都是一次发布,每一次发布都是一个独立的镜像的启动。
|
||||
|
||||
## 思考题
|
||||
|
||||
你所在的公司有没有什么地方可以体现出“不可变”思想?如果没有,是什么原因呢?
|
||||
|
||||
感谢你的收听,欢迎你给我留言。
|
||||
|
||||
|
170
极客时间专栏/持续交付36讲/发布及监控/21 | 发布系统一定要注意用户体验.md
Normal file
170
极客时间专栏/持续交付36讲/发布及监控/21 | 发布系统一定要注意用户体验.md
Normal file
@@ -0,0 +1,170 @@
|
||||
<audio id="audio" title="21 | 发布系统一定要注意用户体验" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/66/cb/66578288cc475bfb3c01763261f1b7cb.mp3"></audio>
|
||||
|
||||
你好,我是王潇俊。我今天分享的主题是:发布系统一定要注意用户体验。
|
||||
|
||||
我在第19篇文章《发布是持续交付的最后一公里》中,介绍了蓝绿发布、滚动发布和金丝雀发布这三种灰度发布方式,也分享了携程根据自身情况综合使用滚动发布和金丝雀发布的方式,构建了自己的灰度发布系统Tars。
|
||||
|
||||
但是,了解了灰度发布的知识,甚至是看过了别家的灰度发布系统,但并不一定能解决如何将这些灰度发布的理念贯彻到你自己的持续交付体系的问题。
|
||||
|
||||
其实,解决这个问题最好的方式,就是构建一套发布系统来落地灰度发布。这也是我今天这篇文章,以及后续两篇文章(《发布系统的核心架构和功能设计》《业务系统架构对发布的影响》)要重点解决的问题。
|
||||
|
||||
如果有一款发布系统,既能完成持续交付的目标,又能提升研发同学的工作效率,岂不美哉。那么,为了我们美好的目标开始努力吧。今天我就先从用户体验的角度,以携程发布系统为例,来和你聊聊如何落地发布系统。
|
||||
|
||||
## 1 张页面展示发布信息
|
||||
|
||||
如果要说什么样的设计才能让用户体验达到完美,那肯定是众说纷纭。从不同的视角去看,都会得到不同的答案。那么,对发布系统来说,我们应该怎么看待这个问题呢?
|
||||
|
||||
我们不妨做个类比,应用的发布和火箭发射其实有点相像。
|
||||
|
||||
平时我们看火箭发射时,往往会看到一个巨大的屏幕,这个巨大的屏幕汇集了火箭发射当时的各种信息,比如实时视频、各种数据图表、周围的情况,等等。
|
||||
|
||||
所有相关人员的注意力都会优先集中在这个大屏幕上,只有发生异常时,才会由具体的负责人在自己的岗位上进行处理。
|
||||
|
||||
这也就说明一个很重要的问题,对于发布这件事儿来说,**首先应该有1张页面,且仅有1张页面,能够展示发布当时的绝大多数信息、数据和内容,这个页面既要全面,又要精准。** 全面指的是内容清晰完整,精准指的是数据要实时、可靠。
|
||||
|
||||
除了以上的要求外,对于实际的需求,还要考虑2个时态,即发布中和未发布时,展示的内容应该有所区别。
|
||||
|
||||
- 发布中:自然应该展示发布中的内容,包括处理的过程、结果、耗时、当前情况等等。
|
||||
- 未发布时:应该显示这个应用历史发布的一个过程,也就是整个版本演进的路线图,以及当前各集群、各服务器上具体版本的情况。
|
||||
|
||||
所以基于以上考虑,携程的发布系统整体设计就只有一张核心页面,如图1所示。因为涉及到安全问题,所以图片处理的有些模糊。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/92/6c/9263fd397cb6246e66e210e5e922cd6c.png" alt="" />
|
||||
|
||||
## 2 个操作按钮简化使用
|
||||
|
||||
发布系统是一个逻辑比较复杂的系统。而且用户在使用时,往往会伴随一定的心理压力,毕竟每次发布都有造成故障的可能。所以,我见过有些公司,要求发布系统的使用者要经过严格的培训:他们需要熟练地掌握整个系统的使用,知晓每个按钮按下去的后果。
|
||||
|
||||
但,这显然不是持续交付想要达到的目标。
|
||||
|
||||
与DevOps的理念一样,我们更希望看到的场景是:谁开发,谁运行。也就是说,我们的目标是,每个开发者都能通过这套系统去发布和运行自己的代码。
|
||||
|
||||
这也就决定了,如果发布系统的用户体验做得很复杂、功能按钮非常多的话,就会增加系统的使用难度,背离我们实施持续交付的初衷。
|
||||
|
||||
所以,携程在思考发布系统的用户体验设计时,就提出了这样一个目标:页面上除了“回滚”按钮常在外,最多同时展示2个操作按钮。这样,用户的选择就会变得非常容易,要么左,要么右,总能找到适合自己的。
|
||||
|
||||
最终,用户在页面上可能会看到的同时出现的按钮组合有以下四种情况:
|
||||
|
||||
<li>
|
||||
开始发布,1个按钮;
|
||||
</li>
|
||||
<li>
|
||||
中断发布,1个按钮;
|
||||
</li>
|
||||
<li>
|
||||
中断或重试发布,2个按钮,发生在有局部错误的情况下;
|
||||
</li>
|
||||
<li>
|
||||
中断或继续发布,2个按钮,发生在发布被刹车时。
|
||||
</li>
|
||||
|
||||
关于如何实现这样的需求,我会在下一次分享《发布系统的核心架构和功能设计》时,着重介绍。
|
||||
|
||||
## 3 种发布结果
|
||||
|
||||
对发布系统的用户来说,他们最关心的无疑是发布结果。所以,发布结果的显示,也要力求简单,降低使用难度。
|
||||
|
||||
因为,结果的数量将直接决定用户操作和状态流转的复杂度。结果越多,程序要处理的逻辑也就越多,操作人员需要处理的状况自然也就越多。所以,如果能够对发布状态做足够的抽象和简化,那么整个系统的复杂度就将会得到指数级的简化。
|
||||
|
||||
**系统不复杂了,用户体验自然也就简单了。这是一个相辅相成的过程。**
|
||||
|
||||
从最抽象的角度来说,发布系统只需要3种结果,即:成功、失败和中断。
|
||||
|
||||
- **成功状态**:很好理解,即整个发布过程,所有的实例发布都成功;
|
||||
- **失败状态**:只要发布过程中有一个步骤、一个实例失败,则认为整个发布事务失败;
|
||||
- **中断状态**:发布过程中任何时间点都可以允许中断此次发布,中断后事务结束。
|
||||
|
||||
特别需要说明的是,部分失败和全部失败在发布系统的设计上没有分别,这也是出于事务完整性的考虑,即优先完成整个事务的发布。
|
||||
|
||||
## 4 类操作选择
|
||||
|
||||
将发布结果高度概括为成功、失败和中断后,配合这三种状态,我们可以进一步地定义出最精简的4种用户操作行为,即开始发布、停止发布、发布回退和发布重试。
|
||||
|
||||
- **开始发布**,指的是用户操作开始发布时,需要选择版本、发布集群、发布参数,配置提交后,即可立即开始发布。
|
||||
- **停止发布**,指的是发布过程中如果遇到了异常情况,用户可以随时停止发布,发布状态也将停留在操作“停止发布”的那一刻。
|
||||
- **发布回退**,指的是如果需要回退版本,用户可以在任意时刻操作“发布回退”,回退到历史上最近一次发布成功的版本。
|
||||
- **发布重试**,指的是在发布的过程中,因为种种原因导致一些机器发布失败后,用户可以在整个事务发布结束后,尝试重新发布失败的机器,直到发布完成。
|
||||
|
||||
## 5 个发布步骤
|
||||
|
||||
在讲解了一个发布事务相关的操作和步骤,包括开始发布,停止发布,发布回退和发布重试之后,接下来我和你聊聊单个实例具体的发布过程。
|
||||
|
||||
就像我在第19讲[《发布是持续交付的最后一公里》](https://time.geekbang.org/column/article/13380)中总结的“靠谱的单机部署”流程一样,单个实例的发布过程,也可以分为5个步骤:
|
||||
|
||||
<li>
|
||||
**markdown**:为了减少应用发布时对用户的影响,所以在一个实例发布前,都会做拉出集群的操作,这样新的流量就不会再继续进入了。
|
||||
</li>
|
||||
<li>
|
||||
**download**:这就是根据版本号下载代码包的过程;
|
||||
</li>
|
||||
<li>
|
||||
**install**:在这个过程中,会完成停止服务、替换代码、重启服务这些操作;
|
||||
</li>
|
||||
<li>
|
||||
**verify**:除了必要的启动预检外,这一步还包括了预热过程;
|
||||
</li>
|
||||
<li>
|
||||
**markup**:把实例拉回集群,重新接收流量和请求。
|
||||
</li>
|
||||
|
||||
在这5个步骤中,第四步verify比较特殊。因为包含了预热这个耗时通常比较长的过程(有时甚至需要几十分钟)。所以,这个步骤的处理必须是异步的。同时,还需要用户在发布配置时,设置一个超时时间,以便防呆处理,即在异步处理长时间无返回时,能够继续处理。
|
||||
|
||||
集群中的每个实例都会分批次,逐个按顺序去完成这5个步骤。这5个步骤本身是串行的,任何一步出错,该实例的操作都会立即停止。
|
||||
|
||||
## 6 大页面主要内容
|
||||
|
||||
最后,再回过头来看一下,在分享的一开始,我提出了一个设想,要做到出色的用户体验,需要将发布的主要信息,呈现在唯一的一张页面上。那么,这张页面涉及到的主要内容到底有什么呢?
|
||||
|
||||
根据携程的实践,我提炼了这一张页面要展示的最主要的6部分内容。
|
||||
|
||||
第一,集群。集群是发布的标准单元。如图2所示,用户可以选择左侧的集群,在界面右侧查看当前运行的版本、历史发布情况、操作发布。
|
||||
|
||||
第二,实例。实例是集群的成员,通常情况下,一个集群会有多个实例承载流量。在界面上,用户可以查看实例的基本信息,了解实例的IP、部署状态、运行状态等。用户能够看到发布时的状态与进度,这些信息可以帮助用户更好地控制发布。
|
||||
|
||||
第三,发布日志。在发布中和发布完成后,用户都可以通过查询发布日志了解发布时系统运行的日志,包括带有时间戳的执行日志和各种提示与报错信息,方便后续排查问题。
|
||||
|
||||
第四,发布历史。发布历史对发布系统来说尤为重要。用户可以通过发布历史了解集群过去所做的变更,并且可以清晰地了解集群回退时将会回退到哪一天发布的哪个版本。
|
||||
|
||||
第五,发布批次。由于集群中有很多实例,如何有序地执行发布,就是比较重要的事情。设定发布批次,可以让集群的发布分批次进行,避免问题版本上线后一下子影响所有的流量。每个批次中的实例采用并行处理的方式,而多个批次间则采用串行处理的方式。
|
||||
|
||||
第六,发布操作。所有的发布操作按钮都会集中在这个区域,以便用户快速定位。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/54/95/54fa7c5ac7a15717cef4f3930ed09995.png" alt="" />
|
||||
|
||||
上面这6大部分内容,就是我在设计携程的发布系统时抽象出的最主要的内容。当然,在最初设计时,我们也考虑过将其他内容也加进来,比如监控内容。但,最终我们放弃了,因为这些都不是发布系统最关注的信息,而且当发布速度达到分钟级时,肉眼也已经无法解决监控或预警的问题了。
|
||||
|
||||
所以,在考虑灰度发布系统的用户体验时,我建议你可以参考以下三个原则:
|
||||
|
||||
<li>
|
||||
信息要全面直观,并且聚合,而不要分散;
|
||||
</li>
|
||||
<li>
|
||||
操作要简单直接,不要让用户做过多思考;
|
||||
</li>
|
||||
<li>
|
||||
步骤与状态要清晰,减少模糊的描述。
|
||||
</li>
|
||||
|
||||
## 总结
|
||||
|
||||
一路看下来,不知道你是否已经发现,整篇文章的6个章节,恰好能用1~6这六个数字串接提炼,我也正是希望这种形式能够加深你对发布系统产品设计的概念理解。这里,我们再一起简单回顾一下吧。
|
||||
|
||||
1张页面展示发布信息,且仅有1张页面,展示发布当时的绝大多数信息、数据和内容,这个页面既要全面,又要精准。
|
||||
|
||||
2 个操作按钮简化使用,即页面上除了“回滚”按钮常在外,最多同时展示2个操作按钮。目的是要降低发布系统的使用难度,做到“谁开发,谁运行”。
|
||||
|
||||
3 种发布结果,即成功、失败和中断状态,目的是简单、明了地显示用户最关心的发布结果。
|
||||
|
||||
4类操作选择,包括开始发布、停止发布、发布回退、发布重试,目的是使状态机清晰明了。
|
||||
|
||||
5个发布步骤,即markdown、download、install、verify和markup。这里需要注意到的是,verify这步包含了预热,由于耗时往往比较长,一般采用异步的处理方式。
|
||||
|
||||
6大页面主要内容,包括集群、实例、发布日志、发布历史、发布批次、发布操作,来统一、简洁而又详细呈现发布中和未发布时的各种信息。
|
||||
|
||||
## 思考题
|
||||
|
||||
如果你是一个灰度发布系统的用户,你最关心的信息都有哪些?是否有我在这篇文章中没有提到的内容,你又将如何处理这些内容呢?
|
||||
|
||||
感谢你的收听,欢迎你给我留言。
|
||||
|
||||
|
139
极客时间专栏/持续交付36讲/发布及监控/22 | 发布系统的核心架构和功能设计.md
Normal file
139
极客时间专栏/持续交付36讲/发布及监控/22 | 发布系统的核心架构和功能设计.md
Normal file
@@ -0,0 +1,139 @@
|
||||
<audio id="audio" title="22 | 发布系统的核心架构和功能设计" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/a7/c2/a72333644f1c82e4929ded616b041bc2.mp3"></audio>
|
||||
|
||||
你好,我是王潇俊。我今天分享的主题是:发布系统的核心架构和功能设计。
|
||||
|
||||
我在分享[《发布系统一定要注意用户体验》](https://time.geekbang.org/column/article/13552)这个主题时,介绍了从用户体验的角度出发,设计一套发布系统的设计理念,以及具体实现。但是,用户体验设计得再好,后端系统无法支持,也就如同巧妇难为无米之炊。
|
||||
|
||||
截止到目前,携程一共有7000多个应用,平均每周生产发布8000多次,而测试环境的发布平均每周要40000多次,如果发布系统没有一个清晰的架构设计,完成这样艰巨的任务是难以想象的。
|
||||
|
||||
所以,今天我就从核心架构和功能设计的角度,和你聊聊如何设计一套发布系统。
|
||||
|
||||
## 发布系统架构
|
||||
|
||||
作为整个持续交付体系中极为重要的一个环节,应用的发布是提升交付效率的关键。高效的发布系统架构应该是清晰的、健壮的、低耦合的,从而达到在最糟糕的情况下也能运作的目的。
|
||||
|
||||
携程在发布系统这件事上也不是一蹴而就,在经历了各种尝试和努力后,最终设计出了一套分布式、高可用、易扩展的发布系统,其系统架构如图1所示。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/d1/77/d1ae2e8175df64dc352290bd197d9d77.png" alt="" />
|
||||
|
||||
Roll Engine,即发布引擎,主要负责创建发布批次,按批次粒度实施部署策略,通过异步方式调用Salt Master服务,再分发到各个Agent节点上执行部署任务。真正的单机部署脚本会根据不同的应用或机型进行分发和定制。而 Controller ,则作为接收外部指令和读写数据的控制器。当然,对于一些对外的通知事务,发布系统会采用消息机制向外广播。
|
||||
|
||||
发布系统需要将发布相关的元数据信息(主要包括App应用、Group集群、Server服务器等),从外部CMDB资产数据库落地到本地数据库,作为一层本地缓存。
|
||||
|
||||
数据更新的方式,主要有两种,一种是在每次发布前更新,另一种是通过消费通知消息进行更新,以保证发布元数据的准确性。
|
||||
|
||||
**根据携程发布系统结构设计的经验,我总结了几个需要注意的点**:
|
||||
|
||||
<li>
|
||||
每台服务实例上的发布脚本一旦产生则不再修改,以达到不可变模型的要求;
|
||||
</li>
|
||||
<li>
|
||||
发布引擎和Salt Master之间采用异步通信,但为增强系统健壮性,要有同步轮询的备案;
|
||||
</li>
|
||||
<li>
|
||||
面对频繁的信息获取,要善用缓存,但同时也一定要慎用缓存,注意发布信息的新鲜度。
|
||||
</li>
|
||||
|
||||
## 发布系统核心模型
|
||||
|
||||
发布系统的核心模型主要包括Group、DeploymentConfig、Deployment、DeploymentBatch,和DeploymentTarget这5项。
|
||||
|
||||
**Group**,即集群,一组相同应用的实例集合,是发布的最小单元,其概念如图2所示。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/db/fd/db5fe492e30a7b598a3eb578ad5256fd.png" alt="" />
|
||||
|
||||
同时,Group的属性非常重要,包括Site站点、Path虚拟路径、docBase物理路径、Port应用端口、HealthCheckUrl健康检测地址等,这些属性都与部署逻辑息息相关。**携程之所以这样设计,是因为group这个对象直接表示一个应用的一组实例,这样既可以支持单机单应用的部署架构,也可以支持单机多应用的情况。**
|
||||
|
||||
**DeploymentConfig**,即发布配置,提供给用户的可修改配置项要通俗易懂,包括:单个批次可拉出上限比、批次间等待时间、应用启动超时时间、是否忽略点火。
|
||||
|
||||
**Deployment**,即一个发布实体,主要包括Group集群、DeploymentConfig发布配置、Package发布包、发布时间、批次、状态等等信息。
|
||||
|
||||
**DeploymentBatch**,即发布批次,通常发布系统选取一台服务器作为堡垒批次,集群里的其他服务器会按照用户设置的单个批次可拉出上限比划分成多个批次,必须先完成堡垒批次的发布和验证,才能继续其他批次的发布。
|
||||
|
||||
**DeploymentTarget**,即发布目标服务器或实例,它与该应用的Server列表中的对象为一对一的关系,包括主机名、IP地址、发布状态信息。
|
||||
|
||||
**这里一定要注意,发布系统的对象模型和你所采用的部署架构有很大关系。** 比如,携程发布系统的设计中并没有pool这个对象,而很多其他企业却采用pool实现对实例的管理。又比如,在针对Kubernetes时,我们也需要根据它的特性,针对性地处理Set对象等等。
|
||||
|
||||
## 发布流程及状态流转
|
||||
|
||||
发布系统的主流程大致是:
|
||||
|
||||
同一发布批次中,目标服务器并行发布;不同发布批次间则串行处理。每台目标服务器在发布流程中的五个阶段包括 Markdown、Download、Install、Verify、Markup。
|
||||
|
||||
如图3描绘了具体的发布流程。
|
||||
|
||||
<img src="https://static001.geekbang.org/resource/image/2c/93/2cf431600f6f026e541cbcbb6004a293.png" alt="" />
|
||||
|
||||
发布过程从技术实现上来说,就是通过状态机控制状态流转,而每个状态都对应一些具体的操作。
|
||||
|
||||
那么,我们就一起来看看整个状态流转如何通过状态机进行控制:
|
||||
|
||||
**首先,借助于Celery分布式任务队列的Chain函数,发布系统将上述的Markdown、Download、Install、Verify、Markup五个阶段定义为一个完整的链式任务工作流,保证一个Chain函数里的子任务会依次执行。**
|
||||
|
||||
**其次,每个子任务执行成功或失败,都会将DeploymentTarget设置为对应的发布状态。** 例如,堡垒批次中的DeploymentTarget执行到Verify点火这个任务时,如果点火验证成功,那么DeploymentTarget会被置为VERIFY_SUCCESS(点火成功)的状态,否则置为VERIFY_FAILURE(点火失败)的状态。
|
||||
|
||||
发布过程中,如果有任意一台DeploymentTarget发布失败,都会被认为是发布局部失败,允许用户重试发布。因此,重试发布只针对于有失败的服务器批次进行重试,对于该批次中已经发布成功的服务器,发布系统会对比当前运行版本与发布目标版本是否一致,如果一致且点火验证通过的话,则直接跳过。
|
||||
|
||||
**这里需要注意的是,** 堡垒批次不同于其他批次:堡垒批次中DeploymentTarget的Chain的最后一个子任务是Verify点火,而不是Markup。
|
||||
|
||||
**再次,点火验证成功,DeploymentTarget的状态流转到VERIFY_SUCCESS后,需要用户在发布系统页面上触发Baking操作**,即堡垒批次中DeploymentTarget的Markup,此时执行的是一个独立的任务事务,会将堡垒批次中的服务器拉入集群,接入生产流量。也就是说,这部分是由用户触发而非自动拉入。BAKE_SUCCESS堡垒拉入成功之后,就是其他批次的RollingOut事务了,这也是一个独立的任务,需要由用户触发其他批次开始发布的操作。
|
||||
|
||||
**最后,设置发布批次。**
|
||||
|
||||
除堡垒批次外,其他的机器会按照用户自主设置的最大拉出比来分批,每个批次间允许用户设置等待时间,或者由用户手动执行启动下个批次发布的操作。从第3个批次起,允许用户设置较短的或者不设置等待批次的间隔时间,以提高最后几个批次的速度,即尾单加速,这样可以提高整个发布过程的效率。
|
||||
|
||||
携程的发布系统,利用了一个分布式异步任务框架来处理整个发布过程的事务,然后通过状态机来控制这些任务的开始和停止。当然,由于我们使用Python语言,所以选择了Celery框架,其他语言也有很多成熟的类似框架,也建议你在实施过程中,充分利用这些框架的优势。
|
||||
|
||||
## 刹车机制
|
||||
|
||||
为了保证用户体验的顺畅和发布系统的高容错性,除堡垒批次外的每个发布批次均采用了Quick and Dirty的发布方式,即不管成功或失败,优先尝试把版本发布完,继续执行下个发布批次,后续再解决个别目标服务器发布失败的问题。
|
||||
|
||||
试想在这种发布方式下,我们应该如何避免大面积的发布失败影响业务呢?
|
||||
|
||||
于是,我们需要为发布系统提供刹车机制,即**在每个批次开始发布任务前,系统会根据用户设置的单个批次可拉出上限比,进行失败率的计算与控制。发布时,一旦达到这个失败率,立即中断当前发布,从而保护Quick and Dirty发布方式。**
|
||||
|
||||
一旦刹车后,发布系统允许用户先执行重试发布操作,如果因为重试批次中的服务器失联或者其他外因导致重试无果,则用户需要终止当前发布,重新设置单个批次可拉出上限比,或者临时将服务器从各个负载均衡设备或访问入口中拉出(与发布拉出为独立的标志位),由此发布系统的分组策略会剔除被拉出的服务器,不再做发布。与此同时,用户可以同步进行失败服务器的下线或者更换操作,而不会阻塞发布。
|
||||
|
||||
## 提升发布速度
|
||||
|
||||
从上面的发布过程中,你不难发现**影响发布速度的步骤通常是下载和点火**。
|
||||
|
||||
为了提高下载速度,携程在各个机房搭建了发布包专用的存储系统,实现了类似CDN的功能,编译和打包系统在任何一个写入点写入发布包,都会尽快同步到各个IDC及各个独立存储中,这样真正发布时,服务器只需从本IDC或本网段做下载。
|
||||
|
||||
对于点火,携程在框架层面统一提供了点火入口和常规的点火验证方法,收口了所有应用的点火验证规范和标准,容错性和速度都得到大幅提升。
|
||||
|
||||
而回滚方面,不再设置堡垒批次,发布系统默认提供了单个批次可拉出上限比为50%的配置,即分两个批次执行回滚发布。这样可以追求最快的回滚速度。当然在日常发布过程中,比如扩容发布,也可以不设置堡垒批次,但前提是待发布的版本已经被证明可以正确工作。
|
||||
|
||||
在单机部署逻辑上,发布系统在服务器本地保留了多个版本,在回滚发布时,可快速进行目录切换,进而直接省略了下载发布包的过程,最大限度地缩短应用的故障时间,提升回滚速度。
|
||||
|
||||
## 降级机制
|
||||
|
||||
对外部系统的服务依赖,例如LB负载均衡服务的拉出或拉入调用,发布系统需要具备降级机制,熔断外部系统依赖的能力,一旦发现外部服务不可用,可以及时处理,保证用户的紧急发布需求。
|
||||
|
||||
对外部系统的元数据依赖,例如从CMDB同步Group信息的场景下,发布系统可以使用Redis锁合并重复的请求,提高同步数据的吞吐能力,以解决重试并发的问题。另外,由于发布系统做了数据缓存,也就同时具备了一键降级CMDB等其他外部系统依赖的能力。
|
||||
|
||||
降级机制能够保证在突发异常情况下,发布系统可以解除所有外部依赖,独立完成任何发布应用的任务。也就是说,**降级机制可以保证发布系统做到,只有部署包存在,就能恢复服务。**
|
||||
|
||||
## 总结
|
||||
|
||||
我今天分享的主题就是,从后端系统设计的角度,来看看一套发布系统的核心架构和功能应该如何设计。我以携程目前使用的发布系统为例,从发布系统的架构、核心模型、发布流程及状态流转三个方面,展开了今天的分享。
|
||||
|
||||
首先,高效的发布系统架构应该是清晰的、健壮的、低耦合的,携程在经历各种迭代后,采用了以 Protal、Controller、Roll Engine、Salt Scripts 为核心的分层架构。
|
||||
|
||||
其次,在设计核心模型时,考虑到部署架构的个性化设计,即要兼容单机单应用,又要兼容单机多应用的问题,携程的发布系统采用了以 Group 和 Deployment 为核心的主要对象模型设计方案。这里你需要注意的是,发布系统的对象模型和你所采用的部署架构有很大关系,所以还是要量体裁衣。
|
||||
|
||||
再次,关于发布系统的发布流程,可以通过状态流转控制单机发布的5个步骤和发布批次。这部分你需要注意的是,堡垒批次不同于其他批次:堡垒批次中DeploymentTarget的Chain的最后一个子任务是Verify点火,而不是Markup。
|
||||
|
||||
最后,一款出色的发布系统,除了要考虑架构、核心模型,以及发布流程的问题外,还必须同时考虑一些附加问题,比如:
|
||||
|
||||
- 为了降低Quick and Dirty方式对业务功能的影响,你需要提供发布刹车机制;
|
||||
- 利用分布式存储、尾单加速、symlink回滚等方式,可以提升发布速度;
|
||||
- 必要的降级机制,可以保证发布系统的高可用。
|
||||
|
||||
## 思考题
|
||||
|
||||
如果你对携程的Tars感兴趣,可以通过[https://github.com/ctripcorp/tars](https://github.com/ctripcorp/tars)获取。你也可以参考开源版本Tars,迅速搭建一套发布系统,并结合自身的情况看看还需要增加什么设计?
|
||||
|
||||
欢迎你给我留言。
|
||||
|
||||
|
111
极客时间专栏/持续交付36讲/发布及监控/23 | 业务及系统架构对发布的影响.md
Normal file
111
极客时间专栏/持续交付36讲/发布及监控/23 | 业务及系统架构对发布的影响.md
Normal file
@@ -0,0 +1,111 @@
|
||||
<audio id="audio" title="23 | 业务及系统架构对发布的影响" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/e9/9d/e949a8ce4621e79c3f45736d74e8469d.mp3"></audio>
|
||||
|
||||
在分享[《发布系统一定要注意用户体验》](https://time.geekbang.org/column/article/13552)和[《发布系统的核心架构和功能设计》](https://time.geekbang.org/column/article/13905)这两大主题时,我分别从用户体验和架构设计两个方面,和你分享了携程灰度发布系统的一些经验和实践。但是,要做出一个出色的发布系统,仅仅考虑这两方面还不够。
|
||||
|
||||
因为发布系统最终要服务的对象是业务应用,而业务应用又和业务、企业的系统架构有紧密的联系,所以要做好一套发布系统,我们还要考虑其要服务的业务及系统架构的需要,并且要善于利用系统架构的优势为发布系统服务。
|
||||
|
||||
那么接下来,我们就一起来看看,业务、企业整体的系统架构会给发布系统带来什么影响,发布系统又可以借用它们的哪些架构能力。
|
||||
|
||||
## 单机单应用还是单机多应用?
|
||||
|
||||
众所周知,.NET应用采用的基本都是Windows + IIS 的部署模式,这是一种典型的单机、单Web容器、多应用的部署模式。
|
||||
|
||||
在这种模式下,单机多应用的问题主要体现在两个方面:
|
||||
|
||||
- 一方面,应用划分的颗粒度可以做到非常细小,往往一个单机上可以部署20~30个应用,甚至更多,而且应用与应用间的隔离性较差;
|
||||
- 另一方面,由于IIS的设计问题,不同虚拟目录之间可能存在共用应用程序池的情况,即多个应用运行在同一个进程下,导致任何一个应用的发布都可能对其他的关联应用造成影响。
|
||||
|
||||
所以,对发布系统而言,.NET应用的这种架构简直就是噩梦:发布系统需要重新定义发布单元的含义,并维护每个虚拟目录和对应的发布单元与应用之间的关系。
|
||||
|
||||
**在携程,我们为了解决这个问题采用的方案是,去除根目录的被继承作用,默认每个虚拟目录就是一个应用,并且每个虚拟目录的应用程序池独立。而每个虚拟目录以应用的名称命名,保证单机上不会发生冲突。**
|
||||
|
||||
这样,应用与应用之间就解耦了,发布系统的设计也会变得简单很多。
|
||||
|
||||
除了上面这种.NET的单机多应用情况无法改变外,其他所有Linux下的应用都可以做到单机单应用。其实,这也正是虚拟化思想最初的设计理念。为什么呢?因为与单机多应用相比,单机单应用更简单直接,更易于理解和维护。
|
||||
|
||||
比如,单机单应用不需要考虑分配服务端口的问题,所有的Web应用都可以使用同一个统一端口(比如,8080端口)对外服务。但是,单机多应用的情况下,就要考虑端口分配的问题,这算不算是徒增烦恼呢?
|
||||
|
||||
另外,单机单应用在故障排除、配置管理等方面同样具有很多优势。一言以蔽之,简单的才是最好的。
|
||||
|
||||
当然,**简单直接,也正是发布系统所希望看到的情况**。
|
||||
|
||||
## 增量发布还是全量发布?
|
||||
|
||||
增量发布还是全量发布,其实是个挺有意思的问题。
|
||||
|
||||
在过去网络带宽是瓶颈的年代里,或者面对体量巨大的单体应用时,增量发布可以节省很多计算资源,确实是一个很好的解决方案。甚至现在的移动客户端发布,也还会选择增量发布的技术来快速发布静态资源。
|
||||
|
||||
但是,互联网应用的场景下,更多的发布需求来自于发布频率非常高的后台服务。在这样的情况下,增量发布反而会造成不必要的麻烦。
|
||||
|
||||
比如,增量发布对回滚非常不友好,你很难确定增量发布前的具体内容是什么。如果你真的要确定这些具体内容的话,就要做全版本的差异记录,获取每个版本和其他版本间的差异,这是一个巨大的笛卡尔积,需要耗费大量的计算资源,简直就是得不偿失。很显然,这是一个不可接受的方案。
|
||||
|
||||
反之,全量发布就简单多了,每个代码包只针对一个版本,清晰明了,回滚也非常简单。所以,**我的建议是,全量发布是互联网应用发布的最好方式。**
|
||||
|
||||
## 如何控制服务的 Markup 和 Markdown?
|
||||
|
||||
首先,你需要明确一件事儿,除了发布系统外,还有其他角色会对服务进行Markup和Markdown操作。比如,运维人员在进行机器检修时,人为的Markdown操作。因此,我们需要从发布系统上能够清晰地知晓服务的当前状态,和最后进行的操作。
|
||||
|
||||
另外,这里还引入了一个全新的问题:当一个服务被执行Markdown操作后,什么系统还能继续处理这个服务,而什么系统则不能继续处理这个服务?
|
||||
|
||||
比如,发布系统如果发现服务最后进行的操作是Markdown,那么还能不能继续发布呢?如果发布,那发布之后需不需要执行Markup操作呢?有些情况下,用户希望利用发布来修复服务,因此需要在发布之后执行Markup;而有些情况下,用户发布后不能执行Markup,很可能运维人员正在维护网络。
|
||||
|
||||
为了解决这个问题,**携程在设计系统时,用不同的标志位来标识发布系统、运维操作、健康检测,以及服务负责人对服务的Markup和Markdown状态。4个标志位的任何一个为Markdown都代表暂停服务,只有所有标志位都是Markup时,服务中心才会向外暴露这个服务实例。**
|
||||
|
||||
这样做的好处是,将4种角色对服务的操作完全解耦,他们只需要关心自己的业务逻辑,既不会发生冲突,也不会影响事务完整性,更无需采用其他复杂的锁和Token机制进行排他操作。
|
||||
|
||||
## 检查、预热和点火机制
|
||||
|
||||
我在分享从用户体验和核心架构的角度设计发布系统时,提到过发布过程中必然会有Verify的过程。
|
||||
|
||||
如果这个过程依赖手工操作的话,一来难以保证发现问题的速度,二来也很难保证落实力度。但如果这个过程能够做到自动化的话,则可以大幅减少因发布而引发的生产故障,同时还可以保证一些服务启动依赖检测。
|
||||
|
||||
在携程,我们借助于VI(Validate Internal)框架中间件,实现了Verify过程的自动化,我们把这个过程形象地叫作“点火”。所有使用这个中间件的应用启动后,发布系统执行的第一个操作就是这个VI接口所提供的检查方法,当然用户完全可以根据业务自定义应用的检查方法。这也就保证了发布过程中一定会执行到Verify过程,而不会因为各种原因而被遗漏。
|
||||
|
||||
Verify是一个异步过程,可能耗时较长,但是程序员们很快就发现,这个VI组件不但可以做检查,还可以在检查时进行一些预热、预加载这样的任务。
|
||||
|
||||
携程通过这样一个中间件组件,很高效地解决了发布过程中的两个问题:
|
||||
|
||||
<li>
|
||||
如何对各个应用做个性化的自动化检查;
|
||||
</li>
|
||||
<li>
|
||||
如何在发布过程中解决应用预加载这类的需求。
|
||||
</li>
|
||||
|
||||
## 如何保证堡垒流量?
|
||||
|
||||
我在[《发布是持续交付的最后一公里》](https://time.geekbang.org/column/article/13380)这篇文章中介绍金丝雀发布时,说到了携程选择的是综合使用滚动发布和金丝雀发布的方案,使用堡垒机的方式来预发和测试新的版本。
|
||||
|
||||
但是,采用这个方案,我们需要考虑分布式服务架构带来的影响,即如何保证堡垒机的流量一定会分发到对应下游服务的堡垒机上。就好比,发布一个包含Web和Service两个应用的新功能,我需要保证Web堡垒的流量只发送给Service的堡垒,否则就会出问题。
|
||||
|
||||
我们解决这个问题的思路是,软负载系统通过发布系统获得堡垒机的IP,在堡垒机发出的请求的header中附加堡垒标识,这样软负载在判断出有堡垒标识时,则只会将请求发向下游的堡垒机。当然,是否加注这个标识,完全由发布系统在发布堡垒时控制。
|
||||
|
||||
这样,我们就解决堡垒流量控制的问题。
|
||||
|
||||
## 总结
|
||||
|
||||
因为发布系统最终服务的对象是业务应用,所以发布系统的设计除了考虑用户体验、核心架构外,还要注意业务、系统架构对发布系统的影响,并且要合理利用业务、系统架构的能力,去完善发布系统的设计。
|
||||
|
||||
业务、系统架构对发布系统的影响,主要体现在是选择单机单应用还是单机多应用、选择增量发布还是全量发布这两大方面。在这里,我的建议是简单的才是最好的,即采用单机单应用的部署架构;对于后台应用,以及发布非常频繁的应用来说,全量发布更直接,更容易达成版本控制,并做到快速回滚。
|
||||
|
||||
除此之外,我们还要利用系统架构使发布系统具有更优的发布能力,这主要包括三个方面:
|
||||
|
||||
<li>
|
||||
利用软负载或者服务通讯中间件的多个状态位,简单直接地解决多角色对服务Markup和Markdown的冲突问题;
|
||||
</li>
|
||||
<li>
|
||||
利用中间件的能力,使得Verify过程不会被遗忘,同时还可以完成自动化检查和预热,达到高效可控的目的;
|
||||
</li>
|
||||
<li>
|
||||
通过软负载和通讯中间件,解决堡垒机与堡垒机间的流量分发问题,保证堡垒机的流量只在上下游服务的堡垒机中流转。
|
||||
</li>
|
||||
|
||||
因此,有效运用系统架构的能力,会为你带来意想不到的收益。
|
||||
|
||||
## 思考题
|
||||
|
||||
在你的实际工作中,发布系统有没有受到架构设计的影响?是积极影响还是消极影响呢?消极影响的话,你有想过如何改变吗?
|
||||
|
||||
感谢收听,欢迎你给我留言。
|
||||
|
||||
|
185
极客时间专栏/持续交付36讲/发布及监控/24 | 如何利用监控保障发布质量?.md
Normal file
185
极客时间专栏/持续交付36讲/发布及监控/24 | 如何利用监控保障发布质量?.md
Normal file
@@ -0,0 +1,185 @@
|
||||
<audio id="audio" title="24 | 如何利用监控保障发布质量?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/0d/89/0dea200892648d704e2fcac4a7d55b89.mp3"></audio>
|
||||
|
||||
你好,我是王潇俊,今天我和你分析的主题是:如何利用监控保障发布质量。
|
||||
|
||||
在前几次的分享中,我详细介绍了发布在持续交付过程中的重要地位,以及如何去思考和设计一套灰度发布系统。作为发布及监控系列的最后一篇文章,今天我就和你聊聊灰度发布的最后一个过程:监控,以及如何做好发布后的监控。
|
||||
|
||||
之所以有今天这次分享,最重要的原因是要告诉你:**千万不要认为发布结束,就万事大吉了。特别是生产发布,发布结束时才是最危险的时刻。** 因为,故障都是伴随着发布变更而来的。所以,我们需要有一套监控系统,及时发现问题、定位问题,帮助我们减少因故障带来的损失。
|
||||
|
||||
同时,随着分布式系统的普及,以及APM(Application Performance Management,系统性能管理)概念的兴起,针对分布式系统的全链路监控系统也逐步发展起来,为持续交付提供了有力的支持。可以说,一套性能优良的监控系统,可以为持续交付保驾护航。
|
||||
|
||||
当然,这个专栏的主要内容是帮你解决持续交付的问题,所以我不会去分享监控系统如何设计这种需要一整个专栏才能解决的问题。
|
||||
|
||||
因此,我今天分享的重点是,帮助你去理解监控的常规概念,和你聊一些技术选型方案,并一起讨论一些与持续交付有关的问题。
|
||||
|
||||
## 监控的分类
|
||||
|
||||
从一般意义上来讲,我们会把监控分为以下几类:
|
||||
|
||||
<li>
|
||||
用户侧监控,关注的是用户真正感受到的访问速度和结果;
|
||||
</li>
|
||||
<li>
|
||||
网络监控,即CDN与核心网络的监控;
|
||||
</li>
|
||||
<li>
|
||||
业务监控,关注的是核心业务指标的波动;
|
||||
</li>
|
||||
<li>
|
||||
应用监控,即服务调用链的监控;
|
||||
</li>
|
||||
<li>
|
||||
系统监控,即基础设施、虚拟机及操作系统的监控。
|
||||
</li>
|
||||
|
||||
因此,我们要做好一个监控系统,可以从这五个层面去考虑,将这五个层面整合就可以做成一个完整的、端到端的全链路监控系统。当然,监控系统的这5个层次的目标和实现方法有所不同,接下来我将分别进行介绍。
|
||||
|
||||
**第一,用户侧监控**
|
||||
|
||||
随着移动互联网的兴起,用户对 Mobile App 的体验成了衡量一个系统的重要指标,所以对用户侧的监控也就变得尤为重要。因为,它能够第一时间向我们反馈用户使用系统的直观感受。
|
||||
|
||||
用户侧的监控通常从以下几个维度进行,这些监控数据既可以通过打点的方式,也可以通过定期回收日志的方式收集。
|
||||
|
||||
<li>
|
||||
端到端的监控,主要包括包括一些访问量、访问成功率、响应时间、发包回包时间等等监控指标。同时,我们可以从不同维度定义这些指标,比如:地区、运营商、App版本、返回码、网络类型等等。因此,通过这些指标,我们就可以获得用户全方位的感受。
|
||||
</li>
|
||||
<li>
|
||||
移动端的日志。我们除了关注系统运行的日志外,还会关注系统崩溃或系统异常类的日志,以求第一时间监控到系统故障。
|
||||
</li>
|
||||
<li>
|
||||
设备表现监控,主要指对CPU、内存、温度等的监控,以及一些页面级的卡顿或白屏现象;或者是直接的堆栈分析等。
|
||||
</li>
|
||||
<li>
|
||||
唯一用户ID的监控。除了以上三种全局的监控维度外,用户侧的监控一定要具备针对唯一用户ID的监控能力,能够获取某一个独立用户的具体情况。
|
||||
</li>
|
||||
|
||||
**第二,网络监控**
|
||||
|
||||
网络是整个系统通路的保障。因为大型生产网络配置的复杂度通常比较高,以及系统网络架构的约束,所以网络监控一般比较难做。
|
||||
|
||||
**一般情况下,从持续交付的角度来说,网络监控并不需要做到太细致和太深入,因为大多数网络问题最终也会表现为其他应用层面的故障问题。但是,如果你的诉求是要快速定位root cause,那就需要花费比较大的精力去做好网络监控了。**
|
||||
|
||||
网络监控,大致可以分为两大部分:
|
||||
|
||||
<li>
|
||||
公网监控。这部分监控,可以利用模拟请求的手段(比如,CDN节点模拟、用户端模拟),获取对CDN、DNS等公网资源,以及网络延时等监控的数据。当然,你也可以通过采样的方式获取这部分数据。
|
||||
</li>
|
||||
<li>
|
||||
内网监控。这部分监控,主要是对机房内部核心交换机数据和路由数据的监控。如果你能打造全局的视图,形成直观的路由拓扑,可以大幅提升监控效率。
|
||||
</li>
|
||||
|
||||
**第三,业务监控**
|
||||
|
||||
如果你的业务具有连续性,业务量达到一定数量后呈现比较稳定的变化趋势,那么你就可以利用业务指标来进行监控了。一般情况下,单位时间内的订单预测线,是最好的业务监控指标。
|
||||
|
||||
任何的系统故障或问题,影响最大的就是业务指标,而一般企业最重要的业务指标就是订单和支付。因此,**监控企业的核心业务指标,能够以最快的速度反应系统是否稳定。** 反之,如果系统故障或问题并不影响核心业务指标,那么也就不太会造成特别严重的后果,监控的优先级和力度也就没有那么重要。
|
||||
|
||||
当然,核心业务指标是需要经验去细心挑选的。不同业务的指标不同,而即使定义了指标,如何准确、高效地收集这些指标也是一个很重要的技术问题。比如,能不能做到实时,能不能做到预测。这些问题都需要获得技术的有力支持。
|
||||
|
||||
**第四,应用监控**
|
||||
|
||||
分布式系统下,应用监控除了要解决常规的单个应用本身的监控问题外,还需要解决分布式系统,特别是微服务架构下,服务与服务之间的调用关系、速度和结果等监控问题。因此,应用监控一般也被叫作调用链监控。
|
||||
|
||||
调用链监控一般需要收集应用层全量的数据进行分析,要分析的内容包括:调用量、响应时长、错误量等;面向的系统包括:应用、中间件、缓存、数据库、存储等;同时也支持对JVM等的监控。
|
||||
|
||||
**调用链监控系统,一般采用在框架层面统一定义的方式,以做到数据采集对业务开发透明,但同时也需要允许开发人员自定义埋点监控某些代码片段。**
|
||||
|
||||
另外,除了调用链监控,不要忘了最传统的应用日志监控。将应用日志有效地联合,并进行分析,也可以起到同样的应用监控作用,但其粒度和精准度比中间件采集方式要弱得多。
|
||||
|
||||
所以,我的建议是利用中间件作为调用链监控的基础,如果不具备中间件的能力,则可以采用日志监控的方式。
|
||||
|
||||
**第五,系统监控**
|
||||
|
||||
系统监控,指的是对基础设施的监控。我们通常会收集CPU、内存、I/O、磁盘、网络连接等作为监控指标。
|
||||
|
||||
对于系统监控的指标,我们通常采用定期采样的方式进行采集,一般选取1分钟、3分钟或5分钟的时间间隔,但一般不会超过5分钟,否则监控效果会因为间隔时间过长而大打折扣。
|
||||
|
||||
## 发布监控的常见问题
|
||||
|
||||
持续交付,或者发布系统,对监控的诉求又是什么呢?其实简单来说只有一句话,即:**快速发现发布带来的系统异常。**
|
||||
|
||||
对于这样的诉求,优先观察业务监控显然是最直接、有效的方式。但是只观察业务监控并不能完全满足这样的需求,因为有两种情况是业务监控无能为力的:
|
||||
|
||||
- 第一种情况是我们所谓的累积效应,即系统异常需要累积到一定量后才会表现为业务异常;
|
||||
- 另外一种情况就是业务的阴跌,这种小幅度的变化也无法在业务监控上得到体现。
|
||||
|
||||
因此,我们还需要配合应用监控,关注被发布应用的异常表现。
|
||||
|
||||
但是,在分布式系统,或者微服务架构下,有时被发布应用本身并没有异常表现,却影响了与之相关联的其他应用。所以,除了关注被发布应用本身以外,我们还要关注它所在的调用链的整体情况。
|
||||
|
||||
在持续交付体系中,还有一些关于监控的其他问题,主要包括测试环境是否也需要监控、发布后要监控多久,以及如何确定异常是不是由你刚刚发布的应用引起的。接下来,我们一起看看如何解决这三个问题。
|
||||
|
||||
**第一,测试环境也要监控吗?**
|
||||
|
||||
首先,我们需要认识到一个问题,即:部署一套完整的监控系统的代价非常昂贵。而且,监控作为底层服务,你还要保证它的稳定性和扩展性。
|
||||
|
||||
因此,测试环境是否需要监控,确实是一个好问题。
|
||||
|
||||
我来说说我建议的做法:
|
||||
|
||||
- 如果你的监控系统只能做到系统监控或日志级别的系统监控,那么对于一些对系统性能压榨比较厉害、对稳定性也没太多要求的测试环境来说,无需配备完整的监控系统。
|
||||
- 如果你的监控系统已经做到了调用链甚至全链路的监控,那么监控系统无疑就是你的“鹰眼",除了发现异常,它还可以在定位异常等方面给你帮助(比如,对测试环境的Bug定位、性能测试等都有极大帮助)。在这样的情况下,你就一定要为测试环境配备监控系统。
|
||||
|
||||
你可能还会问,测试环境有很多套,是不是每套测试环境都要对应一套监控系统呢?这倒未必。你可以对监控系统做一些改造,通过数据结构等方式去兼容多套测试环境。
|
||||
|
||||
**第二个问题,发布后需要监控多久?**
|
||||
|
||||
一般来说,需要延时监控的情况都是针对生产发布来说的。
|
||||
|
||||
如果生产发布过程本身就是一个灰度发布过程的话,那么你基本就没有必要进行延时监控了。
|
||||
|
||||
但是,如果整个灰度过程本身耗时并不长的话,我的建议是要进行一定时间的延时监控。我们通常认为,发布完成30分钟以后的异常,都属于运行时异常。所以,**我建议的发布后监控时间为30分钟。**
|
||||
|
||||
**第三个问题,如何确定异常是由我的发布引起的?**
|
||||
|
||||
具备了持续部署能力之后,你最直观的感受就是发布频次变高了。
|
||||
|
||||
以携程为例,我们每天的生产发布频次超过2000次,如果算上测试环境的发布,则要达到1万次左右。如此高频率的发布,我怎么确定某个异常是由我这次的发布引起的呢?而且除了发布,还同时进行着各类运维变更操作,我怎么确定某个异常是发布造成的,而不是变更造成的呢?
|
||||
|
||||
解决这个问题,**你需要建立一套完整的运维事件记录体系,并将发布纳入其中,记录所有的运维事件。当有异常情况时,你可以根据时间线进行相关性分析。**
|
||||
|
||||
那么,如何构建一套完整的运维事件记录体系呢?很简单,你可以通过消息总线的形式去解决这个问题。
|
||||
|
||||
## 总结
|
||||
|
||||
今天,我围绕着灰度发布的最后一个过程:监控,展开了这次的分享。因为我们这个专栏要解决的主要问题是持续交付,所以我并没有过于详细地阐述如何设计一个监控系统,而只是为你介绍了监控体系的一些基本概念,以及一些与持续交付、持续部署相关的问题。
|
||||
|
||||
首先,我介绍了监控的几种分类,以及分别可以采用什么方式去采集数据:
|
||||
|
||||
<li>
|
||||
用户侧监控,可以通过打点收集,或者定期采集日志的方式进行数据收集;
|
||||
</li>
|
||||
<li>
|
||||
网络监控,通过模拟手段或定期采样进行收集;
|
||||
</li>
|
||||
<li>
|
||||
业务监控,需要定义正确的指标以及相匹配的采集技术,务必注意实时性;
|
||||
</li>
|
||||
<li>
|
||||
应用监控,可以通过中间件打点采集,也可以通过日志联合分析进行数据采集;
|
||||
</li>
|
||||
<li>
|
||||
系统监控,通常采用定期采样的方式收集数据。
|
||||
</li>
|
||||
|
||||
其次,我和你分享了三个对发布来说特别重要的监控问题:
|
||||
|
||||
<li>
|
||||
测试环境的监控需要视作用而定,如果不能帮助分析和定位问题,则不需要很全面的监控;
|
||||
</li>
|
||||
<li>
|
||||
一般发布后,我建议继续坚持监控30分钟,把这个流程纳入发布流程中;
|
||||
</li>
|
||||
<li>
|
||||
完整的运维事件记录体系,可以帮你定位某次故障是否是由发布引起的。
|
||||
</li>
|
||||
|
||||
通过今天的分享,我们可以明白,只有拥有了强大的监控系统,我们才能放手持续交付,即监控可以为持续交付保驾护航。
|
||||
|
||||
## 思考题
|
||||
|
||||
你所在的公司是如何构建监控体系的呢,达到持续交付的需求了么?
|
||||
|
||||
欢迎你给我留言。
|
||||
|
||||
|
Reference in New Issue
Block a user