目录

PingCode 的环境和环境管理

作者:PingCode 孙敬云

一个软件产品的稳定性、可靠性、可用性很大程度上取决于我们如何有效地管理它的环境。这里的”环境“指的是我们在运行软件时,需要的一整套组件,包括硬件、系统、服务、资源、工具和软件本身。在一个健康的软件开发流程中,我们通常需要很多个环境来服务于这个软件产品。

它们服务于不同的场景,缺又都支撑着整个交付流程。在这些环境中,有的必须完全独立的,有的可以共用一些基础设施组件,有的干脆就是启动了多个实例而已。阶段不同、产品不同,环境就又差异,接下来我就跟大家分享一下 PingCode 会使用到的环境:

Tips:PingCode 是由 Worktile 团队打造的智能化研发管理工具,帮助企业实现对研发过程两条工作流的管理,实现研发管理过程的自动化、数据化、智能化,帮助企业提升研发效能。《延伸阅读:PingCode 是什么

本地环境

本地环境是开发人员进行开发和调试的地方。在本地环境,开发人员几乎可以访问到所有必要的信息,也可以通过修改代码来实现必要的尝试,再加上本地环境中通常安装了开发人员最顺手的工具,因此这个环境是最让开发人员舒适的。不过在 PingCode 构建一个完整的本地环境并不容易,因为 PingCode 包含了上百个的服务,涉及到几十个代码库,要想把他们都配置起来那可太难了。好在构建一个完整的环境其实并没有那么必要,开发人员只是需要一个能够把自己的项目代码运行起来的环境而已,这时候让本地程序直接连接开发环境的部分资源就可以了,我们只需要将数据分离开来就好了。

开发环境

开发环境是团队统一构建软件的地方。开发环境通常具有较为完整的基础设施组件,但是软件功能会比较新,而且还充斥着半成品,很多开发人员还会直接修改数据库来达到一些特定的效果,不过这些都是必要的,每个“漂亮”的软件产品都有这样杂乱的车间。在 PingCode,我们的开发环境其实是一个虚拟的环境,它能够帮助开发人员提供各种各样的服务,但是它不是一个具象可见的环境,它的所有服务都是映射自我们的测试环境,包括数据库和其他基础设施组件。这样当然有其好处,因为我们可以少维护一个环境,你要知道,开发人员在类似的事情要做两次这件事上是很在意的,所以慢慢的我们就养成了直接用“测试环境”的服务和数据来验证自己新功能的习惯。

image.png



享受了便利,就要承担它带来的隐患,那就是数据的准确性。PingCode 是一个企业用的多租户服务,它的数据体系是基于一个又一个的“企业”,于是我们就约定俗称为人手几个“企业”账号,只要不涉及全局通用数据,自己“企业”下的数据随便使用。

测试环境

测试环境是我们用“肉眼”体验和测试产品的地方。相比开发环境来说,测试环境更加的独立、完整和稳定。除了软件版本和服务器的性能之外,我们应该在各方面都努力让它和生产环境保持一致。因为如果测试环境和生产环境的差距过大,那么有些问题我们是很难在开发阶段发现的,而一旦过了测试环境,定位和修复缺陷的复杂度就会越来越大,已经有大量事实证明,发现问题的地方越靠后,修复它的成本也就越高。在我看来,构建一个强大测试环境的成本一定比频繁定位生产环境问题的成本要低多了。

我们为测试环境的投入非常大,它的复杂度也就小于生产环境而已,虽然硬件配置上不如下文中的很多环境,但是它的组件完整性几乎和生产环境一致。除了运行 PingCode 必须的各类组件之外,日志系统、监控系统、安全组件、外部系统的账号等也都是独立的一套。

环境能力是一方面,PingCode 本身的服务的稳定性也很重要,我们通过 PR 流程和 CI/CD 流程来保障合入测试环境的功能的准确性,然后通过回滚和数据还原能力来进行兜底。

image.png



Feature 环境

Feature 环境是一组用于体验还未合入到主版本的新功能的地方。这些环境通常是几个并存,它们都是随用随建,用完即删。不过每个 Feature 环境在使用上不太一样,有的环境需要独立入口,但是基础设施组件和常用的 PingCode 服务可以共用;有的环境则要求必须是完完全全独立的环境,这取决于开发团队的需求。比如说:一些跨子产品的重大功能,开发周期也很长,开发团队就会申请创建一个 Feature 环境;还有一些 PingCode 前端的项目在提交 PR 的时,我们会自动为其创建一个专门用于预览 PR 里新特性的环境。这些 Feature 环境是为了保护主版本的开发顺利推进的同时,满足一些并行开发的需求。

image.png



预发布环境

预发布环境是一个更像生产环境的”测试环境“。这个环境通常是给产品经理们验收产品用的,它还有很多别名,最常听到的就是 Staging 环境,我们内部简称它 Beta 环境。在预发布环境上的测试过程很像一个真实客户在使用产品,这使得测试数据更加逼真,我们也更容易体会到产品功能是否真的合理。除了功能层面的测试,预发布环境还会进行部署层面的测试,不同于通过主分支上的代码变动实现测试环境的持续部署,我们通过打 Tag 来实现预发布环境的部署,而这次部署用的制品(Docker 镜像)将被长期存放在制品库里,也只有经过验证的制品才能用于后面的环境,相当于功能锁定了。

image.png



验证环境

验证环境是专门用来验证 PingCode 重要升级方案的环境。为了更加贴近的生产环境的升级状态,验证环境的基础设施配置会高度模拟生产环境的配置,通过在这个环境中执行升级方案,我们可以观察到各个基础组件的压力,从而让我们更加了解本次版本升级方案,也知道如何应对可能出现的问题。

不过验证环境的成本着实不低,不适合长期运行,而且也不是所有的升级都有必要这么验证,绝大多数的日常变更直接滚动升级即可,只有那些变动很大,拿不准的升级方案才需要走一遍验证环境,而需要使用验证环境时,通过我们的自动化流程现构建一个验证环境即可。

image.png



基准环境

基准环境是专门用于性能测试的环境。性能测试只是一个概括性的说法,我们定期会进行这样的非功能性测试,而这类测试最吃环境了,因此我们准备了一个同比例缩小生产环境的环境,并将其命名为基准环境。在基准环境中,我们部署一个指定版本的 PingCode,然后在另外一台服务器上执行预先写好的脚本,最终我们将跑出来的结果按比例放大,粗略的得出一个性能测试结果,最后再用这个结果指导我们的改进方向。

金丝雀环境

金丝雀环境是引生产环境的流量来验证新功能的环境。它是软件产品全面部署到生产环境之前的一个小流量测试环境,先部署到金丝雀环境可以提前发现一些上线后的潜在风险,增加开发人员的信心,这在 PingCode 内部是必不可少的一环,简称上 RC 环境。我们会提前邀请一些客户和使用者,比如我们公司自己,加入到这个引流的策略里,然后借由这些真实的流量检验新功能的可用性,直到新功能稳定运行一段时间之后才可以申请部署到生产环境。需要说明的是,金丝雀环境共用了生产环境的基础设施组件,包括数据库,因此在新功能部署到生产环境之后,这些提前“新增”的数据并不会遗失。

image.png



生产环境

生产环境是给客户使用的环境。保障生产环境的稳定性是保障企业的商业基础,这里我就不展开。

灾备环境

灾备环境是专门用于灾备场景的环境。比如其中一个作用是进行灾备演练,我们会将一些非常重要的、业界有通识的、我们遇到过的问题定义为演练项,然后通过演练这些灾难和执行对应的预案让我们的技术团队能够对灾难有同理心和应对力。

演示环境

演示环境是我们为客户演示时使用的环境。这类环境不同于其他环境,它不是在技术的视角来服务于产品稳定性的,而是在商业的视角服务于业务稳定性的。作为一个专业性的软件,客户在自己摸索的过程中会遇到很多问题,这时就需要一些产品专家将软件的设计理念更好的传达给客户,于是就有了这样的一套环境。这个环境里面的数据是我们的产品专家提前创建好的,并且每天都会重置,然后由客户顾问顺着产品专家的思路带着客户体验一下产品功能,这样就能更好的引导客户认识我们的产品。

image.png



环境管理

其实除了上述这些环境,我们还有很多其他的环境,比如用于私有部署场景的、用于基础设施组件测试的,那么这里就引出了另一个问题。当我们只有一个环境时,我们只需要围绕着这一个环境解决问题;当我们有三个环境时,我们可以通过容器化和容器编排来更高效的管理应用程序,而环境本身的问题无非就是比一个时多一些而已;可是当我们有几十个环境时,那多出来的这些环境问题就需要我们认真思考了。

首先,我们需要把“环境”当作一种资源来理解。如果理解的纯粹一些,环境是一整套包括硬件、系统、服务、资源、工具等外部组件的集合,而我们的软件只是运行在这个环境中的一个实例,就像鱼缸和鱼的关系一样。那我们现在有几十个环境,每个环境中运行一个/多个软件实例,那就是并排着摆着几十个鱼缸,每个鱼缸里都有鱼在游来游去,鱼缸大小不一致,鱼儿们的样子也不尽相同。我们还需要将软件的新版本持续的通过 CD 部署到不同的环境中,再进一步,我们随时需要创建一个新的环境,然后将 CD 接入进去,实现首次的部署,再进一步,我们只需要一个信号,就可以销毁掉这个环境,释放掉它占用的硬件、网络等资源。那么环境是什么,环境管理又是什么,我相信大家已经有了一个基本的概念。

其次,环境越多自动化和统一配置能力就要越强才行。这里的自动化不只是构建、制品和部署,它还包括通过脚本创建和管理环境里的所有组件(这里欢迎大家阅读我们另一篇文章「基础设施管理之 pulumi」);而配置能力则体现在应用程序所需要的环境变量、容器编排需要的参数、外部通用资源的接口等信息都应该存储在一个配置中心里,它掌管着所有环境的所有变量。在这两个核心能力具备了之后,接下来需要的就只是一个调度中心而已,这个调度中心一是负责和使用者们交互,二是通过它背后连接的自动化和配置中心能力。到此我们就可以实现按需创建和销毁环境了。

最后,虽然环境管理看上去似乎应该是一种更底层的能力,我们所有的环境都应该基于一个方案来管理。但是实际上我认为追求这种极致没太大的意义,环境就是有其特殊性,不适合一刀切,尤其是开发环境、测试环境和生产环境这种重要的环境。我认为环境中的自动化是必不可少的,但一切都自动化这就没必要了。

好了,今天就跟大家分享到这里吧。