腾讯问卷一直支撑着腾讯的调研问卷,但它太重,不适合用在微信群实时投票的场景,结合年初微信小程序发布之际,针对微信群场景,我们(CDC)做了个投票小程序。
大家忙活几周,第一版总算出来了。在运营阶段发现一个问题,而这个问题在腾讯问卷中也存在着:
闲时低负载,峰值高并发
腾讯问卷一直支撑着腾讯公司旗下几乎所有业务的调研问卷,例如游戏、音乐,以及滴滴等外部合作公司。基于公司的规模,问卷可能会在瞬间投放给动辄数十万的用户。平时可能用户不多,但只要有业务做大规模的推广时,系统负载会变得特别高。
而在投票小程序当中,这种问题更严重:
1. 无法控制个人用户发起投票的时间
2. 低估了社交场景的传播力量。不少投票可能是单位/学校发起的投票,要求所有员工/学生参与投票,除此之外,用户还会再转发到外部群,生成二维码转发到朋友圈去拉票
于是我们经常会从监控中看到流量暴涨:
流量暴涨,峰值接近平时的 5 倍
面对这种情况,除了对应用本身做优化,也做出了一个迁移腾讯云的决定。于是,在这个背景下,开始了拥抱腾讯云的工作。
迁移腾讯云的过程,开始筹备
1. 上腾讯云前的筹备
腾讯投票在立项初期是基于腾讯问卷的接口去开发的。所以第一步考虑的是有哪些组件可以剥离,以减少迁移的工作量,和提高后续的可维护性。
剩下一个最麻烦的:数据库拆分。目前腾讯投票与腾讯问卷的数据都在同一个数据库。如何把数据拆分呢?我们把过程分成 4 步:
现在我们得到了完整且没有多余数据的独立数据库了,后续迁移时只需要备份和恢复这个数据库即可。
迁移腾讯云的过程,迁移
2. 迁移
该优化的都优化好了,开始准备迁移方案。不停机的方案都有哪些?以下是我们的分析:
1. 腾讯云通过专线访问 IDC 的 MySQL
– 优:对于业务比较安全
– 缺:对于公司不安全
2. 腾讯云通过公网访问 IDC 的 MySQL
– 优:方便
– 缺:不安全
3. 在 IDC 运行期间双写 IDC 和腾讯云的数据库,数据一致时进行迁移和切换
– 优:无需额外策略、安全、不需要停机
– 缺:工作量巨大
停机迁移的方案?也有,就是直接停机,备份和恢复 MySQL,改 DNS 解析,再笨也能做好这件事
– 优:安全可靠,时间成本低
– 缺:需要停止服务
考虑到安全策略、时间成本等因素,我们最后选择了停机迁移。为了不出问题,切割前后还有一些工作:
演练
方案选择了,环境也准备好了,接下来是反复演练,检查迁移过程中可能会出现的问题,甚至把执行过的每一条 Shell 命令都记录下来。直到所有记录的 Shell 命令不需要再做修改,直接执行就能完成迁移工作。
切割
前期工作准备好,风险也分析了,回滚方案也有了,演练了这么多遍,也该上战场了,再不迁移,老板休假回来要找我麻烦了。找了一个周末凌晨的时间点,准备好停机公告。然后就可以照着演练时的步骤一步一步操作了。测试通过后就可以做 DNS 切换了。
观察
进行 DNS 切换后就意味着流量都会直接到腾讯云上的环境。接下来的几个小时是最紧张的时间,在监控上看着流量慢慢起来,用户创建的投票也多了起来,这才松了一口气。
关于跨机房迁移,不同的项目有不同的解决方案。具体情况具体分析,如何合理配置原有的 IDC 资源与云计算资源,可能会取决于项目的 SLA、开发团队的规模,安全策略的限制等因素。
迁移腾讯云的过程,弹性伸缩调优
3. 弹性伸缩
前面提到我们的痛点之一是闲时低负载,峰值高并发,有没有解决办法?有,腾讯云的弹性伸缩。利用弹性伸缩,可以做到白天高峰期自动加机器,晚上销毁。任意时间内如果访问量突增,也能自动加机器并投入生产环境。
在介绍弹性伸缩基础概念之后,还需要介绍两个名词:无状态化与服务发现
无状态化
无状态化是指服务不保存需要持久化的数据(不管是短暂的 session 还是长期的用户上传附件)。好处是可以快速复制和销毁实例而不需要考虑数据是否会丢失,这也是弹性伸缩对应用的基本要求。
因为腾讯问卷有文件上传等一系列等功能,无状态化会很困难,得需要很多时间和精力。而投票刚好没有用到这些功能。没有文件上传等功能,session 也没有保存到文件系统。天生就是无状态,非常适合做水平扩展,新增实例只需要加到负载均衡上就能投入使用。
服务发现
无状态化好处之一是快速复制或者销毁实例,这样就可以做到快速地水平扩容。如果这种水平扩容还需要人工参与,那效率会低效很多。所以必须跑集群式的服务。于是你会需要服务发现工具。
服务发现可以告诉你:哪个服务都有哪些实例在提供,例如:
监控脚本问:腾讯投票的后端服务器有哪几台?
服务发现回答:10.0.0.1:8080, 10.0.0.2:8080, 10.0.0.3:8080
在收到回复后,监控脚本就可以把这几个 IP 加到 Nginx 或者 HAProxy 的负载均衡中去了。
在弹性伸缩的帮助下,腾讯投票的后端服务器频繁变更,在服务发现软件 Consul 的帮助下,做到了新增机器时能投入使用,销毁时自动从 Nginx 中摘除,达到了不丢失用户请求的效果。
小结(以上两点需要:策略配置)
应用做好了上述的无状态化与服务发现机制后,接下来就是腾讯云的弹性伸缩配置:
在配合腾讯云的弹性伸缩、服务发现 Consul 以及各种监控系统的情况下,我们做到了:当系统高负载时,弹性伸缩开启新机器,监控脚本同步最新的代码以及启动相应的服务。最后,Consul 将新机器投入使用。
弹性伸缩的配置
当 CPU 利用率超过 70% 时加机器。
监控告警
图中可以看出 12:00 触发告警,12:02 机器启动完成,12:04 投入使用。弹性伸缩还是比较给力的。
迁移腾讯云的过程,监控
4. 监控
一路忙活,做了很多改动,有没有影响到用户?性能有没有变化?快了还是慢了?总不能让用户来告诉我们吧。还好有监控。
有了监控就知道每次变更带来了什么影响,在做运维变更、版本发布时,心里也比较有底。开发者也应该养成良好习惯,每次做完变更、发完版就要看看监控。
比如有一次,我们通过性能监控发现微信接口异常。当时,曲线显示用户投票量突然减少一半,但系统各组件都正常,也没有报错。排查后发现是微信开发平台接口做了变更,把一个字段给去掉了。如果没有监控,估计要等到第二天才能发现。
说了那么多,究竟监控什么呢?以下是我们所使用的监控系统:
多方位监控
CPU 动不动就会飙高,幸好有弹性伸缩。此外,我们正在优化投票结果的数据结构,优化完后 CPU 的波动应该会有改善
带宽跟随请求一并增加了
对比一下迁移前后的效果:
可以看出红色的慢请求减少,最底下的绿色也增多了。
服务器利用率这里还有优化空间,我们会在下一篇文章详细介绍。
5. 总结与展望
腾讯投票的定位是一款小而美的应用,像张小龙先生所说,用完就走,成为一个对用户有价值的小工具。
后续我们也计划将腾讯问卷 https://wj.qq.com 的 IDC 资源与腾讯云资源结合,使用弹性伸缩做到动态扩容,在提高运算能力的提前下减少运营成本。以及利用腾讯云的各种云服务为开发同学减轻运维负担,让开发同学更专注于开发业务,为用户提供更多更有价值的创新。
扫一扫,体验一下运行在腾讯云的腾讯投票
Tencent CDC(http://cdc.tencent.com/2017/08/11/是的,腾讯投票已经拥抱腾讯云了/)