文 | 宫元 on 测试
环境对于一个迭代迅速的电商公司来说,它的重要性无须赘述了;如何让环境高效,满足多项目并发对环境的需求,节约环境机器成本,建立环境标准体系,这不是几个人的事情,而是框架组、运维组、开发、测试、pm 大家共同努力的结果,其中的过程也不是一帆风顺的,有赞在这条路上走过了很多坑,今天就给大家分享下我们的经验。
一、有赞测试环境背景历程
有赞从最早到现在一共有过 dev(已废弃),daily,qa,perf,pre5 套环境,其中 perf 环境,是专门用来做性能测试的:
二、有赞测试环境多环境实现原理
刚才我们讲了有赞环境的历程,提到了 sc 多环境方案,想必大家关注到了,现在就开始讲下 sc 多环境的解决方案。
有赞 sc 应用隔离解决方案是由框架组提出的解决方案,产生的背景是为了解决项目并行,大家抢占资源,开发 5 分钟,联调测试 1 小时的问题。
1)全链路标识透传弱隔离方案
全链路标识透传 service chain,简称 sc 方案,是一种弱隔离的环境方案,简单分析下两种主要的隔离方案:
两种隔离方案优缺点分明:
强隔离:优点,隔离性强,不用修改应用,对应用侵入性低;缺点,运维成本高
弱隔离:优点,全链路标识透传,降低不必要的运维机器成本;缺点,隔离性弱,对应用侵入性高
最终我们选择了弱隔离,原因是有赞业务发展形态决定的。有赞零售等垂直业务的崛起,而垂直业务依赖了绝大多数的底层应用服务,为了降低运维服务器成本,所以我们选择了弱隔离。
框架设计这个方案最初设定了 4 个目标:
a. 按需隔离应用,只需要隔离需求中有变更的应用
b. 全链路标识透传,为以后的全链路压测打下基础
c. 应用侵入低,更多的由应用框架和中间件来感知和担保,应用自身做到低侵入
d. 使用方便快捷,通过平台(基础保障平台)创建隔离的 sc(service chain)环境
最初的全链路设计方案
面那条线我们称为“基础环境”链路,下面那条线我们称为“sc 环境”链路,当标识透传到下一个服务的时候,如果没有找到对应 sc 应用节点,会默认走标准环境,如果有对应的节点,走 sc 环境的应用节点,整个过程 sc 标识从一开始的 web 端 http 请求传入,就一直透传下去。
此外还会遇到一些重要的细节点,比如消息 NSQ 中间件,我们也做了隔离标识透传设计方案:
比如业务代码异步调用标识透传问题,可以自行定制 Runnable 或者定制线程池再或者业务方自行定制实现。
2)Service Chain 路由
全链路标识透传,那就要求入口发起的请求,无论是哪种业务应用或者何种协议,何种框架,都必须将源端的 sc 标识透传下去,如果其中任何一个环节标识透传失败,就没有意义了;这里主要讲下两种主要协议的标识透传:
第一种,RPC 调用。
首先应用框架层面改造,实现 RPC SC 路由,再通过 web 发布平台将应用带有 sc 标识服务信息写入 etcd,这样 RPC 调用的时候直接通过 RPC 路由将 sc 标识进行透传,如果没有匹配到 sc 标识,默认走到基础链路服务,RPC 路由实现原理如下:
第二种,REST调用。
规定 rest 调用必须通过域名调用,规范统一的域名命名方式,比如应用 A 提供 rest 调用,这样命名:http://A.qa.xxx.com:port/
尽量做到命名简单统一规范,再通过 web 发布平台将应用带有 sc 标识的 rest 服务信息写入到 etcd;接下来很重要的一步,实现 rest sc 路由,做法是部署一台专门干这个活的机器, 这里称为 sc-nginx0 机器;rest 通过域名调用都会走到 sc-nginx0,sc-nignx0 再通过 nginx 配置做全应用名称模糊匹配,从而转发到对应的应用 rest sc 服务节点,这样就实现了 rest 调用标识透传。需要注意的是如果路由不上,会走到兜底的 sc-nginx1 机器,sc-nginx1 会路由基础链路服务。链路图如下:
这里再给大家展示下,有赞的标识透传表现形式,仅供参考:
3)Service Chain 入口
前面讲了 sc 的整体和路由,sc 标识究竟是怎么传递进来的呢,那就自然要讲 sc 入口了。
有赞业务业务入口,绝大多数是在 iron 工程,因为历史包袱这是一个相当复杂冗余的 php 工程。后来随着业务发展,我们将部分业务入口从 iron 代码剥离出来,形成一个个独立的前端是 node 的微服务,简单分别讲下两种不同的入口实现 sc 方式。
第一种,iron 入口。
首先针对不同的环境,本地需要绑定 host,域名需要接入统一网关,接着通过 web 代理页面,给浏览器 http 访问 header 头带上 iron 访问多人路径名 who 信息、sc 标识信息必要信息,最后在代理页面选择入口机器(ps:多人 iron 机器),就可以开始 sc 调用之旅了;iron 服务我们不同环境只有一台服务,在机器上建立多人路径名,通过 who 信息由 tengine 走到各自的路径 iron 代码,这样我们就解决了 iron 入口的问题;接下来 iron 调其他服务,会通过 rest 请求,前面我们有讲过 rest 调用的路由,我们在代理页面已经将 sc 标识带入了,所以 sc 标识会接着往后面透传了。绝大多数 iron 调用服务化服务都是通过 rest 调用的,但是 iron 复杂在历史有些业务还通过了 rpc(nova) 调用,我们通过改造 tether 中间件给与了 sc 标识透传支持,这里有赞特色特别鲜明就不过多介绍了;这里还有一些 php 比较复杂的 nginx,tengine 代理也不讲了,有同样背景且感兴趣的伙伴可以私下交流。
第二种,node 入口。
node 入口,类似于前面介绍过的 rest 调用路由,需要申请浏览器访问的外部域名,同时外部域名要确保接入统一网关;再通过 web 发布平台将带有 sc 的外部域名 rest 信息写入到 etcd,我们通过浏览器域名访问的时候,入口通过 web 代理页面选择 sc-nginx 路由机器,sc 路由机器会转到对应的 sc node 服务,这样就解决了 node 入口的问题。
最后为了降低环境使用成本,我们入口做了统一,将测试环境老的多人 iron 入口使用姿势也改成了 sc-nginx 入口,同时兼容了多人 iron 的访问实现;因为有赞鲜明特色不多说了,仅供参考,链路方案如下:
4)Service Chain 出口
对于内部业务来说,没有 sc 出口一说,这里说的出口是指外部三方的调用。三方调用支持 sc 分为两种,一种是同步查询只要对接的第三方应用支持 sc 标识就可以了;还有一种是异步回调,可以通过给三方传回调地址加入 sc 标识实现,内部应用获取回到 url 的 sc 信息,这样可以实现 sc 标识涉及第三方透传,这种方法大多数情况下三方都是可以支持的。
至此 service chain 环境隔离技术层面的方案差不多这样了。
三、有赞环境推动
上一个环节已经大致的介绍了有赞 service chain 全链路标识透传隔离方案的技术实现,这个环节开始介绍我们在确定技术实现方案之后,做的一些列推动的措施。
1)推动应用框架升级接入sc
前面我们说了 RPC 调用是通过框架实现 sc 路由的,所以推动应用框架、nsq 客户端升级,这一步非常重要;因为很多业务链路很长,如果某些业务线没有升级,整个 sc 链路就会卡在某个应用没法透传标识;这点在一开始的时候,我们没有做好,因为前期的宣传力度不够,推动不足,导致有些业务线接入 sc 升级比较快,有些业务线相当滞后,项目试点之后才发现还不支持 sc,给后面的试点带来了很大的阻力和困难;所以建议,如果一旦确定好适合自己的隔离方案之后,开始推动的时候,做好充分的准备,定好时间,并指定各业务线的跟进 owner。
2)推动应用接入配置平台
因为经常会发现某个应用因为环境依赖的基础服务配置不对,导致应用的测试环境服务各种问题,排查的时候要去 code 里看配置,非常的耗时与不便;所以为了方便管理应用环境配置,我们做了应用配置平台,推动应用平台配置化,把一些基础的配置模板固化,这样我们环境配置的问题基本就能解决了。
3)推动基础环境整治
这一步非常核心,因为只有基础环境稳定,大的测试环境才会稳定。核心是维护基础环境服务,下掉多余的基础环境机器(ps:服务不带标识信息的机器)及服务,基础环境的应用服务只保留一个,这样保证了我们基础环境服务链路简单清晰,方便了问题定位,也方便控制基础环境发布权限。还可以从以下几点考虑来治理基础环境:1,测试环境基础链路服务发布权限管控,只允许发布 master 代码,不允许轻易发布,保证基础链路服务稳定;2,基础链路服务当天生产环境有代码变更,凌晨自动更新 master 代码等。
4)web 应用发布管理平台
前面有说过,sc 应用服务信息写入 etcd,是通过 web 发布平台,所以我们需要一个方便便捷的 sc 环境应用发布管理平台。
创建 sc 环境
sc环境应用管理
这里值得一提的是,sc 服务的机器可以申请虚拟机,也可以用 docker,从成本而言,我们默认是使用更加节约成本的 docker。
5)推动项目试点
在准备工作做好之后,可以选试点项目试行了,因为环境方案问题的复杂性,建议不要一开始就推行全公司,可以找一些项目先做试点;在试点的过程中,我们会发现各种明显坑,等把这些明显的坑解决一圈之后,再推全公司实行。
6)共性问题解决方案跟进
共性问题有哪些,比如有提到过的测试环境调用第三方支持 sc、卡门支持 sc 等等,在环境使用的过程中,会遇到大家都会遇到的问题,这类问题影响是大范围的,那就必须拉群及时跟进响应解决,如果不能及时解决就会降低大家使用推动环境优化的积极性;处理完问题,需要及时总结记录,大的问题还要及时通知,以及在培训过程中给大家举例讲解;有赞在环境推动的过程中,我们大大小小的建了 40 多个问题跟进的群,制定了 10 多个共性问题解决方法,这些方案有着很鲜明的我厂特色,这里就不给大家分享了。
7)环境基础保障
测试环境使用的便捷稳定,必然会要求我们做一些环境基础保障的工作,比如开发测试环境数据 mock 平台、服务监控平台。
环境数据 mock 平台—测试团队目前开发覆盖了包括大数据,交易,支付等 14 块业务 mock 场景,大大提升了测试环境的高效便捷;比如测试环境有些特殊的场景是需要数据构造的,店铺没钱了,e卡支付账号没钱了,添加店铺管理员等,都可以通过测试平台自己实现。
基础环境服务监控平台—测试环境基础环境链路的服务稳定直接影响了环境的稳定性,如果基础环境服务异常,会影响到所有人测试环境使用,为此开发了环境服务监控平台,覆盖了 daily、qa、pre90% 以上的核心应用的服务;每隔 10 分钟监测一次 etcd 应用的 dubbo 服务,一但发现某环境服务异常,就会给应用的测试角色发送邮件告警、以及内部工具告警,测试童鞋收到服务异常告警,及时处理,避免测试环境服务长时间影响大家使用。
服务异常告警
环境监控平台非常重要,我做过统计,环境问题至少降低 70% 以上,提升环境排查解决效率至少 80%,很多时候服务异常了我们第一时间就解决了,避免了大家感知,还有其他的一些环境保障的工具这里就不多说了。
8)环境方案规范制定
对于环境使用者来说,很多时候他可能不需要详细了解环境隔离方案的实现,更多时候比较关心环境究竟怎么使用。所以在方案之后,我们需要制定环境使用规范,有赞针对入口变化,前后制定过两个版本的使用规范 ppt,大致的内容如下:有赞环境介绍,应用接入 sc 规范,环境使用规范,测试环境交付规范,移动端使用规范,环境保障,环境发布权限规则,很多内容在前面也都讲过了。
9)环境培训
有了环境方案规范之后,对于一个已超过 600 技术人员的公司来说,还需要通过一系列的环境培训,这样才能确保每个人都知道如何做如何使用。在有赞是通过各业务线组一个个宣讲进行的,还有新人入职技术大学培训,前后组织了接近 20 场培训,除此之外还反复强调老人要帮扶指导新来的童鞋环境的使用,通过这些努力才能保证绝大多数人知道怎么使用环境。
10)环境故障定级
在我们做了大量的培训、宣导之后,还是会有童鞋将测试环境基础环境服务弄出问题,这是很难避免的,毕竟使用的人多,大家对环境的学习理解程度又不一样。对于这种情况就需要制定惩罚措施了,给环境故障定级,分为 p1(影响阻塞基础环境主链路的故障),p2(影响非主链路或者非基础环境的故障),对于故障多的业务组,予以通报tl。
11)环境问题记录
环境的问题各式各样,多而繁杂,需要组织专门的老司机,负责排查环境问题,尤其在当下微服务越来越细化的背景下,一个环境问题出现了,需要查好几个业务线N个应用,这是很大的工作量。所以环境问题显得非常必要了,有了环境问题记录,当我们再遇到类似的问题的时候,我们可以有经验知道怎么快速定位问题以及解决。
环境推动方面大致这些,每个公司都会有自己的制度,主要是希望可以给大家借鉴。
四、有赞环境与持续交付
有赞 2018 年提升研发效率,很重要的一个动作就是 devops,为此我们做了 CICD 平台帮助我们更高效的进行日常项目管理。环境的稳定,与持续交付的推动是紧密联系的,标准规范方便使用的稳定环境是持续交付的基础。
项目的发起从 daily(开发)环境发起,开发完成 daily 环境的冒烟自测之后交付到 qa 环境,测试童鞋 qa 环境完成测试之后交付到 pre 预发环境,预发验收之后就可以发布上线,这是一个完整的项目生命周期,开发和测试环境的隔离,可以使得项目进行的更加顺利。
举例说明,xx 项目是一个非常大的项目,涉及到的业务方 7,8 个,涉及的应用 60 多个,如果测试和开发童鞋都在 qa 的 sc 环境测试,那么会出现测试在测试的同时开发修复 bug 重发服务,从而打断测试的情况,这样的大项目就没有办法进行下去了。如果按照交付的思路,开发在 daily 环境完成自测,交付 qa 测试,大家互不影响,可以很好的提升项目效率。
通过 web 平台,目前准备一个隔离的复杂的项目环境基本上可以控制在半个小时内。我们还有很大的提升空间,比如在 docker 容器服务化上还可以做很多改进,和 CICD 结合之后,整个项目的生命周期过程实现自动化。
五、个中得失感悟
到了这里有赞环境方便的分享差不多就结束了,因为有赞的历史包袱复杂性,导致我们的环境相对复杂,从接手环境治理到取得阶段性结果,差不多半年时间。期间处理遇到很多的环境问题,也走了不少弯路,一点一滴的经验都是宝贵的。环境问题在大多数公司都是一个头痛的问题,所以很多时候心态上需要心平气和,遇到问题大家一起解决也是获得成长和友谊的过程。特别感谢运维和框架的兄弟们特别多的帮助和付出,有你有赞!