一个在阿里云打工的清华学渣!
本文作者:杨牧原(花名牧原),阿里云技术专家,多年操作系统和应用调试经验,理论功底深厚,实践经验丰富。目前专注 Linux 性能调优,容器集群和系统网络。
本文经原作者授权发于公众号『程序猿石头』,在原文基础上稍作改动。
背景
疫情初期某地政府决定发放一批免费口罩面向该市市民,该市市民均可免费预约领取,预约时间为早上9点-12点,因此该场景为限时抢购类型场景,会面临非常大的定时超大流量超大并发问题,在该项目的落地过程中,涉及的架构演变,做了一些记录和思考。
架构图&分析-V1
高并发口罩抢购项目架构演进记录&优化经验分享_第1张图片
原始架构图示&分析(2月2号晚上22点左右的原始架构)
2月2号晚上22点左右的原始架构

  1. 客户端走 HTTPS 协议直接访问 ECS;
  2. ECS 上使用 Nginx 监听 HTTPS 443 端口;
  3. Nginx 反代 Tomcat,Nginx 处理静态文件,Tomcat 处理动态请求;
  4. 程序先去 Redis 查缓存,如未命中则去数据库查询数据,同时Redis 与 Mysql 之间的数据同步靠程序控制。
    这样架构设计:
    • 优点:易管理,易部署;
    • 缺点:性能差,无扩展性,存在单点风险;
    结果:事实证明该应用一经上线就立刻被打挂了,因未知原因预约页面被泄露,导致还未到预约时间,服务即被打挂。
    架构图&分析-V2
    随后我方介入,进行架构调整,24点左右找的我们,早上9点要开服,时间太紧,任务太重,程序不能动的情况下,几十万的并发架构如何做?
    2月3号早上9点左右的架构,4号也恢复了这个架构)
    高并发口罩抢购项目架构演进记录&优化经验分享_第2张图片
    2月3号早上9点左右的架构
  5. 接入 SLB,通过镜像横向扩展负载能力;
  6. 接入读写分离数据库架构,通过阿里云数据库自动进行读写分离,自动同步数据;
  7. 调整 Nginx 协议;
  8. 同架构备集群启用(域名解析做了两个A记录);
  9. 分析访问日志发现失败原因在获取短信和登陆初始化 Cookie 的点上。
    这样架构设计:
    • 优点:增加了高可用性,扩展了负载能力;
    • 缺点:对流量预估不足,静态页面也在 ECS 上,因此 SLB 的出带宽一度达到最大值 5.X G,并发高达 22w+。
    结果:因为流量太大导致用户一度打不开页面,同时由于域名服务商 XX 的限制,客户无法自助添加解析,且当晚联系不到域名服务商客服,导致 CDN 方案搁浅。
    架构图&分析-V3
    高并发口罩抢购项目架构演进记录&优化经验分享_第3张图片
    2月5号的架构
  10. 接入 CDN 分流超大带宽;
  11. 取消 Nginx 的代理;
  12. 做了新程序无法准时上线的灾备切换方案(没想到还真用到了);
  13. 使用虚拟服务器组做新老程序的切换,但是缺点是一个七层监听的 SLB 后端只能挂 200 个机器,再多 SLB 也扛不住了,导致老程序刚承接的时候再度挂掉;
  14. 5 号使用这个架构上线,7 分钟库存售罄,且体验极度流程,丝般顺滑,健康同学开发的新程序真是太爽的。
    这样架构设计:
    • 优点:CDN 负担静态资源的流量降低了 SLB 的出带宽,压测的效果也非常理想;
    • 缺点:需要多一个独立的域名在页面里面,涉及跨域,4 号临开服之际测试发现入库&预约短信乱码返回,紧急切换回了老程序,即二代架构。
    理想架构图&分析-V4
    高并发口罩抢购项目架构演进记录&优化经验分享_第4张图片
    理想架构
  15. 主域名接入CDN;
  16. CDN通过设置回源 Http、Https 协议去访问 SLB 的不同监听实现新老程序之间的切换,具体实现为回源协议对应。不同监听,监听对应不同的程序。
    这样架构设计:
    • 优点:静态加速降低SLB带宽,动态回源,无跨域问题,切换方便;
    • 缺点:仍需手工设置,镜像部署ecs不方便,如果时间充足,可以直接上容器的架构该有多美好呢,一个 scale 可以扩出来几十上百的 pod,也可以做节点自动扩容。
    总结
    时间紧任务重,遇到了N多的坑:
  17. vcpu 购买额度;
  18. SLB 后端挂载额度;
  19. 客户余额不足欠费停机;
  20. 域名服务商解析需要联系客服才能添加;
  21. 第一次考虑 CDN 架构的时候未考虑跨域问题;
  22. 新程序开发期间未连接主库测试,导致上线失败(主库乱码);
  23. 第一次(3号)被打挂的时候只关注了 SLB 的流量,未详细分析失败最多的环节;
  24. 上线前压测缺失,纯靠人工测试功能;
  25. 压测靠人手一台 Jmeter(4号晚上到5号早上引入了 PTS 进行压测);
  26. 突然想起来客户原始的程序是放在 Windows上的,Windows + 烂程序性能真的极差;
  27. 这个“小项目”前后竟然耗费了小十万,如果一开始就给我们做的话,应该可以减少一半的成本。
    最后的成果统计(采样分析,实际数据比这个还大):
    高并发口罩抢购项目架构演进记录&优化经验分享
    成果统计(采样分析)
    最后上线的三代架构,为了保险起见上了 150 台机器,但是根据活动期间的观察,以及对压测结果的评估,上 50 台机器应该就可以抗住了,从持续 5 小时一直崩溃被终端用户骂街,到 7 分钟库存售罄的领导赞赏,虽然经历了 3 个通宵的戮战,依然可以隐隐约约感觉到身心都得到了升华。
    各种优化笔记
    参数优化
    • 网络调参
    net.ipv4.tcp_max_tw_buckets = 5000 --> 50000
    net.ipv4.tcp_max_syn_backlog = 1024 --> 4096
    net.core.somaxconn = 128 --> 4096
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_timestamps = 1(5和6同时开启可能会导致nat上网环境建联概率失败)
    net.ipv4.tcp_tw_recycle = 1

    • /etc/security/limits.conf

    * soft nofile 65535
    * hard nofile 65535

    • nginx参数优化

    worker_connections  1024-->10240;
    worker_processes  1-->16;(根据实际情况设置,可以设置成auto)
    worker_rlimit_nofile 1024-->102400;
    listen 80 backlog 511-->65533;

    部分场景也可以考虑nginx开启长连接来优化短链接带来的开销
    架构优化
    • 扩容SLB后端ECS数量,ECS 配置统一;
    • Nginx 反代后端 upstream 无效端口去除;
    • 云助手批量处理服务,参数优化,添加实例标识;(划重点,大家批量使用 ECS,可以考虑利用云助手这个产品)
    • 云监控大盘监控,ECS、SLB、DCDN、Redis等;
    • 调整 SLB 为 7 层监听模式,前 7 后 4 关闭会话保持导致登录状态失效。
    程序优化
    • 添加 GC log,捕捉 GC 分析问题,设置进程内存;

/usr/bin/java -server -Xmx8g -verbose:gc -XX:+PrintGCDetails -Xloggc:/var/log/xxxx.gc.log -Dserver.port=xxxx -jar /home/app/we.*****.com/serverboot-0.0.1-SNAPSHOT.jar

• 优化短信发送逻辑,登陆先查询 Redis 免登 Session,无免登 Session 再允许发送短信验证码(降短信的量,优化登陆体验);
• jedis连接池优化;

maxTotal 8-->20
acceptcount优化(对标somaxconn)

• bug:springboot1.5 带的 jedis2.9.1 的 Redis 连接泄漏的问题,导致 Tomcat 800 进程用满后都无限等待 Redis 连接。后来进一步调研发现这个问题在 2.10.2 已经修复,而且 2.10.2 向后兼容 2.9.1。
数据库优化
• Redis 公网地址变更为内网地址;
• Redis Session 超时设置缩短,用于释放 Redis 连接;
• 慢SQL优化(RDS的 CloudDBA 非常好用);
• 添加只读实例,自动读写分离;
• 优化 backlog;
• 添加读写分离实例数量。
最后
高并发口罩抢购项目架构演进记录&优化经验分享_第5张图片
ECS运维指南之Linux系统诊断
本文节选自《ECS运维指南之Linux系统诊断》,《ECS运维指南之Linux系统诊断》是牧原呕心沥血之作,不仅内容精益求精,代码的编排作者也花了不少心思。你也可以直接登录阿里云开发者社区下载本书——《ECS运维指南之Linux系统诊断》,或者直接在公众号后台回复关键字“ecs”获取本合集。
阿里云开发者社区有不少高质量技术文章,大家可以去观摩学习,有很多书籍都是可以直接免费下载的。

如果本文内容你觉得有所启发,有所收获,请帮忙点个“在看”呗,或者转发分享让更多的小伙伴看到。


这 10 行比较字符串相等的代码给我整懵了,不信你也来看看


工欲善其事,必先利其器 -- Mac 软件推荐(序)


一行代码引来的安全漏洞就让我们丢失了整个服务器的控制权


面试 Google, 我失败了 | Google 面经分享

欢迎关注,共同成长,共同进步!
高并发口罩抢购项目架构演进记录&优化经验分享_第6张图片
高并发口罩抢购项目架构演进记录&优化经验分享_第7张图片
高并发口罩抢购项目架构演进记录&优化经验分享_第8张图片

欢迎 扫码 加群
备注“内推”/“交流”
程序猿石头