This commit is contained in:
louzefeng
2024-07-11 05:50:32 +00:00
parent bf99793fd0
commit d3828a7aee
6071 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
<audio id="audio" title="持续交付专栏特别放送 | 答疑解惑" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/bb/be/bb56409f10f4341550fccef0882aeabe.mp3"></audio>
整个专栏的全部37篇文章已经更新完毕了。在这三个多月的时间里我一直在尽自己的最大努力想要把自己过往的一些经验和遇到的问题分享给你。但是毕竟篇幅、时间有限针对一些比较复杂的案例或者是针对不同层次的读者也很难做到面面俱到。
所以借着专栏即将结束的机会我整理了一下大家的留言总结了一些比较典型的问题并从中挑选了5个问题在这篇文章中给与回答。虽然这些问题我依旧不能做到面面俱到但也想再为你略尽绵薄之力。
因此,今天我就针对下面这五个问题,再详细的展开一下,和你分享一些携程在这些方面的真实方案和实践:
<li>
测试环境使用和管理的实例;
</li>
<li>
怎么处理数据库发布和回滚;
</li>
<li>
Immutable在携程是如何落地的
</li>
<li>
携程的破坏性测试DR演练
</li>
<li>
携程GitLab HA方案。
</li>
## 测试环境使用和管理的实例
在第8篇[《测试环境要多少?从现实需求说起》](https://time.geekbang.org/column/article/11468)和第9篇[《测试环境要多少?从成本与效率说起》](https://time.geekbang.org/column/article/11472)文章中,我和你分享了携程的测试环境包括这么三类:
<li>
FAT环境为每个团队或功能准备的独立功能测试环境
</li>
<li>
FWS环境部署稳定版本的功能服务以供其他团队联调的环境
</li>
<li>
UAT环境用户接受测试的环境包括独立部署的DB、缓存和中间件。
</li>
这三类环境中UAT环境的使用和管理方法大家都已经比较熟悉了所以这里我再着重和你分享一下FAT和FWS环境相关的内容。
FAT和FWS环境的关系如图1所示。
<img src="https://static001.geekbang.org/resource/image/05/36/058efd9587ff02ebdaecc92af8184236.png" alt="" />
### FAT与FWS环境的关系
FAT环境属于不同部门可以包括多套环境。在管理时既可以按需临时生成也可以作为常备环境持久保留。我们可以在一套FAT环境中部署任意个服务应用。
而FWS环境主要部署的是中间件和公共服务通常情况下它的版本与生产版本一致。
FWS和FAT这两类环境在网络上完全相同并共用一组数据库和缓存。
### 如何控制服务调用关系?
既然FWS和FAT这两类环境完全相同而且不同的FAT环境中也会存在相同的服务应用那么我们就必然要解决一个问题如何控制服务的调用关系。
因为即使是相同的服务应用部署在不同的FAT环境中的应用版本号也可能不一样。如果按照标准服务治理方式的话那么就需要把所有FAT环境中的同一个服务认为是一个服务集群。而同一应用的不同版本同时服务的话它们提供的功能也不一样这会对测试产生负面影响。因为你无法确定出现Bug的版本到底是哪一个。
那么,携程是如何解决这个问题的呢?
携程的解决方案是由SOA通信中间件指定服务的具体地址即通过配置指定要调用的服务的具体地址。当然如果每个服务都要去指定配置那么就太过繁琐了。所以我们还定义了一条默认规则
>
如果没有特别指定的服务调用地址则优先调用同一个环境中的相关服务。如果同一个环境中该服务不存在则尝试调用FWS中部署的实例。
### 在携程如何创建测试环境?
在携程我们有一套完整的测试环境自助管理平台开发人员或QA团队可以按需自助完成对对测试环境的任意操作。这里我也分享一下在携程创建一个测试环境的大致步骤。
**第一步选择一个已经存在的FAT环境或者重新创建一个FAT环境**。如果是重新创建的话,可以选择重新创建一个空的环境,或者是复制一个已有的环境。
**第二步选择要在这个FAT环境下部署的服务应用先进行关系绑定这个FAT环境下要部署的所有服务应用的描述再部署**。如果该服务属于其他团队,则可以要求该团队协助部署(由平台来处理)。
在携程一个团队只能部署属于自己的服务应用如果你的FAT环境中包含了其他团队的应用则要由其他团队部署。这样做的好处是各司其职能更好地控制联调版本。
**第三步配置这个FAT环境相关的信息**。携程的配置中心同样也支持多测试环境的功能可以做到同一个配置key在不同环境有不同的value。
**第四步,对于特殊的服务调用,进行单独配置。**
经过这样的四步,一个测试环境就被创建起来了。期间测试环境的任何变化,都可以通过环境管理平台完成。比如,增减服务应用、修改配置,或是扩容/缩容服务器等。
## 如何处理数据库发布和回滚?
这也是一个大家比较关心的问题。我来和你分享一下携程的实践吧。
在携程数据库的变更是和应用发布拆分开的。也就是说我们的数据库有单独的持续交付流程。这个持续交付的过程大致如图2所示。
<img src="https://static001.geekbang.org/resource/image/74/f5/74abc88062ee031f08ae574df7fd4df5.png" alt="" />
在这个过程中有两处DBA审核
- 第一处审核,是在提交脚本之后。审核的内容主要是变更内容是否合法、方式是否得当、是否影响业务等等。
- 第二处审核,是在提交生产变更后。审核的主要的内容是,判断变更是否会对当时的生产系统产生影响。比如,订单表的更新、大表的变化等,就不允许在业务高峰期进行。
整个数据库发布的持续交付流程是以测试通过为驱动的。这个过程要经历开发、功能以及集成测试3个环境。而数据库的发布又与代码发布不同步所以如果有兼容问题的话就容易被发现了。
那么,怎么做到兼容呢?**携程对数据库变更的要求是:**
- 第一,与业务相关的,只能新增字段,不能删除字段,也不能修改已有字段的定义,并且新增字段必须有默认值。
- 第二对于必须要修改原有数据库结构的场景则必须由DBA操作不纳入持续交付流程。
所以,按照这个管理方式处理数据库的持续交付的话,数据库本身基本就没有需要回滚的场景了。
## Immutable在携程是如何落地的
在第20篇文章[《Immutable任何变更都需要发布》](https://time.geekbang.org/column/article/13535)中,我提到了“不可变”的概念和价值,也讲到了任何系统的变更都要视为一次发布。然而,在传统的基于虚拟机的系统架构下,要做到这一点代价非常大。
所以携程基于Docker容器和k8s落地了不可变模型。
具体的实现思路,其实也很简单。在落地不可变模型之前,我们只有应用发布,这一个可追溯的版本树;那么,针对不可变的需求,我们在其上增加了一个系统变更版本树。同样地,原来只在代码交付时才会进行镜像和部署;现在在系统变更时,我们也会针对性地生成镜像、标注版本、进行部署。
将应用发布和系统变更这两条版本树合并,就是完整的不可变模型需要的版本树了,也就是落地了不可变模型。
## 携程的破坏性测试DR演练
其实,携程的破坏性测试也只是刚刚起步,还没有完全具备混沌工程的能力,其原因主要是:很多的老旧系统比较脆弱,不具备在所有的随机破坏后快速恢复的能力。
但是携程在同城多机房DR灾难恢复方面做得还是比较出色的。其实DR也是一种破坏性测试一般采用的方式是局部断电或者流量切换。所以我们也会定时做DR演练以检验系统健壮性是否达标。
其实破坏性测试和DR演练这两种方式的最终结果是一样的都是将所有生产流量从灾难机房迁移至其他正常机房。当然要完成这样的切换同时不影响正常业务我们需要在架构层面多花费一些精力。比如数据库的同步、Redis的同步、SLB路由的快速切换等等。
我们一起看一下DR演练的具体过程吧。假设IDC B的某个服务单元出现了异常如图3所示。
<img src="https://static001.geekbang.org/resource/image/38/2e/382e4995d5fcf556cc7d04ba21ba932e.png" alt="" />
而此时IDC A有这个服务单元的灾备存在那么系统就会被触发流量切换GLB会将所有发给故障服务单元SLB上的流量切换到IDC A的灾备服务单元上如图4所示。
<img src="https://static001.geekbang.org/resource/image/06/e2/063d34003341274dc91a67561af1eee2.png" alt="" />
这样,故障的服务单元就暂停了服务,直接由灾备服务顶上了。
当然这种演练不仅仅是整个服务单元异常这一种场景还可用于单元内的个别服务的异常演练这时的流量切换就不再是由GLB这种上层来做了而是利用SLB这一层的能力切换部分服务的流量到灾备服务上。
最后你还要记住的很重要的一点就是要能探测到故障单元是否恢复正常了。如果恢复正常了的话流量还要还原回去。这部分的能力可以利用SLB的健康检测实现。
其实,整个破坏性测试过程中最容易出现问题的是,数据库和缓存的处理。如果没有跨机房数据实时同步的能力,建议最好不要尝试,毕竟不要把演练变成了破坏。
## 携程的GitLab HA方案
携程的GitLab HA方案主要是基于Sharding思想大致的架构设计如图5所示。
<img src="https://static001.geekbang.org/resource/image/d0/62/d03603b09210e7d170906d27eb2c6662.png" alt="" />
这个方案的核心思想是通过Nodejsssh2代理和分发所有SSH请求利用Nginx代理和分发所有http请求。具体的实施包括以下三点
第一每台宿主机上有多个GitLab实例可以是虚拟机形式当然也可以是容器形式。
第二同台宿主机上的GitLab实例共享一个Volume这样就保证了即使某一个GitLab实例故障也可以快速将流量切换到同宿主机的其他实例上继续提供服务。
第三我们对每台宿主机的仓库简单地用rsync做了冷备。此处并没做互备否则就变成NFS方案了因为我们的目的是只要保证存储故障时可恢复所以无需采用NFS方案
这个方案的开发成本和维护成本都比较小、简单实用,你也可以借鉴。

View File

@@ -0,0 +1,82 @@
你好,我是王潇俊。
“持续交付36讲”专栏全部的正文部分已经更新完毕了。这里我总结了一份【高效学习指南】希望交付给你的是我在创作这个专栏前后的想法变化以及怎么才能从这个专栏中收获更多。
而不管你是刚刚订阅这个专栏,还是已经学完了全部专栏文章,亦或是只看了其中几篇而未能继续坚持下去,我都相信这篇【高效学习指南】,可以帮你更上一个台阶。
## 关于持续交付的知识图谱
更新完了37篇正文我也曾想结合自己的经验希望可以梳理出一个关于持续交付的知识图谱帮助你了解持续交付的知识边界。但我思索再三几次提笔又放下最终还是放弃了。因为我真的无法界定这个知识图谱的边界持续交付涉及到的内容实在是太多了。
如果我说Java是一种技术你应该不会反对吧而我说数据结构也是一种技术算法也是架构也是你照样不会反对吧
如果我又说与产品相关的内容,更像是一种管理,是对技术成果的一种管理,这看起来也没什么问题,对吧?
那么,我们口中谈论的“持续交付”到底是什么呢?技术?管理?流程?方案?经验?还是实践?
持续交付好像和这些都沾边,是不是?但,肯定也不是说涉及到了这些内容的方方面面。所以,我决定不再归纳这个专栏的知识图谱了。
但是,我相信上面的这些问题,却给了你也给了我,第一个也是最重要的一个学习持续交付的建议,即:
**在学习前,你首先要确定自己的学习目的,是想了解别人的经验,还是要掌握普适的流程,又或是要学习其中的个别技术。**
我始终相信,只有确认了目的地,才能找到所谓的“捷径”。否则,“持续交付”在你我的眼中,终是“一锅大杂烩”,而实施起来就是毫无头绪。
## 关于理论与实践
其实关于“理论与实践”,也是一个需要辩证看待的问题。到底是先掌握理论,还是应该先去实践,这同样是个见仁见智的问题吧。
就像有些读者,在专栏里面留言说“缺少干货和实践”。对这个问题,我不置可否。因为,我始终认为先理解持续交付的基础知识,再动手搭建一套自己的系统,是个水到渠成的事儿。所以,我就把整个持续交付体系的搭建,放在了专栏最后的“实践案例”系列中。
所以,如果你觉得有必要的话,也可以先看最后“实践案例”的系列文章,然后在搭建持续交付体系过程中遇到具体问题时,再去前面的基础文章中寻找答案。或许,这种方式对你来说会更有感觉。
但是我并不太提倡这种做法。就像你在学习Java时一定是先看到“类是对对象的抽象”这种拗口、抽象的定义一样搭建一套持续交付体系也需要先去理解一些技术本质的内容。所以**在我看来,先看懂理论,再结合着实践回顾,才是最理想的学习方式,才会事半功倍。**
另外你可能会纠结于我到底应该先学会使用基础工具还是应该先去掌握解决问题的思路。那么在我看来工具也好实现也罢随着你的成长和技术发展最终都不会成为问题的核心就好像Docker一出现就瞬间解决了以往的很多技术难题一样。
所以,解决问题的思路和方法,才是我最想分享给你的。因为,即使这些思路、方法过时了,你也能从中领悟到它们的来龙去脉,以及为什么会演变出新的思路、方法。这,就是温故而知新。
## 关于小团队与大团队
或许,你也像大多数人一样,一直在纠结一个事情,小团队和持续交付的关系。
其实在我看来持续交付体系的建立和团队的大小没什么直接关系。但是持续交付ROI却与团队大小有直接关系。
我最近也离开携程创业了目前技术团队只有5个人主要产品是基于微信小程序。微信小程序的发布也有一套审核流程所以我针对这个过程借用了一些Hook的能力做了CD。但是最近也有一家上千人的大厂询问我关于持续交付的问题。他们的问题是团队连续搞了很长时间最后却连基本工具也没顺利搭建起来。
所以说,团队大小并不会限制你的持续交付能力,你也无需再纠结于自己的团队大小而无法实施持续交付的问题了。
但从另一方面来看,任何技术、流程和工具,在大团队中的收益一定会比小团队要好。其实,这是必然的,因为受益的群体大了嘛,而且能切实地解决更多复杂问题,更明显地提高协作效率。而这些,又恰恰是一个大型研发团队最需要解决的问题。
所以,大团队对持续交付的关注度要远远高于小团队。
## 推荐一些参考资料
有不少的读者,希望我推荐一些持续交付方面的参考资料。因此,我稍作整理,把我觉得最最值得推荐的参考资料列在了这里:
<li>
《持续交付:发布可靠软件的系统方法》,是一本必读书籍。
</li>
<li>
《凤凰项目》以小说的方式介绍了一些持续交付和DevOps的理念非常有趣。
</li>
<li>
官方文档。这里我有一个建议,就是在学习和运用开源系统和工具时,要先通读官方文档。这些文档都是作者心血和智慧的结晶,从中你定可以收获颇丰。所以,我建议你能把阅读官方文档形成一个习惯。
</li>
这里,我再啰嗦一句,**持续交付体系中涉及到很多开源软件,如果你想做好持续交付,那就一定要去理解它们,而不只是使用它们。**
## 我讲的不一定都是对的
最后,关于持续交付,我还有一个非常重要的建议,要分享给你:我们通常在网络上看到的与持续交付相关的分享,都是经验与实践。
那么,我们就需要认清这么一个现实,既然是经验与实践,那就很可能要受到当时情况和条件的限制:这个经验与实践,也许在当时是最优的,但未必现在还是最优的;也许在此处能正常工作,但换一处未必能行。
但是,你也不要因此而悲观。虽然我不能告诉你怎样做一定是对的,但是我分享了怎样做一定是错误的。这些一定错的部分,也可以说是我们进行持续交付的一条底线吧。
而且,如果你有机会可以修正和弥补那些不那么正确或不那么适用的部分,将可以使你自己的持续交付过程变得更好。
所以,最后,我希望我的专栏能给你带来不同的思考。思考出你自己的观点和解决方案,并付诸实施,这才是最棒的。