1、项目背景
2020年的春节被新型冠状病毒感染肺炎疫情蒙上了一层阴影,看到疫区医院IT运维志愿者的召集令以及各地同行纷纷动手开发系统为国家尽力时,我司(天津云顶云科技有限公司)作为行业的一份子,也想在这个特殊的时期做点什么,贡献自己的一份力量。
在这个时候,我们接到了合作伙伴外语教学与研究出版社的电话。原来,为了积极响应*和教育部门“停工不停学”的号召,伙伴决定将旗下的《新概念英语》免费向社会开放,希望我们能给予技术上的支持,能尽早上线,帮助广大学生在疫情期间依然能有机会学到最好的知识。
在就产品需求、技术方案、人员情况、当地疫情等多方面的全面评估后,我们决定一起用技术奉献社会,用最短的时间完成这个公益项目的上线,并确保它能够平稳运行。
2、项目分析
2.1 时间紧
团队虽然年轻,干劲却很足,给自己立下了FLAG:从研发到上线,赶在96小时内完成目标!
既然做了决定,我们就这样如火如荼地开始了紧张刺激的冲刺96小时。
2.2 压力大
结合相关的数据与经验,我们初步预估项目上线后的冲量峰值压力将会是上线前的20倍左右。
后来的实际情况也证实了这一点,2月4日上线当天,瞬间涌入的峰值压力是上线前平均值的19.4倍。
因此,如何筑起高墙大坝,扛住突如其来的流量洪峰,是我们要面对的第一个难题。
2.3 协作难
由于春节期间很多同学都回老家过年,项目相关的成员分散在北京、天津、山西、福建等全国各地,这也是我们团队第一次展开这么大规模的远程协作,很多问题一下子凸显了出来:
- 网络的问题:尤其有的同学在农村,网络不太稳定,有时信号一断只能干着急。
- 联调的问题:平时在公司通讯基本靠吼,或者探身看下屏幕就能了解情况,现在只能靠不停的码文字、语音、电话......
- 项目管理的问题:时间紧任务重,现在只能倒排计划,就像一面开车、一面查目的地的情况...
没想到因缘际会,使我们团队可能成为了全国最早远程复工的那一波人之一 >_<
2.4 测试难
由于事发紧急,只能一边研发一边测试,这样的方式对于我们这样有着DevOps经验的团队来说倒也不是太大的难事,只是有一点比较麻烦:扛住巨大的流量压力是整个项目中最为关键的一环,如果不能做到万无一失,即使万事俱备也有可能功亏一篑。
因此,
我们不仅需要做足够的压力测试,还要做到严格、靠谱的压力测试;
我们不仅要在测试和预发环境上做压力测试,还要在生产系统上做压力测试;
我们不仅要在白天边研发边测试,还要在夜深人静压力位于谷底时在生产环境上滚动更新做压测,验证功能、查找问题、参数调优等一通操作猛如虎,然后再回滚回来确保白天用户正常使用...
3、冲刺96小时
伟人说过,一切敌人都是纸老虎。
与困难狭路相逢,勇者胜!团队没有二话,只有一个字:干!
3.1 打磨需求,不放过每个细节
这个文案与这次公益行动不符,要改!
这个不容易理解,要改!
正向需求验证没问题,既有的系统功能呢?要验证!
前台交互没问题,后台日志系统是否有影响?要分析!
对其他依赖的第三方应用是否有影响?要保证兼容性!
……
3.2 持续优化,力争做到万无一失
流量增加 50%能不能抗住?流量翻倍能不能抗住?流量数十倍增加能不能自我保护?能不能动态扩容抗住压力?能不能减少流量抖动带来的不必要的弹缩?流量模型是什么样子?流量会聚集在哪个瓶颈点上?各个突发情况下,除了自动化机制外,还有哪些其他的应急措施?
在这样追问、讨论中,大家不断深入思考;在各种压测数据中,大家不断探求优化的思路和可能。为了不影响既有用户的访问,所有的压测都集中深夜;为了获得真实的一手数据,敢于直接压测生产环境(这也得益于系统的鲁棒性强)。
3.3 胜利会师,圆满完成任务
- 连续作战 4 天 4 夜,不只 96 小时
- 持续发布 7 版,不断迭代完善
- 流量激增19.4倍,扛住了!
- 钉钉语音会议 30+ 次
- 参与的同学 20+ 名
4、解决方案
总结起来,该公益项目能快、准、狠地完成,主要得益于以下几个方面:
- 项目采用了微服务架构,模块之间耦合度较低,新功能上线可滚动发布,加上团队具备DevOps能力,因此保质保量地完成了研发任务。
- 项目完全基于阿里云的容器服务ACK构建,同时得益于阿里云强大而全面的产品矩阵来加持,使整个项目的稳定性、可靠性上更上了一层楼。
除了阿里云强大的容器服务以外,我们也用到了大量的其他产品如OSS、CDN、PTS等,强大而且全面的阿里云是本项目成功上线的幕后英雄。
最终,我们利用阿里云的若干产品完成了如下方案:
这个方案具有以下特点:
- 应用容器化部署,享用云原生容器组资源编排能力
- 优化容器组集群计算资源,集群稳定性高
- 利用弹性伸缩以及抢占式实例,弹性低成本
- 解决自建集群快速扩容困难问题
- 内容分发网络CDN有效分担源站压力,避免网络拥塞,确保在不同区域、不同场景下加速网站内容的分发,提高资源访问速度。
4.1 方案解读:两级弹性伸缩
由于流量洪峰的不确定性(不确定什么时候到来,不确定最终的压力有多大),同时还要考虑到财务的可行性,不惜一切代价是态度,但不能作为工程实践的指南,要让花的每一分钱都有价值。因此我们最终采用两级弹性伸缩的策略:
- 利用ESS对整个集群进行弹性伸缩,ESS是阿里云推出的可以自动调整弹性计算资源的服务,可以根据业务需求和策略设置伸缩规则,在业务需求增长时自动为您增加ECS实例以保证计算能力,在业务需求下降时自动减少ECS实例以节约成本。
设置ESS:当CPU平均使用率达到75%或内存使用率达到80%时,会向K8S集群中添加两台ECS,以提高系统整体的服务能力。
- 利用K8S的HPA机制对容器资源进行弹性伸缩,最大限度利用云资源的水平弹性。HPA是实现水平伸缩的控制器,它能在当POD中业务负载上升的时候,创建新的POD来保证业务系统稳定运行,当POD中业务负载下降的时候,可以销毁POD来提高资源利用率。
设置HPA:当CPU平均使用率达到70%或内存使用率达到80%时,会水平扩展POD数量,以提高热点服务的能力。
4.2 使用HPA趟过的坑
在使用HPA的过程中,我们也遇到了一些问题,虽然历经一些波折,最终也顺利解决,这里一并记录。
问题1:在压测过程中发现,POD分布不均匀,相互间存在资源争抢的现象,导致服务器资源富裕而性能提升不上去的情况。
解决办法:对于资源消耗较高的服务使用硬性反亲和,资源消耗相对较低的使用软性软亲和方式可以有效利用服务器资源,提高整体系统性能。
问题2:POD的CPU和内存的基准值配置错误,导致使用率始终超过弹性伸缩的阈值,POD直接弹缩到最大值。
解决办法:调大request值,将使用率控制在HPA值之下。
问题3:POD启动消耗的资源较大,启动瞬间会将POD数量弹至最大值,从而导致整体资源使用率过高。
解决办法:等服务启动稳定后再配置HPA规则即可解决。
4.3 方案解读:利用PTS进行专业准确的压力测试
PTS是阿里云推出的云化测试工具,是项目中压力测试的好帮手。它可模拟海量用户的真实业务场景,全方位验证业务站点的性能、容量和稳定性。通过较低的人力和资源成本,构造出最接近真实业务场景的复杂交互式流量,快速衡量系统的业务性能状况,为性能问题定位、容量最佳配比。
利用PTS,我们进行了100多轮不同接口不同规模的压力测试,快速地定位问题、解决问题和回归验证,是项目压力测试的绝世神器!
通过这些压测实践,我们也总结了一套关于压力测试的心得:
- 根据接口需要达到的并发,来进行首次递增式压测,来查看目前接口能达到多大的并发。
- 压测完成后,查看压测数据,查看RDS,ECS,Reids等监控,从资源方面入手来查找瓶颈,来查看是否是连接数设置的问题,还是资源性能问题。
- 从架构方面来进行排查,从底层一步一步来排查。先将直接压接口,看看接口能达到多大
- 并发,然后在加上SLB来压测,来看是否是服务配置问题。
4.4 使用PTS趟过的坑
问题1:使用PTS压测时发现来源IP过于集中,如何能让压测数据更有可信度?
解决办法:经优化,选择了扩展来源IP和指定地域配置来进行压测,从而实现压测数据的可信性。
问题2:模拟大量客户注册登录,最开始创建的压测创景是只使用一个账号密码来进行反复登录,也存在压测数据的可信度问题。
解决办法:后来经优化场景,采用自定义参数,随机生成一些数据库中没有的账号,来进行传参,更真实的模拟了用户登录场景。
问题3:不通时间段,同一个接口压测结果相差较大。
解决办法:在压测的时候有时候可能会有网络抖动,影响压测结果,同样的接口,在没有任何修改的情况下,白天和凌晨压测的结果,相差较大,白天TPS相对要高一些。由于客户的正式站不能在业务繁忙的时候进行压测,所以将测试站配置对齐正式站,选择客户业务繁忙时间,来进行压测测试站,最后来和正式站压测数据对比。
PTS的报告十分直观,信息也很详尽。
4.5 方案解读:利用CDN分发加速减轻源站压力
由于终端用户分布在全国各地,但课程的音频资源放在阿里云的华东2地域(上海),距离较远的用户在使用过程中就会出现较高的延迟。为了解决这个问题,我们引入了CDN。
利用CDN分布在各地的边缘节点,有效分担源站压力,避免网络拥塞,确保在不同区域、不同场景下加速网站内容的分发,提高资源访问速度。
5 项目总结
紧张刺激的96小时,通过伙伴外研社团队、云顶云团队和阿里云的精诚协作,最终顺利完成,上线后用户好评如潮,我们也在全国共克时艰的时候,为抗击疫情贡献了自己的一份微薄之力,也为云顶云在云原生、微服务的探索之路上添加了重要的一笔。
以不远的将来,云顶云将继续秉持“让云计算更简单”的理念,立足于阿里云强大的技术与生态,服务更多用户,为祖国蓬勃发展的互联网事业继续贡献自己的力量。