云计算与虚拟化技术丛书

阿⾥云运维架构实践秘籍

驻云科技 乔锐杰 著

ISBN：978-7-111-64969-4

本书纸版由机械⼯业出版社于2020年出版，电⼦版由华章分社（北京

华章图⽂信息有限公司，北京奥维博世图书发⾏有限公司）全球范围

内制作与发⾏。

版权所有，侵权必究

客服热线：+ 86-10-68995265

客服信箱：service@bbbvip.com

官⽅⽹址：www.hzmedia.com.cn

新浪微博 @华章数媒

微信公众号 华章电⼦书（微信号：hzebook）

⽬录

推荐序

前⾔

绪⾔ 云计算带来的技术变⾰

第⼀篇 云端选型篇

第1章 云平台的选型

1.1 全球云⼚商占⽐

1.2 国内云⼚商的现状

1.2.1 阿⾥云

1.2.2 腾讯云

1.2.3 华为云

1.2.4 百度云

1.2.5 其他云⼚商

第2章 云产品的选型

2.1 阿⾥云产品概要

2.2 云产品的8/2选择原则

2.2.1 五个技术优势

2.2.2 两个⾮技术优势

2.2.3 选择⾃建环境的条件

第3章 软件技术选型

3.1 “宇宙最⽕”的语⾔

3.2 硬件的天下

3.3 “后台强⼤”的语⾔

3.4 “胶⽔语⾔”

3.5 “世界上最好”的语⾔

3.6 最适合⾼并发的语⾔

3.7 唯⼀的前后端语⾔

3.8 不可替代的机器语⾔

第4章 系统技术选型

4.1 云端⽹络的三种选型策略

4.1.1 策略⼀：⽹络类型选型的五个注意点

4.1.2 策略⼆：⼊⽹请求选型的四种⽅法

4.1.3 策略三：出⽹请求选型的三种⽅法

4.2 云端Web服务器的五点选型考虑

4.2.1 考虑⼀：稳定性

4.2.2 考虑⼆：性能

4.2.3 考虑三：对负载均衡功能的⽀持

4.2.4 考虑四：前端静态数据缓存

4.2.5 考虑五：丰富的插件及⽀持灵活的⼆次开发

4.3 云端负载均衡选型的五个⽅⾯

4.3.1 对⽐⽅⾯：四⼤热门负载均衡的优缺点

4.3.2 分类⽅⾯：五⼤类型负载均衡的原理场景详解

4.3.3 演变⽅⾯：负载均衡的两种演变

4.3.4 性能⽅⾯：负载均衡隐藏的性能秘密

4.3.5 选型⽅⾯：云端负载均衡的两种选型

4.4 云端存储的四种类型

4.4.1 类型⼀：块存储

4.4.2 类型⼆：共享块存储

4.4.3 类型三：共享⽂件存储

4.4.4 类型四：对象存储

4.5 云端缓存的两⼤选型秘籍

4.5.1 秘籍⼀：云端静态缓存唯⼀的选型

4.5.2 秘籍⼆：云端动态缓存唯⼀的选型

4.6 云端数据库选型的三个⽅⾯

4.6.1 分类⽅⾯：数据库的三⼤分类

4.6.2 性能⽅⾯：数据库的性能秘密

4.6.3 选型⽅⾯：云端数据库选型的两点考虑及⼀个步骤

第5章 配置选型

5.1 衡量业务量的指标

5.1.1 ⼀台Tomcat跑两亿PV的笑话

5.1.2 衡量业务量的指标

5.2 业务访问量与性能压⼒指标的转换

5.2.1 指标转换原理

5.2.2 性能指标转换计算模型实践

5.2.3 业务指标转换计算模型实践

5.3 云端服务器配置模型

5.3.1 PV量对应的服务器配置

5.3.2 服务器CPU/内存配置模型

5.4 云端带宽配置选型

5.4.1 带宽配置估算模型

5.4.2 带宽类型选择的8/2原则

第⼆篇 云端实践篇

第6章 云主机实践

6.1 云⽹络下的业务新架构

6.2 云的技术本质优势

6.2.1 云主机与硬件服务器性能对⽐的误区

6.2.2 云的本质优势在于分布式架构

6.3 云时代下的资源⾃动化管理

第7章 云端负载均衡实践

7.1 “1+1>2”经典架构

7.2 单机+SLB架构的必要性

7.3 被LBHA误导的架构

7.4 DNS的两⼤主流实践

7.4.1 实践⼀：不推荐DNS作为负载均衡的误区

7.4.2 实践⼆：DNS不为⼈知的核⼼秘密功能

7.5 企业级Web架构实践

7.6 企业级负载均衡架构实践

7.6.1 七层SLB性能实践案例

7.6.2 互联⽹企业负载均衡架构实践

7.6.3 云端负载均衡中⼩型架构实践

7.6.4 云端负载均衡中⼤型架构实践

7.7 通过代理+VPN提速跨国际⽹络访问

7.7.1 跨国际⽹络访问的延时问题

7.7.2 解决跨国际⽹络访问的代理架构

7.8 通过反向代理提速跨国际⽹站访问

7.8.1 ⽅案⼀：双域名反向代理架构⽅案

7.8.2 ⽅案⼆：单域名反向代理架构⽅案

第8章 云端存储实践

8.1 云端块存储⼋⼤实践技巧

8.1.1 提升云盘I/O的三⼤技巧

8.1.2 云盘使⽤的五⼤技巧

8.2 云端共享⽂件存储的五种⽅法

8.2.1 ⽅法⼀：Rsync⽂件共享实践

8.2.2 ⽅法⼆：Rsync+Inotify⽂件共享实践

8.2.3 ⽅法三：NFS⽂件共享实践

8.2.4 ⽅法四：NAS⽂件共享实践

8.2.5 ⽅法五：OSS⽂件共享实践

8.3 OSS⽂件管理的六⼤技巧

8.3.1 技巧⼀：使⽤API接⼜/SDK管理OSS

8.3.2 技巧⼆：使⽤阿⾥云管理控制台管理OSS

8.3.3 技巧三：使⽤图形化⼯具管理OSS

8.3.4 技巧四：使⽤本地⽂件系统挂载管理OSS

8.3.5 技巧五：使⽤FTP管理OSS

8.3.6 技巧六：使⽤命令⾏⼯具管理OSS

8.4 四招搞定OSS数据迁移

8.4.1 第⼀招：OSSImport⼯具

8.4.2 第⼆招：OSS在线迁移服务

8.4.3 第三招：跨区域复制

8.4.4 第四招：OSS离线迁移

8.5 运维容灾备份新篇章

第9章 云端缓存实践

9.1 使⽤静态缓存提升⽹站性能的四种⽅法

9.1.1 ⽅法⼀：浏览器缓存

9.1.2 ⽅法⼆：磁盘缓存

9.1.3 ⽅法三：内存缓存

9.1.4 ⽅法四：CDN（动静分离）

9.2 动态缓存的三种应⽤场景实践

9.2.1 场景⼀：数据库缓存

9.2.2 场景⼆：集中Session管理的六种策略

9.2.3 场景三：四招搞定动态页⾯缓存

第10章 云端数据库实践

10.1 垂直拆库三⼤应⽤场景实践

10.1.1 场景⼀：垂直拆库的应⽤实践

10.1.2 场景⼆：主从的四种实践⽅案

10.1.3 场景三：集群技术的应⽤实践

10.2 ⽔平拆表三⼤应⽤场景实践

10.2.1 场景⼀：业务层⽔平分区拆表的三种⽅式

10.2.2 场景⼆：数据库层次⽔平分区拆表的⽅法

10.2.3 场景三：四⼤成熟分布式Sharding技术⽅案

第11章 云端运维实践

11.1 上云迁移的实践

11.1.1 上云的诉求

11.1.2 前期技术调研

11.1.3 三⼤运维痛点

11.1.4 上云迁移的挑战性

11.1.5 七步搞定上云迁移

11.1.6 上云前后的对⽐

11.2 混合云⼋⼤运维架构实践

11.2.1 混合云实践1：基于VPC+专线构建混合云架构

11.2.2 混合云实践2：RDS⾃建主从同步在混合云中的实践

11.2.3 混合云实践3：MongoDB副本集在混合云中的实践

11.2.4 混合云实践4：RabbitMQ+SLB⾼可⽤实践

11.2.5 混合云实践5：云端⾃建DNS实践

11.2.6 混合云实践6：Redis主从+Sentinel+Consul+DNSmasq⾼

可⽤实践

11.2.7 混合云实践7：MySQL主从+Consul+DNSmasq⾼可⽤实

践

11.2.8 混合云实践8：关于DNS的⾼可⽤

11.3 云端运维架构五⼤优化

11.3.1 优化⼀：云端配置选型

11.3.2 优化⼆：云端⽹络架构

11.3.3 优化三：云端负载均衡的选择

11.3.4 优化四：云端静态资源访问

11.3.5 优化五：云端运维管理

第12章 云端监控实践

12.1 物理机体系：三⼤监控⽅案实践

12.1.1 监控⽅案⼀：Shell/Python

12.1.2 监控⽅案⼆：Nagios

12.1.3 监控⽅案三：Nagios+Cacti

12.2 云计算体系：四⼤监控⽅案实践

12.2.1 监控⽅案四：Zabbix

12.2.2 监控⽅案五：云监控

12.2.3 监控⽅案六：驻云监控1.0（集群监控）

12.2.4 监控⽅案七：驻云监控2.0（⾃动化监控）

12.3 容器体系：四⼤监控⽅案实践

12.3.1 监控⽅案⼋：Prometheus+Alertmanager+Grafana

12.3.2 监控⽅案九：TICK技术栈

12.3.3 监控⽅案⼗：驻云监控3.0（容器体系监控）

12.3.4 监控⽅案⼗⼀：驻云监控3.1（智能监控）

第13章 云端容器/DevOps实践

13.1 云端容器技术的⼗⼆⼤实践

13.1.1 容器实践1：关于云端容器资源编排技术的选择

13.1.2 容器实践2：结合K8S的DevOps流程

13.1.3 容器实践3：关于K8S集群的配置

13.1.4 容器实践4：K8S云端部署架构

13.1.5 容器实践5：K8S插件之DNS

13.1.6 容器实践6：容器的Web管理控制台

13.1.7 容器实践7：K8S业务应⽤+⾃建DNS实践

13.1.8 容器实践8：K8S Master节点⾼可⽤

13.1.9 容器实践9：K8S Node节点⾼可⽤

13.1.10 容器实践10：K8S部署架构优化

13.1.11 容器实践11：⾃建K8S迁移阿⾥云K8S托管版+Rancher

13.1.12 容器实践12：K8S监控实践

13.2 DevOps发展的四个阶段

13.2.1 ⼈⼯阶段

13.2.2 脚本及⼯具阶段

13.2.3 平台化阶段

13.2.4 智能化阶段

第三篇 云端安全篇

第14章 云端安全⾯临的挑战和机遇

14.1 云端安全问题的现状

14.2 云端安全⾯临的三⼤挑战

14.2.1 挑战⼀：安全⾏业状态不容乐观

14.2.2 挑战⼆：云端安全环境复杂化的挑战

14.2.3 挑战三：安全对云优势的冲击

14.3 云端安全带来的两⼤机遇

14.3.1 机遇⼀：云计算、⼤数据将成为安全体系的基础核⼼保

障

14.3.2 机遇⼆：政策驱动叠加，使得⾏业将迎来爆发

第15章 云端⿊客常见攻击

15.1 什么是⿊客

15.2 ⿊客⼊侵的途径：漏洞

15.3 ⿊客⼊侵流程

15.4 ⿊客常见系统层攻击

15.5 ⿊客常见应⽤层攻击

15.6 ⿊客常见⽹络层攻击

第16章 云端安全最佳防御⽅案

16.1 云端常见⿊客攻击的防御

16.1.1 四款热门的云端安全产品

16.1.2 安骑⼠、WAF、态势感知三⼤使⽤误区

16.1.3 DDoS和WAF三⼤实践技巧

16.2 云端安全架构四⼤策略实践

16.2.1 策略⼀：云平台架构模式选择

16.2.2 策略⼆：分布式架构是安全保障的基⽯

16.2.3 策略三：全⾯开启云产品的安全机制

16.2.4 策略四：基于VPC的企业级安全架构

16.3 云端运维安全实践⼗则

16.3.1 第⼀则：云端堡垒机的三种实践

16.3.2 第⼆则：运维⽤户管理

16.3.3 第三则：密码安全管理

16.3.4 第四则：防⽕墙安全管理

16.3.5 第五则：端⼜安全管理

16.3.6 第六则：云端开源WAF实践

16.3.7 第七则：云端数据安全传输的标准

16.3.8 第⼋则：运维安全性能调优的三种⽅法

16.3.9 第九则：通过冷备及热备进⼀步保障云端数据安全性

16.3.10 第⼗则：加强安全巡检及安全培训管理

16.4 云端防御综合案例总结

第四篇 云端架构篇

第17章 云端千万级架构的演变

17.1 架构原始阶段：万能的单机

17.2 架构基础阶段：物理分离Web和数据库

17.3 架构动静分离阶段：静态缓存+对象存储

17.4 架构分布式阶段：负载均衡

17.5 架构数据缓存阶段：数据库缓存

17.6 架构扩展阶段：垂直扩展

17.7 架构分布式+⼤数据阶段：⽔平扩展

第18章 云端架构的应⽤

18.1 云端电商架构应⽤

18.1.1 业务特点：活动

18.1.2 业务特点：商品图⽚

18.2 云端游戏架构应⽤

18.3 云端移动社交架构应⽤

18.4 云端⾦融架构应⽤

推荐序

中国最早的云计算⼚商阿⾥云于2009年成⽴，⾄今，云计算在中

国⼤地上已经⾛过10多个年头，它作为互联⽹的基础设施，也已经在

不知不觉中⾮常深刻地影响着整个社会、整个世界，并且这种影响还

在不断发酵。上云这个词在2013年和2014年可能还是新鲜词汇，但今

天还没有使⽤云计算的企业反⽽更像是稀有品种。

云计算正在并且已经慢慢地重构了整个IT的基础架构，这个过程

会持续加速，使其逐步发展成中国IT的基⽯。我以及上海驻云科技的

各位同仁在2013年就参与到云计算业务中，作为上述整个过程的参与

者和见证者，发现新的技术、云的技术、云背后的互联⽹技术将成为

未来每⼀个互联⽹技术从业⼈员不可或缺的基础能⼒，⽽对企业来

说，未来没有掌握这种能⼒的技术型员⼯是⾮常可怕的，这种IT、⼤

数据甚⾄⼈⼯智能技术的运⽤能⼒可能会彻底改变你现在所处的⾏

业。

作为互联⽹的参与者，尤其是技术参与者，⽆论是系统架构师、

开发⼯程师、运维⼯程师，掌握云计算及相应的技术产品知识，以及

利⽤云计算解决实际的业务问题都将变得必不可少。这个过程并不复

杂，但需要接受并拥抱云计算带来的改变。

乔锐杰作为中国最早的云计算⽅⾯的架构师和技术参与者，随着

驻云科技的成长和中国云计算的发展，逐步成为国内云计算⽅⾯的运

维专家，⾮常通晓以阿⾥云为主的中国主流云计算⼚商的相关产品及

技术。本书是其多年运维⼯作经验的汇总，⽤⾮常浅显的语⾔讲述了

如何成为⼀名云计算运维⾼⼿，是⼀本⾮常好的⼯具书，可供愿意学

习并使⽤云计算技术的读者参考。相信本书能够很好地帮助读者解决

使⽤云计算技术⼯作时遇到的各种问题。

驻云CEO，湖畔⼤学⼀期 蒋烁淼

2020年1⽉

前⾔

关于本书

随着云计算的到来，传统IT已经向DT变⾰。云计算具有低成本、

⾼稳定性、⾼效率、可灵活扩展等诸多优点，已经在逐渐淘汰传统

IDC的IT模式。未来，云计算将成为互联⽹的基础设施。

2012年，我机缘巧合接触到云计算这个领域，有幸⾛到了互联⽹

发展的前沿。更多时候，我觉得并不是我选择了云计算，⽽是云计算

选择了我。由于我对计算机颇感兴趣，从事过Java开发、系统运维、

系统架构等⼯作，又恰逢云计算浪潮来临，我个⼈的专业技能正好在

这个领域得以施展，所以说我是被云计算选中的。在云时代，当上架

⼀台服务器就像在淘宝上购物⼀样⽅便，当做环境配置、软件部署就

像在⽹上选择产品型号⼀样快捷，也就是说当这⼀切⼯作都由云平台

替运维⼈员完成时，那运维⼈员还有什么价值呢？这也是云时代下传

统中⼩型企业不需要运维⼈员的根本原因——不再需要⼈⼒去做这些

基础⼯作。所以说DevOps是运维⾏业的未来之路。云计算只是⼀个开

始，不管是运维、开发还是架构等，未来你需要更多技能才能顺应互

联⽹发展的潮流。

在云计算领域，当前市⾯上关于运维架构技术实践⽅⾯的书籍⾮

常匮乏，⼤多数书籍的内容偏向云计算底层（IaaS）的基础架构，及

云计算的体系介绍。我在2013年看过《飞天开放平台编程指南》⼀

书，但它的篇幅有限，内容更偏向于API，于是我萌⽣写⼀本基于云

计算的、偏向实践的书籍的想法。我平时喜欢跟他⼈通过⽂章、沙

龙、会议等分享⾃⼰在云端技术⽅⾯的所见、所想，且我是计算机技

术出⾝，也⼀直追求开源的分享精神，这些都是我坚持写完本书的核

⼼动⼒。

2009年的阿⾥云，2011年的盛⼤云，2012年的电信天翼云，2013

年的腾讯云及华为云，2015年的百度云，国内的云计算市场可谓百花

齐放。鉴于阿⾥云的领先地位，加上我本⾝也⼀直基于阿⾥云从事云

端产品研发、云端迁移、云端运维、云端架构、云端安全、云端培训

等⽅⾯的⼯作，所以刚开始我准备以“阿⾥云：千万级系统的架构”为

重点凸显架构实践内容，但后来考虑到架构分软件层的系统架构和系

统运维层的分布式集群架构，⽽我的实践经验更偏向于后者，为了让

主题更加清晰，也为了发挥我的专业优势，最终将本书定位为“阿⾥云

运维架构实践秘籍”。

读者对象

本书的内容偏向于实践经验，不太适合没技术基础的初学者，⽽

是适合在研发、运维、架构等⽅⾯具备⼀定经验的技术⼈员。

·开发⼈员：本书可帮助开发⼈员熟悉云端分布式集群架构的相关

技术，使其能够从宏观架构的⾓度研发代码，提升技术眼界和⾼度。

·运维⼈员：本书可帮助运维⼈员提升运维实践技能和知识⼴度、

⾼度，有助于其向⾼级运维、架构师晋升或转变。

·架构师：本书介绍了⼤量云端实践经验、实践案例及场景，对架

构师来说不可多得。

·技术管理者：本书介绍了⼤量云端技术架构、云端技术思维、云

端技术⽅向等⽅⾯的实践经验，在成本把控、技术⽅向把控/决策、技

术⼈员管理等⽅⾯是技术管理者的重要指导。

·关注和使⽤云计算的⽤户：同样，本书也适合对云计算实践技术

具有浓厚兴趣的爱好者，相信⼤量的案例、实践场景会让你有所受

益。

内容简介

本书共18章，介绍云端运维架构最佳实践的⼗⼋招绝技，所以我

也喜欢把本书称为云端实践秘籍——“降云⼗⼋掌”。本书是我历时⼋

年的云端技术实践，总结了五千余家⼀线互联⽹企业实践⼲货及经

验。技术⾯覆盖⼆⼗余款热门云产品实践、五⼗余种常见开源热门技

术实践，并包含百余种云端架构技术的实践技巧和⽅法、千余项案例

实践经验，以及云端混合云、云端容器、云端监控演变、云端⾃动化

运维、云端DevOps、云端智能化运维、云端安全、云端分布式架构⼋

⼤技术架构实践。

本书内容最初规划时分为五篇：云端选型篇、云端实践篇、云端

安全篇、云端架构篇、云端运维篇。由于内容太多，最后决定将云端

运维篇的相关内容放在我的下⼀本书中进⾏详细介绍。本书基本结构

如下。

云端选型篇（第1～5章）

云端选型篇介绍了在云端选择什么样的云平台做战略规划部署及

业务体系建设，选择什么样的云产品来架构及规划业务，选择什么样

的开发语⾔来应对业务开发需求，选择什么样的系统技术来搭建运维

架构及实施，以及选择什么样的配置来部署业务及做容量规划等。

第1章讲述部署业务服务时选择什么样的云平台落地，即选择哪个

云⼚商落地。由于不同云⼚商的公司实⼒、业务背景、技术团队实⼒

等不同，所以不同云⼚商的业务⽅向、平台稳定性、平台安全性、平

台服务质量、产品功能及价格等都有所不同。因此云平台的选择，决

定了业务的体系建设及战略规划部署⽅向。

第2章讲述在对应的云平台上选择什么样的云产品进⾏业务的部署

及规划，云产品的8/2选择原则教我们在⾯对云平台两三百款眼花缭乱

的产品时，如何选择对应的产品，选择的重点是什么，以及要注意些

什么。

第3章讲述当下云端最⽕热的编程语⾔，由于云平台的特性决定了

云适合分布式应⽤，所以在云端使⽤较多的还是Java、C#等具有Web

框架的语⾔，以及PHP、Python所代表的脚本语⾔。

第4章是本篇的重点，其核⼼内容包含云端⽹络、云端Web服务

器、云端负载均衡、云端存储、云端缓存、云端数据库五个⼤类，基

本覆盖云端千万级运维架构常见的运维技术。通过学习该章内容，你

将了解及熟悉在云端运维架构中应该选择什么样的运维技术。

第5章介绍在云端选择什么样的服务器配置来部署业务及做容量规

划，该章通过实践案例做经验性的梳理及总结，有效解决了企业应⽤

中普遍存在的服务器配置偏⾼、资源使⽤率偏低等常见问题。

云端实践篇（第6～13章）

云端实践篇是基于云端选型篇，对云端运维架构涉及的相关技术

的重要实践，也是本书的重点篇幅，包含云主机、云端负载均衡、云

端存储、云端缓存、云端数据库等云端最⽕热的技术的实践，并且结

合上云迁移、混合云及容器、云端运维实践这三类云端最常见的热门

需求，结合真实客户案例，向⼤家分享当前最热门、最流⾏的混合云

技术架构、云端容器技术架构、云端监控演变及技术实践、云端⾃动

化运维技术实践、云端DevOps技术实践等。

第6章基于云端最核⼼产品ECS的特性，讲述云⽹络下的业务新架

构、云的分布式架构、云的资源⾃动化管理等云的技术优势、特点及

其实践。

第7章是本篇的经典内容，介绍在传统开源负载均衡的经验基础

上，结合云平台下负载均衡的最佳实践经验、负载均衡作为分布式架

构及⾼可⽤架构的核⼼技术，以及企业级的应⽤场景及案例。

第8章讲述块存储（云盘）、共享⽂件存储、OSS对象存储这三⼤

云端⾮结构化数据存储的实践技巧及⽅法。

第9章讲述以Nginx、Varnish、Squid等为主的静态缓存技术、如何

提升Web应⽤的静态资源（如HTML、JS、CSS、图⽚、⾳视频等静态

⽂件）的访问速度，以及以Memcache、Redis等为主的动态缓存技术

在数据库缓存、集中Session管理、动态页⾯缓存这三⼤场景中的应

⽤。

第10章从数据库的垂直拆库及⽔平拆表两个维度，讲述所涉及的

垂直拆库、⽔平拆表的应⽤场景实践，以及所涉及的主从、集群、分

布式Sharding三⼤数据库架构技术实践。

第11章通过三个真实客户案例，讲述上云迁移、混合云架构、云

端运维架构优化这三类云端最常见的热门运维需求的技术实践。

第12章讲述物理机体系、云计算体系、容器体系这三⼤IT架构体

系所对应的系统架构的演变过程，通过Nagios、Zabbix、云监控、

Prometheus、TICK技术栈等⼗⼀⼤监控⽅案，介绍互联⽹监控技术的

发展及演变过程，⽅案所涉及的技术也⼏乎覆盖了当今互联⽹最热门

的监控技术。

第13章通过真实客户案例讲述云端容器⼗⼆⼤技术实践，更是通

过DevOps发展的四个阶段，即⼈⼯阶段、脚本及⼯具阶段、平台化阶

段、智能化阶段，分析了云端容器、云端⾃动化运维、云端DevOps这

三者之间的区别与联系。

云端安全篇（第14～16章）

随着云计算的发展，云端⾯临着挑战也⾯临着机遇。如何通过技

术⼿段保障云端业务的安全性是本篇的核⼼内容。通过常见攻击案

例，结合云端最佳安全防御⽅案，本篇将带你⼀起⾛进⿊客攻防的世

界。

第14章通过分析云端安全问题现状，讲述安全⾏业⾯临的⾏业状

态不容乐观、云端安全环境复杂化、安全对云优势有剧烈冲击这三⼤

挑战，及其带来的云计算和⼤数据将成为安全体系基础核⼼保障、政

策驱动叠加使得⾏业将迎来爆发这两⼤机遇。

第15章通过介绍什么是⿊客、⿊客⼊侵的途径、⿊客⼊侵流程

等，带⼤家了解⿊客的真实定义及⿊客⽇常攻击流程，提醒⽤户注意

保护个⼈⽹络安全。

第16章从云端安全产品、云端安全架构、云端安全运维这三个⽅

⾯，结合⼤量云端⽤户遇到的安全问题及场景，跟⼤家分享云端安全

最佳防御实践经验。

云端架构篇（第17～18章）

在云端如何构建千万级架构，本篇主要结合前⾯的云端选型篇、

云端实践篇、云端安全篇中相应的阿⾥云最佳实践经验，向⼤家分享

⼀个⼩型⽹站如何逐步演变到千万级架构的过程。另外，结合云端热

门的、不同的互联⽹业务的特点，介绍设计架构时要如何考量，以及

有哪些秘密和诀窍。

第17章讲述⼀个应⽤如何从架构原始阶段（即万能的单机）、架

构基础阶段（即物理分离Web和数据库）、架构动静分离阶段（即静

态缓存+对象存储）、架构分布式阶段（即负载均衡）、架构数据缓

存阶段（即数据库缓存）、架构扩展阶段（即垂直扩展）演变发展到

架构分布式+⼤数据阶段（即⽔平扩展）。

第18章通过电商、游戏、移动社交、⾦融四⼤热门应⽤的业务特

点，讲述在云端架构设计中需要注意的技术重点。

勘误和⽀持

由于作者⽔平有限，且时间仓促，书中难免存在疏漏，恳请读者

朋友批评指正。如果你有更多宝贵意见，欢迎发送邮件⾄qiaobangzhu-

cn@qq.com，期待您的⽀持与反馈。

致谢

本书写作历时两年，感谢公司对我的⼤⼒⽀持，这也是我坚持写

完本书的最⼤动⼒。

感谢机械⼯业出版社华章公司的杨绣国编辑，我们相识5年，她的

⽀持、⿎励和帮助，是我顺利完成写作的不竭动⼒。

感谢蒋宁在本书的内容上提出的⼤量宝贵专业建议，感谢陈婵在

本书的运营宣传上提供的⼤量宝贵建议，感谢徐伟琴对本书所⽤的两

百余张图⽚所进⾏的专业设计。

谨以此书献给我最亲爱的家⼈，以及宋帅、⽏佳龙等⽀持我的朋

友们。

乔锐杰

上海驻云科技，2020年1⽉

绪⾔ 云计算带来的技术变⾰

传统IT正在向DT变⾰。未来，云计算将成为互联⽹的基础设施。

作为技术过来⼈，我亲历了中国互联⽹时代的发展、云计算云时代的

发展，以及技术⼈员眼中云计算所带来的技术变⾰。

⼀、中国互联⽹时代

“Across the Great Wall we can reach every corner in the world”（越过

长城，⾛向世界）是1987年9⽉20⽇从北京向海外发出的中国第⼀封电

⼦邮件。这也预⽰着，互联⽹时代悄然叩响了中国的⼤门。

1994年4⽉20⽇，中关村地区教育与科研⽰范⽹络（NCFC）通过

美国Sprint公司接⼊国际互联⽹（Internet）的64K国际专线开通，标志

着我国正式全功能接⼊国际互联⽹，这⼀年也是中国开启互联⽹时代

的元年。

1.中国互联⽹起点

1994年4⽉20⽇中国实现了与国际互联⽹的全功能连接，但是直到

1998年，我国的门户⽹站才兴起，中国真正意义上正式进⼊⽹络时

代，这也是真正意义上的中国互联⽹的起点。

中国互联⽹巨头也⼤多于1998年左右成⽴：

·⽹易：1997年6⽉；

·搜狐：1998年；

·腾讯：1998年11⽉；

·新浪：1998年12⽉；

·阿⾥：1999年；

·盛⼤：1999年11⽉；

·百度：2000年。

2.IDC/数据中⼼的硬件时代

2002～2012这10年期间，中国互联⽹得到了长⾜的发展。电⼦商

务、传统互联⽹等都是这个时代的产物。这⼀时期是IDC/数据中⼼的

硬件天下。

运维⼈员在⽇常⼯作中，⼀半精⼒花在跟硬件打交道、跟IDC机房

打交道。“IOE”是这个时代的经典组合：服务器提供商IBM、数据库软

件提供商Oracle、存储设备提供商EMC。

3.云时代

从⼯业时代到电⽓时代，再到信息⽹络时代，随着科技的发展，

云时代是⼈类科技进步的阶段性时代。就如同云时代的下⼀个时代是

⼈⼯智能，⼈⼯智能是不是⼈类科技的终点，答案还需探索。

2005年，Amozon宣布AWS（Amazon Web Service）云计算平台成

⽴，这是全球云计算落地的起点。2009年，阿⾥云成⽴，这是中国互

联⽹云计算的起点。随着这⼏年云计算从概念期转⼊落地期，云计算

低成本、⾼稳定性、⾼效率、可灵活扩展等诸多优点所带来的红利让

千千万万企业受益。从这⼏年国内⼏家知名云计算公司的成⽴，也可

以看到中国云计算发展的时间年轮：

·2009年，阿⾥云；

·2011年，盛⼤云；

·2012年，天翼云；

·2013年，腾讯云、华为云；

·2015年，百度云。

⼆、什么是云计算

从技术⾓度来看，云计算并不是⼀种新技术，它也⽤到了编程语

⾔排⾏榜上的那些编程语⾔，以及数据库排⾏榜上的那些数据库，还

有那些热门的开源技术。只不过它在虚拟化+分布式+⾃动化平台的基

础上解决了以下问题：

·稳定性：采⽤分布式集群部署，保障服务不宕机。

·弹性扩展：按需索取，⼀键式秒级开通资源。

·安全性：采⽤分布式多副本冗余部署，保障数据不丢失。

·成本：⼀台2核4GB服务器附赠5GB抗DDoS攻击流量，费⽤极

低。

·易⽤性：Web管理控制台，智能化便捷操作。

不同的是，云计算是⼀种新的互联⽹模式，这种模式本质上如同

IDC的IT模式。传统计算资源的使⽤流程是采购→机器安装配→机器上

架→机器后期机房托管。⽽在云端，在Web界⾯简易的⼀键式操作就能

获取计算资源。就如同使⽤⽔和电⼀样⽅便，按需索取。

三、云平台优化点

从本质上来讲，云计算只是⼀个概念，如同LDAP协议。⽽阿⾥

云、腾讯云、华为云就是云计算的落地实现，如同开源⼯具OpenLDAP

对LDAP协议的实现。云计算是⾯向⼴⼤⽤户的，对应的是⼀个分布式

云管控平台（简称云平台），⽤户可以在这个云平台上管理及使⽤对

应的云资源。众所周知，云平台具有稳定性、可弹性扩展、安全性、

低成本、易⽤性等优点。那云平台有缺点吗？答案也是肯定的。

正如前⾯所说的，从技术⾓度来看，云平台只不过是虚拟化+分布

式+⾃动化的⼀个综合类平台，所以很多相对于传统物理硬件来说⽐较

烦琐的事情，都可以在云平台上⼀键⾃动化。正是因为它将传统上很

多重复的安装配置、调优、管理维护进⾏产品平台化，才带来了⼀键

式管理维护的⽅便性。平台化设计的⼀个前提就是产品封装性，封装

性带来了定制灵活性的问题。⽐如最开始SLB七层并不⽀持虚拟主机的

功能、RDS的MySQL不开放root权限、阿⾥云ECS不⽀持组播和⼴播。

产品封装性带来的定制灵活性的问题在传统物理机器上是不存在的，

所以这⼀点也是云平台的缺点。

云端产品封装性带来的灵活性的问题，可以在业务层、架构层、

运维层进⾏协调解决：

·⽐如，最开始对于SLB的虚拟主机的功能灵活性需求（此功能现

在SLB已具备），可直接在ECS上搭建Nginx来满⾜。

·⽐如，对于RDS的MySQL权限、参数修改等灵活性的需求，可以

直接在ECS上搭建MySQL来满⾜。

·⽐如，对于ECS组播和⼴播的功能、集群⾼可⽤的功能，如在

ECS上搭建Oracle RAC的功能，可以通过在ECS上安装N2N等VPN软件

来变通⽀持。当然变通做法会带来稳定性、性能等问题，这⾥暂不讨

论。

四、云计算对技术的变⾰

1.技术的发展变⾰

云计算的普及，也促使最新热门的开源技术的普及使⽤。因为⼤

家使⽤的⼤多数云产品都基于热门开源技术做了定制化开发及封装。

⽐如，负载均衡（Server Load Balancer，SLB），其中，四层就是基于

LVS（Linux Virtual Server，Linux虚拟服务器，它是⼀个虚拟的服务器

集群系统。本项⽬在1998年5⽉由章⽂嵩博⼠成⽴，是中国国内最早出

现的⾃由软件项⽬之⼀）、七层就是基于Tengine（Tengine是由淘宝⽹

发起的Web服务器项⽬，它在Nginx基础上，针对有⼤访问量需求的⽹

站，添加了很多⾼级功能和特性）等做了对应定制化开发及优化。云

计算浪潮席卷着互联⽹，同时在技术更新迭代、实践上也引领着变

⾰。

（1）在技术更新迭代⽅⾯的变⾰

⼤多数运维⼈员都喜欢墨守成规。因为系统90%的事故都是由变更

导致的，所以我们担⼼新的技术、新的软件版本会影响系统稳定性，

觉得“最好的技术就是⾃⼰最熟悉的技术”，总是喜欢⽤同⼀版本的操

作系统、同⼀版本的中间件，哪怕其版本的更新迭代已经进⾏得如⽕

如荼。

⽽云计算的普及，促使我们尝试接触新的技术、新的版本、新的

特性。从某种程度上来讲，甚⾄是逼着我们去⽤这些新的技术、新的

版本、新的特性。⽐如，⼀⽅⾯，云计算已经成为必备IT基础设施，

另⼀⽅⾯，云平台基本上都会下架⼀些旧版本，就拿操作系统来说，

随着RedHat7的推出，云端很快进⾏了更新换代，你⽆法再选择⼀些旧

的软件版本。

（2）在技术的实践变⾰上

2012年、2013年，云计算在国内还处于概念期。那时候我作为阿

⾥云架构师更多的是给客户介绍这个概念，⽽如今，更多的是⽤户急

切地跑来咨询：如何⽤云来满⾜⾃⼰的业务需求，如何更好地使⽤云

的⼀些产品及服务。

⽽在⽇常的学习中，我看到很多书籍、技术⽂档等还在讲磁盘的

RAID、OpenStack，基于物理硬件的部署、调优等技术。这些技术已经

在被逐步淘汰，在云上，我们可能再也接触不到物理服务器。相关软

件的安装配置、调优、⾼可⽤等都会由云平台来完成。未来的技术⽅

向是我们如何更好地使⽤、实践这些云产品及云技术。

2.在运维技术⽅⾯的变⾰

在运维领域，运维⾃动化⼀直是运维技术最重要的体现，也是运

维的灵魂。运维⾃动化⼀般有以下⼏个阶段：

·⼈⼯阶段。⽇常运维全部靠⼈⼯来做。

·脚本及⼯具阶段。对于⽇常重复的事情，我们开始尝试⽤脚本、

⼯具来替代⼈⼯⽅式，以提升效率。

·平台化阶段。⽤平台界⾯智能化操作来完成⽇常运维命令或执⾏

脚本/⼯具，以进⼀步提升效率。

·智能化阶段。智能运维，如⾃动扩容、故障⾃愈等，进⼀步减少

⼈为参与，进⼀步提升运维效率。

从事运维⼯作这么多年，我发现⼤多数中⼩企业的⾃动化⽔平还

停留在脚本及⼯具阶段，运维全靠⼈⼯。⽐如很多企业做代码发布都

还是通过⼿动操作SCP、FTP的⽅式更新线上代码再重启服务，效率实

在低下。云平台本⾝就是⼀个⼤的⾃动化平台，随着云平台的普及，

我们的运维技术⽔平得到了极⼤的提⾼，让我们直接进⼊平台化的阶

段。通过这个⼤的⾃动化云平台，我们的运维效率及质量得到了质的

飞跃，我们可以将更多精⼒放在⾃⾝业务场景中。

3.在技术体系架构的变⾰

IT架构和技术架构的演变其实是相辅相成的。就⽐如每次微软有

新的操作系统推出，背后都隐藏着Intel CPU的升级换代；苹果⼿机每

次有新品发布，背后其实也都隐含着硬件的升级换代。产品业务越来

越复杂，就需要越来越好的硬件来⽀持。可以说，IT的体系发展⽀撑

着技术架构的演变。同时，技术架构的演变也推进着IT的体系发展。

IT体系会经过以下3个阶段：

1）物理机体系阶段。传统的IOE架构其实是物理机的典型代表。

想使⽤计算资源，就需要去购买对应的硬件。

2）云计算体系阶段。在传统硬件服务器的基础上，通过虚拟化及

分布式技术形成对应的云资源平台。对计算资源的使⽤，如同使⽤⽔

和电⼀样，在云资源平台上按需索取即可，⽽不⽤再和底层物理硬件

打交道。

3）容器体系阶段。我们既不⽤关注底层物理硬件，也不⽤关注⽤

的云平台是AWS还是阿⾥云，我们的业务都能⽆缝过渡及运⾏。我们

对计算资源的使⽤会脱离对硬件，甚⾄是对各个云平台的依赖。

相应地，对应的技术架构会经过以下4个阶段：

1）单机架构的阶段。IOE架构（IBM的⼩型机+Oracle+EMC存

储）是单机架构中的典型代表，都是⾼配性能的计算资源，在这个阶

段的架构，其业务基本上都是单机部署的。有时候数据库和业务代码

甚⾄部署在⼀台⾼配机器上，完全要靠单机的硬件性能来⽀持更多的

业务访问。

2）集群架构的阶段。集群架构其实是单机架构的演变。集群架构

的典型技术特点就是，⼀般采⽤虚拟VIP技术（如Keeplived、

Hearbeat）解决单点故障问题，让架构⾼可⽤，如图1所⽰。⽽值得注

意的是，在云端，对应的云产品底层都⽤集群架构来保障⾼可⽤。

图1 单机架构向集群架构演变

3）分布式架构阶段。分布式架构最重要的特点就是，不管是业务

代码还是数据库，都是通过多台服务器以分布式模式部署的。如果业

务压⼒增加，那么就增加对应的服务器资源。在云计算阶段，分布式

架构特别适⽤于云平台部署。这个架构对服务器单机的性能依赖不

⾼，主要通过⼤量的云资源进⾏分布式快速部署，来满⾜业务发展和

迭代需要。值得注意的是，分布式架构是集群架构的演变，很多⼈把

集群架构和分布式架构混为⼀谈，这是很⼤的认识误区。集群的虚拟

VIP技术只能将⼀台服务器作为热备（Backup），并且只有在主服务器

故障的时候，才会切换到热备上，平时其都是处于空闲状态。⽽分布

式架构的技术特点就是，负载均衡的引⼊，让不同服务器同时应对业

务压⼒，⽽如图2所⽰。

图2 集群架构向分布式架构演变

4）微服务架构阶段。微服务架构本质上也是分布式架构，微服务

其实是业务功能层⾯的⼀种切分，即切分成单个⼩型的独⽴业务功

能。多个微服务通过API⽹关（Gateway）提供统⼀服务⼊⼜，对前台

透明，⽽每个微服务也可以通过分布式架构进⾏部署，如图3所⽰。这

给研发灵活性、业务后期迭代带来了极⼤的可扩展性，这是未来软件

技术架构的主流。微服务在云平台的基础上结合Docker容器技术进⾏

部署，能让业务、运维、架构在技术和⾮技术⽅⾯的稳定性、成本、

效率、可扩展性等都达到最优。

图3 分布式架构向微服务架构演变

第⼀篇 云端选型篇

·第1章 云平台的选型

·第2章 云产品的选型

·第3章 软件技术选型

·第4章 系统技术选型

·第5章 配置选型

在2013年我在担任阿⾥云架构师⼀职时，向客户介绍的更多的是

云概念⽅⾯的内容，⽽不是云技术⽅⾯的解决⽅案。⽐如不停地告知

客户云计算在便捷性、安全性，以及成本的节省等⽅⾯具有怎样的优

势。随着技术的发展，云计算已经从概念时期步⼊使⽤时期。现在，

⼈们越来越关注如何将企业级应⽤架设在云端、如何利⽤云计算快速

⽀撑业务的发展。未来，新零售、新制造、新⾦融、新技术、新能源

都将深刻影响中国，影响世界，⽽这⼀切，都会依托于云计算，云计

算将成为企业IT资源的必需品。可想⽽知，如果现在我们还保持IDC

硬件的固化思维，必将被互联⽹浪潮和云计算浪潮所淹没。

但是使⽤云计算是有门槛的，⽽且门槛还不低。截⾄2018年12

⽉，阿⾥云有两百款产品或服务。想要正确、⾼效地使⽤这些云端产

品及服务，可不是⼀件容易的事情，⽽且对技术专业性要求极⾼。那

么，在云端选择什么样的云平台做战略规划部署及业务体系建设、在

云端要选择什么样的产品来架构及规划业务？选择什么样的开发语⾔

来应对业务开发需求？又该选择什么样的系统技术来进⾏运维架构及

实施？或者通过什么样的配置来部署业务并做容量规划呢？这些便是

云端选型篇的重点内容。相信这些经验的总结，是你在云端技术选

型、云端运维架构规划上不可多得的参考内容。

第1章 云平台的选型

在云端部署业务服务的时候，⾸先要考虑的就是选择⼀个什么样

的云平台落地，即选择哪个云⼚商落地。这就跟我们选择⼿机⼀样，

会考虑是买苹果⼿机、华为⼿机，还是⼩⽶⼿机等。由于云⼚商的公

司实⼒、业务背景、技术团队实⼒等不同，导致不同云⼚商平台的业

务⽅向、平台稳定性、平台安全性、平台服务质量、产品功能及价格

等都有所不同。

本章主要根据编者多年积累的云计算领域的从业经验，来阐释国

内云⼚商平台的现状，从⽽为在云端进⾏运维架构部署提供技术参考

依据。

1.1 全球云⼚商占⽐

参考Gartner发布的2017～2018年全球IaaS报告，⼤家了解⼀下全球

云⼚商的占⽐情况（见表1-1）。我们可以看到排名前三甲的分别为：

亚马逊云、微软云、阿⾥云，2018年市场占⽐分别为30.4%、9.9%、

4.9%。⾕歌紧跟其后，占⽐2.6%。2018年国内云市场的竞争也逐步进

⼊⽩热化，2018年的全球云⼚商占⽐情况相⽐2017年应该没有太⼤变

化，前五的供应商排名基本没有变化。其中有3点⽐较明显的是：

1）亚马逊2018年的市场占有率为30.4%，依然占据⽆法动摇的主

导地位，相信业内⼈员对亚马逊在云计算领域的地位也是能感同⾝受

的。

2）阿⾥云在2018年的年增长率⾼达92.6%，在前三甲中持续保持

最⾼年增长率（亚马逊为26.8%，微软云为60.9%）。不管是在全球云

计算市场，还是在国内云计算市场，都能看到阿⾥云的增长趋势。想

当初，王坚博⼠创⽴了阿⾥云，在国内⾸例落地云计算。他甚⾄在阿

⾥内部也承受着诸多的不理解和不⽀持。好在王坚博⼠坚持、马云⽀

持，成就了如今的阿⾥云。从2009年⾄今，我们看到了阿⾥云的成

长，阿⾥云也逐步得到了⼤家及市场的认可。

3）腾讯云在2018年的表现⾮常强势及抢眼，128%的年增长率让其

排名狂升12位，⼀跃进⼊榜单前⼗，紧跟IBM其后，排名第六。腾讯

云在国内的发展要晚于阿⾥云，但能在国内稳定开拓市场，并能在国

际市场上有如此影响⼒，也算是真正意义上的后起之秀。

表1-1 2017～2018年全球排名前⼗云供应商 （单位：百万美元）

1.2 国内云⼚商的现状

前些年，云计算的概念⾮常⽕热，但是普通⼤众对云平台没有太

清晰的概念，所以有很多⼚商打着云计算的旗帜，对外提供的所谓的

云资源服务，其实说到底，就是⽤VMware等虚拟化技术虚拟出来的

VPS（Virtual Private Server，虚拟专有服务器）。从技术⾓度来看，云

主机是分布式的，所以在稳定性、资源隔离、数据安全性等⽅⾯都能

得到保障，⽽VPS是单机版。对于后者，由于虚拟母机的硬件（如

CPU、内存、硬盘、⽹卡）存在问题，可能会导致这台母机上的所有

虚拟机都遭殃，如由于机器硬盘存在问题，某所谓的云⼚商在换硬盘

时因操作不当造成了⽤户数据丢失。其实从这个案例可以看到，这就

是单点问题。因为分布式的云平台⼀般采⽤三份数据冗余，所以某台

物理机硬件有问题根本不会造成⽤户数据丢失。

随着这⼏年国内云计算的发展及普及，在国内繁杂的云市场中，

各个云⼚商的市场占⽐也逐步明朗化。图1-1所⽰的数据摘选⾃Synergy

Research Group的市场研究报告，供读者参考。

亚马逊云平台在国内落地及业务的开展并不顺利，所以在国内云

市场份额的占⽐中，阿⾥云⼀直占据主导的地位。不过，如果有国际

云资源的需求，亚马逊也是很好的选择。那不同的云⼚商之间除了市

场占⽐的不同外，其他⽅⾯还有什么不同呢？以下就国内⼏个相对知

名的云平台进⾏说明。

图1-1 2017 Q1～2018 Q4中国云基础设施服务市场份额

1.2.1 阿⾥云

正如阿⾥云的⼴告语“上云就上阿⾥云，市场占有率超过第2～5名

总和。”

阿⾥巴巴在电商领域拥有海量⽤户、海量数据、⾼访问量/⾼并发

的业务场景，也拥有⼀流的技术实⼒。

·2013年，阿⾥云获得全球⾸张云安全国际认证⾦牌，当时只有包

括HP的两家国外企业获得了云安全国际认证银牌。

·2014年，阿⾥云成功防御了全球互联⽹史上最⼤的DDoS攻击：

453G/s。

·2015年，阿⾥云千岛湖数据中⼼采⽤深层湖⽔⾃然制冷（普通技

术是电制冷），其节⽔率打破了Facebook全球数据中⼼的最低纪录，

成为世界第⼀，且⽐普通数据中⼼全年节约⽤电数千万度，减少碳排

放量⼀万多吨标煤，也是⽬前国内亚热带最节能的数据中⼼之⼀。

·2016年，CloudSort阿⾥云夺冠，性价⽐⾼出AWS保持的世界纪录

三倍，并且在以评测计算系统规模和效率为主的GraySort和MinuteSort

这两项重量级⽐赛中，打破了全部4项世界纪录。

国内众多云平台我也都使⽤过，阿⾥云在整体稳定性、安全性、

性价⽐、产品功能等⽅⾯的综合性能处于国内第⼀地位。特别是2014

年阿⾥巴巴收购了万⽹，致使阿⾥云拥有了⼀键便捷式的域名备案服

务。这⽅⾯的优势是国内其他云服务提供商甚⾄亚马逊都⽆法相媲美

的。

1.2.2 腾讯云

2017年3⽉，腾讯云⼀分钱竞标厦门政务云成功，⼀时间闹得沸沸

扬扬，其本质也是想抢占云市场份额。在国内云市场，除了阿⾥云

外，就当属腾讯云占⽐最多。腾讯云有⼀个特点，那就是游戏。相⽐

其他云平台，腾讯云部署游戏类业务会更具有优势。当然，不是说腾

讯云只适合部署游戏业务，跟阿⾥的淘宝电商业务⼀样，这只是腾讯

云的⼀个业务特点，因为游戏占据了腾讯业务的半壁江⼭。腾讯作为

游戏开发商，在游戏领域有着强⼤的渠道、丰富的经验。⽐如腾讯游

戏在运维领域累积的“蓝鲸”运维⾃动化平台，就⽆缝对接了腾讯云。

相⽐国内阿⾥云及其他云平台，这是腾讯云的优势和特点。

同样，相⽐阿⾥的淘宝、蚂蚁⾦服，腾讯在QQ、微信、游戏业务

⽅⾯也有着海量⽤户、海量数据、⾼访问量/⾼并发的业务场景，同样

也拥有强⼤的技术实⼒。只不过相⽐阿⾥云，腾讯云在云计算领域的

战略布局较晚。从“⼀分钱”中标的实践也能感受到腾讯云这⼏年⼀直

在云计算领域发⼒，2018年在市场上强有⼒的表现更是让⼈看到了腾

讯云的决⼼。

1.2.3 华为云

华为是全球领先的信息与通信解决⽅案供应商。华为的优势在于

通信硬件设备，以前中国移动⼤多都是⽤思科的通信设备，后来全部

换成华为的通信设备。华为相⽐BAT（百度、阿⾥、腾讯），在海量

数据、海量⽤户、⾼访问量/⾼并发的互联⽹业务场景中累积的技术经

验要弱⼀些。

所以，结合华为在通信硬件设备⽅⾯的优势，华为云的优势与特

点主要在于企业级私有化解决⽅案。在安全、⼤数据等云资源服务

上，相⽐阿⾥云、腾讯云，华为云还存在⼀定的差距。

1.2.4 百度云

百度的主要业务是搜索，相⽐阿⾥云、腾讯云在IaaS云服务领域

的⽐拼，百度云对此并没有过多的关注，在国内的战略布局也较晚。

⽽百度近些年⼀直专注于⼈⼯智能，⽐如在江苏卫视《最强⼤脑》栏

⽬中，百度机器⼈“⼩度”在⼈脸识别中战胜“⽔哥”王昱珩；⽽在2017

百度AI开发者⼤会上，百度创始⼈、董事长兼⾸席执⾏官李彦宏通过

视频直播了⼀段⾃⼰乘坐公司研发的⽆⼈驾驶汽车的情景，也展现了

百度在⼈⼯智能领域的技术优势。

所以，百度云的优势在于⼈⼯智能相关服务上，⽽在其他核⼼云

资源服务领域，相⽐阿⾥云、腾讯云则有明显不⾜。但从百度云官⽹

所⽰的产品类别中，相⽐其他云平台，可以看到百度云独有的⼈⼯智

能类别，⽽且提供的产品服务也很丰富，其中包括：

·Apollo仿真开放平台

·Apollo标定服务平台

·Apollo数据开放平台

·⽂字识别

·⼈脸识别

·图像审核

·图像识别

·语⾔处理基础技术

·理解与交互UNIT

·语⾳识别

·语⾳合成

·语⾳唤醒

·视频内容分析

·视频封⾯选图

·视频内容审核

·结构化数据抽取

·知识图谱Schema

·增强现实

·数据众包服务

1.2.5 其他云⼚商

2011年，盛⼤云对外提供服务，它在国内算是实施云计算较早的

云⼚商。但盛⼤⾃从“传奇”那款游戏爆⽕之后，由于战略布局后劲不

⾜，最终被腾讯反超，开始⾛下坡路。⽬前，盛⼤云已是强弩之末。

2012年，电信推出天翼云。其实电信在机房、硬件⽅⾯有着得天

独厚的优势，但由于种种原因，天翼云在国内云市场⼀直⽆所作为。

之后，Ucloud、青云也曾在国内云市场⼩有名⽓。相⽐阿⾥云、

腾讯云这样的⼤云⼚商，Ucloud、青云通过云产品功能细化以及服务

质量提升来吸引客户。其中，Ucloud服务包括如下⼏项：

1）在⼯单响应⽅⾯，Ucloud跟客户单独建⽴聊天群，⾥⾯有客

服、技术⼈员，所以客户的问题每次都能得到快速响应及解决。

2）Ucloud具有独有的服务器托管服务。⽽当时阿⾥云、腾讯云不

能提供这项业务。

3）拥有独有的产品功能服务。2015年5⽉，陌陌将游戏业务从

Ucloud迁移到阿⾥云，当时Ucloud就具备MongoDB产品服务了，但阿

⾥云还不具备MongoDB相应产品服务（⽬前已具备）。对此，阿⾥云

设计了⼀套MongoDB分⽚集群的解决⽅案。

以上对全球云⼚商及国内云⼚商的特点进⾏了介绍。在海外的业

务部署上，建议优先选择亚马逊。在国内互联⽹业务部署上，建议优

先选择阿⾥云。在私有云、私有化输出⽅⾯，建议尝试使⽤华为云，

毕竟华为是做硬件出⾝的。如若在游戏、运维等细分领域有更深的需

求，建议尝试使⽤腾讯云。若对云产品功能特性、存储或者其他细分

领域有需求，建议使⽤Ucloud、七⽜云等云⼚商的产品。这只是根据

不同云平台的特性⽽给出的笼统建议，⽐如当前阿⾥云在私有云、国

际化⽅⾯的输出⽇益成熟，选择阿⾥云进⾏部署也未尝不可。不同云

平台的技术特性代表不同的技术⽅案，最终选择哪家云⼚商还是取决

于业务需求。

第2章 云产品的选型

选好云平台后，接下来我们要考虑的是在这个云平台上选择什么

样的云产品进⾏业务部署及规划。可是在⾯对云平台上的两三百款产

品时，我们不免会眼花缭乱。如何选择对应的产品？选择的重点是什

么？我们又要注意哪些事项呢？希望本章的内容对你能有所启发。

2.1 阿⾥云产品概要

⽬前，阿⾥云官⽅有将近两百款产品（数据汇总于2019年3⽉，在

过去10年，阿⾥云共发布了162个产品，4610个新功能，⼏乎每天都有

产品新功能发布），如图2-1所⽰。

主要为以下7⼤类：

·⼈⼯智能

·云计算基础

·物联⽹

·⼤数据

·安全

·企业应⽤

·开发者服务

⾯对如此繁杂的云产品，暂且不说如何去选择使⽤，可能我们连

很多云产品是做什么的都不太清楚。通过这些年的云端实践，我们发

现80%～90%的云端⽤户主要在使⽤以下⼏类云端产品，这也是我们企

业级应⽤中必须要选择的5个云产品。

图2-1 阿⾥云产品概要

1）ECS（Elastic Compute Service）：云服务器

2）RDS（Relational Database Service）：关系型数据库

3）SLB（Server Load Balancer）：负载均衡

4）OSS（Object Storage Service）：对象存储服务

5）VPC（Virtual Private Cloud）：专有⽹络

事实上，以上5个云产品是有先后顺序排名的，⽽这个排名是通过

实践得到的。ECS、RDS、SLB、OSS这是阿⾥云4款打江⼭的核⼼产

品，简称“阿⾥云四⼤件”。ECS则是业务代码服务的载体，甚⾄基于

ECS我们可以⾃⾏搭建数据库、缓存、负载均衡等服务，ECS作为云产

品中的“基⽯”，是最基础最重要的云产品，排⾏第⼀⼀点也不为过。

不管企业级应⽤还是个⼈应⽤，98%的应⽤基本上都是动态业务，

很少见到⼀个只有⼀个静态html（当然也有这样的需求）的业务。这⾥

必然会涉及与数据库的交互，所以RDS紧跟在ECS后⾯，排名第⼆。

云的特性是分布式，传统IOE的单机应⽤很难展现云平台的优势，

⽽SLB是让业务⾛向分布式的关键和基础，所以SLB排名第三。即使是

单机业务，我们也有必要在单台ECS前⾯放个SLB作为代理转发。这样

做的优势很多，详细内容将在第7章中跟⼤家介绍。

OSS对象存储是类似于开源MFS、Ceph、GlusterFS、Lustre的分布

式⽂件系统。其实作为“阿⾥云四⼤件”之⼀，相⽐前⾯的3个云产品，

其通⽤性不那么强了。因为OSS的使⽤有个⼤门槛，就是需要通过API

对⽂件进⾏增删查改。当然有很多官⽅提供的软件开发⼯具包

SDK（⽐如Java、Python、GO、PHP等主流开发语⾔版本的OSS

SDK），以及OSS相关⼯具（⽐如8.3节提到的ossfs、ossutil等⼯具）降

低了OSS的使⽤门槛，⽐如，在Linux运维中可以通过“Crontab+OSS⼯

具”实现⽂件的异地备份，这种运维⽅式在很⼤程度上替代了传统“备

份服务器”的⾓⾊。当然OSS在图⽚、转码等领域甚⾄可以结合CDN来

使⽤，应⽤场景也较多。

VPC放在最后⼀位，是因为VPC是在“阿⾥云四⼤件”之后推出的⼀

款产品。SNAT、VPN、专线都是基于VPC的，现在在云端企业级应⽤

中，VPC基本上是默认的选择。但在实际应⽤中，⼀些⾦融客户还在

使⽤经典⽹络，这样⼀来，安全性、架构扩展性等⽅⾯就受限了。

当然，还有很多⼤家熟悉的云产品暂未放在使⽤率较⾼的系列

中，⽐如：

·CDN相关产品。之所以没有将CDN相关产品放在使⽤率较⾼的系

列中，是因为很多业务中静态图⽚等静态资源并不多，对CDN加速的

需求不明确。

·Memcache、Redis相关缓存产品。真正需要引⼊缓存时，侧⾯说

明企业业务是中⼤型的。在传统中⼩型企业应⽤中，业务代码⼤多就

跑⼏台Tomcat、PHP就⾏了。

·云盾相关安全类产品。随着⽹络安全法的推⾏，虽然未来企业对

安全性的要求及重视程度会越来越⾼，但是直到今天，⼤多数中⼩型

企业对安全性仍没有概念，导致重视程度还不够，这也是很多企业没

有使⽤云盾安全产品的主要原因。

2.2 云产品的8/2选择原则

在云端应⽤场景下，80%的企业（默认情况）会选择云产品，只

有20%的企业会考虑⾃⾏搭建对应服务。⽐如，有SLB，企业肯定不

会⾃⼰去搭建Nginx做负载均衡；再如，有RDS，企业也定不会⾃⼰去

搭建MySQL。

对于云产品的选择，有件事情让我印象深刻。⼀次去北京出差，

与同事⼀起拜访了⼀家公司。这家公司在云领域有⼗⼏台服务器，由

⼀位运维⼈员负责维护。该公司的数据库都是在ECS上搭建MySQL来

运⾏的，于是我问那位运维⼈员，“为什么不选择RDS？”那位运维⼈

员不假思索地说，“在ECS上搭建也挺⽅便的，为什么要⽤RDS？”听

到这个回答，我有点不⾼兴了，⽐较严肃且强势地说，“使⽤RDS就不

⽤你考虑安装配置、调优、备份、扩展等问题，拿来就⽤，为什么还

要⾃⼰去折腾搭建！”所以选择合适的云产品，相⽐⾃⾏搭建，有以下

技术⽅⾯及⾮技术⽅⾯的优势。

2.2.1 五个技术优势

1.安装配置⽅⾯

⼀些软件的编译安装，⽐如PHP，经常会有依赖包、版本兼容等

问题，其安装配置没有想象中那么简单。⽽对于云产品，我们不⽤再

去官⽹找安装包，也不⽤⾃⼰⼿动安装、配置，这⼀切云产品都默默

地替你做了。

2.调优⽅⾯

对于云产品，我们也不⽤关⼼⼀些性能参数要如何去优化，这⼀

切云产品也会默认替你实现。⽐如，MySQL的配置优化对细节、技

术、经验都有较⼤的挑战，如果你对其性能要求较⾼，只需要在管理

界⾯选择更⾼规格的配置型号，或者选择集群版本即可。

3.备份⽅⾯

在传统运维过程中，我们需要搭建主从、编写备份脚本以及操作

Binlog来进⾏对应的备份及恢复，这⽅⾯对运维⼈员来说都是较⼤的

挑战。但使⽤云产品时，我们也不⽤关⼼冷备、热备⽅⾯的问题了，

因为这⼀切云产品都默认帮你实现了，你只需要“傻⽠式”地操作即

可，哪⾥不会点哪⾥。

4.⾼可⽤⽅⾯

使⽤云产品，我们不⽤担⼼出现⾼可⽤⽅⾯的问题，也担⼼什么

时候挂了没办法提供服务。在ECS、SLB、RDS、OSS等阿⾥云产品

中，都是采⽤集群的⽅式部署对应的云产品，保证我们使⽤对应云产

品的⾼可⽤性。⽐如，ECS和OSS都是三副本的数据冗余，⽽RDS，

则是采⽤DNS+双Master架构来保障⾼可⽤性。除了开放给⽤户的⼀个

RDS库以外，还有⼀个隐藏的从库未开放给客户（举例：进⼊RDS

MySQL，通过“show slave status\G”可以看到隐藏的从库）。

5.安全性⽅⾯

对于安全性⽅⾯，使⽤云产品，不⽤关⼼软件版本的安全性问

题，也不⽤关⼼这个版本的软件有哪些补丁、漏洞要去修复，更不⽤

关⼼这个软件会被攻击的问题，这都是云产品默认会做到的。

2.2.2 两个⾮技术优势

1.责任⽅⾯

在⾮技术⽅⾯，云产品有⼀个很⼤的优势，即如果是⾃⼰搭建维

护的平台出了问题，那么对客户、对领导都要负责，对应的损失也得

⾃⼰承担；相反，如果使⽤云产品出现了对应问题（当然主要是云产

品稳定性、性能、安全性、⾼可⽤等本⾝问题，不包括因⽤户不会使

⽤及对应误操作等导致的问题），那么对应的损失甚⾄可以找云⼚商

进⾏索赔。

部分企业在⾯向客户服务的时候，想要⾃⼰招聘运维⼈员，⽽不

想找第三⽅服务公司，觉得不安全，怕数据被第三⽅公司窃取，或者

出现安全性问题。众所周知，企业招聘员⼯，本⾝在成本和管理上就

有很⼤的困难，这⾥先不谈这⽅⾯的挑战。换个⾓度，企业招聘员⼯

本⾝就是安全风险⾮常⾼的事情，⽐如，怎么保障这个员⼯不泄密？

其实很多企业的数据泄露，不是因为被⿊客窃取，⽽往往是因为公司

内部⼈员泄密。有时候，我们也会看到⼀些有意思的故事，⽐如“从删

库到跑路”。虽然⼤家把这些故事都当成笑话，但殊不知这都是真实的

案例。⽐如，⼀个运维⼈员因加班⽽失恋，之后格式化了所在公司的

所有服务器并离职。因此员⼯造成的问题，结果只能是企业⾃⼰扛。

若⾯对的是第三⽅专业团队，那么这些问题就可由第三⽅专业团队解

决，甚⾄向其索赔。

2.费⽤⽅⾯

当然，云产品责任⽅⾯的优势只是从特定的某个⽅⾯来说，具体

情况还得看业务需求和业务场景。在实际应⽤中，很多⽤户会觉得使

⽤云产品成本较⾼，不如⾃建平台。单纯使⽤⾼规格的云产品的费⽤

的确不低，但是深⼊了解后你会发现，想⾃⾏在ECS上搭建出和云产品

具备相同性能的环境，所采⽤的ECS台数和ECS配置的费⽤加起来也不

⽐使⽤云产品的费⽤低多少，如表2-1所⽰。

表2-1 RDS与⾃建MySQL配置的费⽤对⽐

这⾥有⼀个需要注意的地⽅，RDS的8核16GB配置只是⼀个规格配

置参考，并不代表我们⾃⼰ECS上部署的MySQL也要采⽤8核16GB配

置，这是个细节误区。RDS最主要的规格性能参数是：“最⼤连接数：

4000;IOPS：8000”。所以在实际部署中，要让数据库达到如此性能。

我们⼀般采⽤CPU和内存配⽐为1∶4的ECS配置（数据库偏向内存型应

⽤，具体实践参考第5章），如4核16GB、8核32GB、16核64GB。在上

述ECS的配置清单中，默认推荐选择8核32GB是为了保障⾃建数据库的

性能和稳定性。⽽且RDS的⾼可⽤版是双机⾼可⽤版，我们在ECS上⾃

建的MySQL是单机版，这⾥还需要再开⼀台做主从，以保障数据库数

据的安全性和⾼可⽤。这样⼀来，成本就进⼀步增加了。

2.2.3 选择⾃建环境的条件

那么，具体在什么场景下我们才需要⾃⼰搭建对应的服务呢？对

此主要从功能性和灵活性等⽅⾯来考虑，这也是⾃⾏搭建服务平台的

相对优势。阿⾥云的很多云产品，如SLB、RDS、CDN等，其核⼼都

是基于开源技术进⾏了封装并做了相应优化，然后形成对应的云产

品。相应的封装给我们带来了相应的优势（就是2.2.1节中描述的技术

⽅⾯的优势），但同时也给我们带来了相应的缺陷，⽐如，做了封

装，必然会使很多原⽣态的功能和特性存在⼀定的使⽤限制，下⾯我

们具体来看。

1.七层SLB的功能限制

何为七层负载均衡？更多地称之为反向代理，⼤家最为熟悉的就

是Nginx。何为七层反向代理/负载均衡？是因为它不只是能做七层转

发，⽽更多的是能在七层上做很多Rewrite的七层控制等。⽽早期的

SLB产品，连虚拟主机功能都不⽀持，只是可以简单地七层转发。当

然，当前SLB产品已经⽀持虚拟主机，具有七层代表性的核⼼功能。

如果想⽤Rewrite等更多七层功能，我们只能⾃⾏在ECS上搭建Nginx。

2.连接Redis，有密码鉴权

有些客户问这个密码鉴权能不能去掉，代码中采⽤了⼀个⽼的

Ruby框架，不⽀持这个鉴权，也没办法改代码。所以这时候我们只能

⽆奈地在ECS上⾃⼰搭建主从Redis，然后结合Console+DNS做⾼可

⽤。

3.RDS MySQL对Myisam存储引擎的⽀持

在⽤户的业务中，需要MySQL⽀持Myisam存储引擎。⽽RDS

MySQL版默认只⽀持Innodb的存储引擎，所以我们只能在ECS上搭建

MySQL来满⾜业务需求。

4.云数据库MongoDB对跨地域多副本冗余的⽀持

若客户对数据的安全性要求较⾼，并且云端和他们线下IDC做了

专线打通，他们需要将云端的MongoDB数据在线下IDC中做个副本，

当前云数据库MongoDB结合DTS还不⽀持此功能。所以我们在云端搭

建了两个副本，在IDC上同步⼀个副本，组成MongoDB的副本集。

综上可见，有些功能是云产品没办法⽀持的，且当前企业没办法

调整⾃⼰的业务架构及代码。这个时候基于灵活性和功能性⽅⾯的考

虑，只能选择在ECS上搭建相应的服务。

第3章 软件技术选型

在选择好对应的云⼚商和云产品后，在云端我们应该选择什么样

的软件技术（编程语⾔）来开展业务开发以及后期业务迭代呢？⽽又

是什么样的编程语⾔在云端最⽕、最时髦呢？希望本章能让你了解和

熟悉云端当前最⽕的编程语⾔。原则上，任何编程语⾔都能在云端环

境中运⾏。通过云端实践，⽤得⽐较多的还是Java、C#等具有Web框

架的语⾔，以及PHP、Python所代表的脚本语⾔，主要原因是，云平

台适合分布式应⽤，⽽这些热门的编程语⾔更加轻量化，⽅便分布式

处理。

3.1 “宇宙最⽕”的语⾔

其实在早些年，计算机刚进⼊中国时，互联⽹主要是以新浪、搜

狐和⽹易为主的门户⽹站。那时候在国内从事计算机⾏业的⼀批⼈，

其实都是“⾼材⽣”。我记得那时候监控⼯程师基本都是研究⽣学历。

但随着互联⽹的普及和发展，计算机岗位需求量呈爆发式增长，从事

IT相关⾏业的门槛越来越低，加上IT岗位的⼈才需求量巨⼤，且IT岗

位有稳定的收⼊来源，不少⼈都去参加IT相关培训，然后进⼊计算机

领域。

Java语⾔算是较早的编程语⾔，经过多年的发展，其在C/S领域和

B/S领域都占有⼀席之地。因为其语⾔的特性，适合做⼤型Web类系

统，特别是在银⾏、⾦融、电商等⾏业领域应⽤⼴泛。Java语⾔⼀直

在编程语⾔排⾏榜上独领风骚，但随着社会需求的变化和其他语⾔的

专注，Java的市场正在被⼀点点侵蚀。Web⽹站领域⼏乎被PHP⼀统天

下，C/S、嵌⼊式领域⼏乎被C/C++垄断。要不是安卓的出现，Java的

命运还真不容乐观。但不管如何，如今Java依然是全“宇宙最⽕”的语

⾔。

我当初选择学Java时，对这门语⾔还没有清晰的认知，仅仅只是

觉得Java难学，有挑战性，就想尝试，所以就选择从事Java开发。随

着技术的不断发展，也证明了我的选择是正确的。⼀⽅⾯，Java作为

应⽤场景⾮常多的⼀门后端语⾔，在Linux开源技术⽅⾯⾮常⽕热，这

能让其接触到最前沿的分布式架构技术。⽐如，Android刚出来的时候

特别⽕热，只要会⼀点Android知识，即使没什么经验的⼈，⽉⼯资也

能达到七⼋千元。这对刚毕业做开发的⼈来说，其实诱惑⼒是⾮常⼤

的。不过，我还是坚持做Java后端开发，其实原因也很简单，我觉得

Android是前端App开发技术，这对我本⾝的技术成长没有多⼤帮助，

加上我的兴趣点也不在前端。在技术领域，我更想要做的是分布式集

群架构，这也是很多前端⼯程师⼀直想要转后端的最主要的原因。另

⼀⽅⾯，Java作为⼀种纯⾯向对象的⾼级语⾔，掌握着Java核⼼编程

理念，后续若想转⾄PHP等其他编程语⾔，也是⼀件⾮常容易的事

情。但PHP⽤户想往Java开发⽅向转型，不是那么容易的⼀件事。

在云端实践中，⼏乎80%的Java应⽤都跑在Tomcat中。我们在云

端很少看见Jboss、Weblogic等重量级中间件（相⽐于Weblogic，在云

端还能偶尔看到有⽤户⽤Jboss部署相关业务），因为这些重量级中间

件对服务器的性能要求较⾼，所以⼀般适⽤于传统IOE那套⽼架构。

⽽云的优势在于分布式，所以在⼀台4核8GB的ECS上⾯跑⼀台轻量级

的Tomcat，效果⼗分完美。另外，结合当前最热门的微服务架构，

Spring Cloud是⼀套完整的微服务解决⽅案。在云端结合Docker的实

践，也是当前在云时代最流⾏、最⽕热的做法。

3.2 硬件的天下

在编程语⾔的排⾏榜中，⼀般Java、C、C++列居前三。与Java不

同的是，C/C++是底层语⾔，与硬件结合度⽐较⾼。可以⽤来进⾏⼀

些更贴近硬件的开发（主要是性能上），所以在ARM开发/智能家居/

物联⽹/智能硬件等嵌⼊式⾏业应⽤⼴泛。⽽C++相⽐于C，引⼊了类

的概念。我们知道，Java是⼀个纯⾯向对象的编程语⾔，在Java中，

⼀切皆对象（这与在Linux中“⼀切皆⽂件”的概念差不多）。⽽相⽐于

Java，C++不是完全⾯向对象，它保留了部分⾯向过程的东西。⽐

如“指针”这个概念在C++⾥依然强⼤。下⾯来看看C/C++的3个具体应

⽤场景。

·C语⾔最主要的使⽤领域应该是Unix系统开发以及某些Unix系统

软件的相关开发，所以常见的开源技术的源码，如Nginx，⼤多数都是

⽤C语⾔编写的。因此在云端实践中，更多的是下载常见开源的源码

包，使⽤Make编译及“Make Install”进⾏安装，这也是云端实践中做得

最多的事情。

·C语⾔在嵌⼊式开发中，依然居于“舍我其谁”的霸主地位，主要

是因为C语⾔跟底层硬件的结合度较⾼。在诺基亚王国⿍盛时期，也

是⼭寨机流⾏的年代，我曾在⽆锡⼀家从事⼿机增值服务业务开发的

公司做Java开发，但公司的研发主要还是基于C语⾔的，主要是基于

MTK平台做⼿机的嵌⼊式开发。我印象最深刻的就是，每次C语⾔开

发团队加班就是等代码编译。⼿机硬件端主要负责基于LBS/GPS的定

位功能，⽽Java后端平台端主要负责数据展⽰查看、数据管理⽅⾯的

功能（⼿机通过HTTP请求跟后端Java平台做数据同步交互）。后来随

着Android的崛起，进⼊了智能机时代，那家公司也⾯临转型的问题，

最终业务转型失败，湮没在历史的潮流中。另外，在互联⽹⾏业中，

对嵌⼊式⼯程师需求量最⼤的⼀家公司就是华为。华为技术有限公司

是⼀家⽣产销售通信设备的民营通信科技公司，对于华为交换机，搞

过运维的、对硬件有过接触的⼈基本都听说过，华为需要⼤量的嵌⼊

式研发⼈才来进⾏开发。

·MFC让C++跟Windows系统底层结合得特别紧密，所以C++在游

戏领域特别⽕。我们看到热门游戏的客户端，⼗之⼋九是⽤C++编写

的。或者Windows下的⼀些软件/⼯具，⼗之⼋九也是⽤C++编写的。

另外，⼤多数游戏外挂程序也都是利⽤MFC和C++开发的。以前我对

游戏外挂特别痴迷，很好奇具体是通过什么样的技术⼿段来实现的。

其实原理也很简单，主要是通过进程钩⼦的⽅式将DLL放进游戏进程

中去，修改游戏参数达到“外挂”的效果。

3.3 “后台强⼤”的语⾔

C#语⾔被描述成“后台强⼤”的语⾔，它和C++、Java⼀样是⾯向

对象的编程语⾔。C#能在编程语⾔排⾏榜排名前五，紧跟

Java/C/C++之后，很⼤⼀部分原因是C#是微软推出的，C#对Windows

的依赖性很⼤。凭借Windows占据了操作系统的绝⼤市场，硬是给C#

创造了良好的“⽣活环境”。很显然，如果脱离了Windows，就没有了

C#。

C#与C/C++不是同⼀层次的编程语⾔，C/C++更多偏向底层。C#

与Java是同⼀层次的编程语⾔，都是基于运⾏库⽀持的，分别是.NET

与Java虚拟机两⼤平台的代表性开发语⾔。其⽬的是实现⼀次编译即

可在任何系统上运⾏，C#编译代码只需要系统安装了相应的.NET运⾏

库，即.NET Framework，即可运⾏.NET程序。其⽣成的程序代码实际

上是中间代码，⽽不是像C或C++那样编译⽣成机器码。对于Java编译

代码，只要系统安装了Java虚拟机（Java的运⾏库）即可运⾏，这两

者是未来的主流，是应⽤级程序开发⼯具。⾄少在Windows下，C#依

然不可替代。

C#的应⽤场景跟C++有部分重叠，有很多⼈拿C#与C++做对⽐，

担⼼C++的未来命运。如果哪⼀天C#能拿来做驱动开发，那么C++也

许就真的会被淘汰。

C#傻⽠式的类库操作和⾯向对象编程的完美特性，确实让其成了

Windows平台上最受欢迎的编程语⾔。微软再通过种种FrameWork让

你陷⼊其中，你会觉得原来编程是这么容易的事情。所以C#在⼀些

Windows⼯具中应⽤很⼴，⽐如⿊客的SQL注⼊、DDoS攻击类软件⽅

⾯的⼴泛应⽤。我⽤过的12306订票助⼿（⼀款客户端订票⼯具）也是

⽤C#开发的，不需要安装，解压就能⽤起来。

3.4 “胶⽔语⾔”

“胶⽔语⾔”指的是⽤来连接软件组件的程序设计语⾔，通常指脚

本语⾔。何为“胶⽔”？就是这种语⾔能嵌套或者粘着其他编程语⾔⼀

起使⽤。它不仅能⾃⼰单独运⾏，其他开发语⾔还可以单独调⽤它。

哪⾥要⽤，就粘到哪⾥。⽽这其中，最著名的要属于Python语⾔了。

已经接触过Python的开发⼈员都了解“胶⽔语⾔”的巨⼤优势。Python

开发的程序⼯具可以很⽅便地嵌套到Java、C、PHP、C#等开发语⾔中

进⾏使⽤。⽐如以下案例：

1）Ossutil是基于OSS API的⼀款OSS⽂件操作⼯具，源码通过

Python实现，它可以实现对OSS⽂件的增、删、查、改等相应功能。

在Linux运维中，我们可以采⽤“Shell+Ossutil”⽅式来对OS层⾯的⽂

件、⽂件夹做异地备份。

2）再如⼤家熟知的Ansible这款⼯具，源码也是基于Python的。我

们可以通过Java来调⽤Ansible，以实现⾃动化的⼀些管理操作等。

Python也是⽹络攻防的第⼀⿊客语⾔，它正在成为编程⼊门教学

的第⼀语⾔以及云计算系统管理的第⼀语⾔。Python程序员最爱说的

⼀句话是：“⼈⽣苦短，我⽤Python。”这句话后⾯更多隐藏着Python

设计的哲学：“优雅、明确、简单”。Python是完全⾯向对象的，函

数、模块、数字、字符串都是对象，不像Java中还有基本类型。所以

前⾯说的⼀句话：Java中⼀切皆对象，相⽐于Python，Python更加适⽤

这句话。

Python的主要优势还是在于代码量⼩、维护成本低、编程效率

⾼。语⾔的特性决定了语⾔的应⽤场景，即同样⼀个需求，⽤不同语

⾔来实现，代码量相差很⼤。⼀般情况下，Python代码量是Java的

1/5。

在云端实践中，Python⼀般会运⽤到以下3种热门场景中。

1.DevOps

说到运维、⾃动化运维、DevOps，Python⼀直是热度最⾼的开发

语⾔。基本上Linux系统都会默认安装Python，加上Python在Linux OS

层⾯有丰富的库，这是运维实现⾃动化运维⽽替代⼈⼯运维的重要⼿

段。⽐如，通过Python实现备份、SSH登录、⽂件操作等，其实跟

Shell⼀样简单。Python直接导⼊对应的OS库，⽤简单⼏⾏代码就可搞

定。若想⽤Java来实现这些功能是很不容易的事，因为Java不擅长。

所以在⼀些⾃动化的运维平台中，我们优先选择使⽤Python。在⼀些

系统类的运维⼯具中（⽐如前⾯所说的Ossutil⼯具），我们也是优先

选择Python。

在从事云端运维的这⼏年，我⾯试过很多资深的运维。他们在职

业⽣涯发展到⼀定阶段、运维领域⽅⾯的技术已经学得差不多的时候

⼤多都会遇到同样的瓶颈，就是开发能⼒的缺失，导致其没办法在⾃

动化运维领域及技术领域做更多的事情，所以很多⼈希望有机会掌握

Python这种技术。但很多运维⼈员说⾃⼰熟悉Python，我却发现最多

也就是会使⽤Python写⼀些⽇常运维的基础脚本，如备份、安装配置

等。在我看来，这跟熟悉了Python语法，写⼀个“Hello World”没什么

两样。如果没有⽤Python写够⼏万⾏代码，我觉得还是停留在学习

Python语法的阶段。但这也是运维⼀直以来最⼤的痛点。在⽇常运维

场景下，没有更多需求、复杂场景能让我们写更多的Python代码了，

这是我们⼀直不具备研发能⼒的客观原因。所以想熟练掌握Python，

别⽆他法，只能从事相关的职位或进⾏相应的开发。

我当初学习Python，也是因为在DevOps⽅⾯有需求。我花费了⼀

个星期的时间学习Python的语法和特性，然后在OSS的客户端⼯具

（Windows中基于OSS的⼀个类似FTP的⼯具，能同步Windows⽂件⽬

录到OSS中）上⾯做⼆次开发，增加新的功能。通过这个项⽬，我熟

练掌握了Python语法、特性、多线程编程。后来，阿⾥云官⽅最初的

ECS CLI⼯具，也是我带着⼀个Python开发⼈员写出来的。业务场景的

需求、开发进度的压⼒促使我掌握了这门技术，⽽且越来越熟练。

2.⽹络爬⾍

⽹络爬⾍是Python擅长的强势领域。Python所具备的爬⾍框架

Scrapy、HTTP⼯具包urlib2、HTML解析⼯具Beautiful Soup，让其在爬

⾍⽅⾯⾮常⾼效、快捷。所以在数据分析、数据挖掘这⽅⾯，很多公

司都会选择使⽤Python，Python在这⽅⾯有先天的语⾔优势。对于很

多初学者来说，要想快速掌握Python，通过爬⾍来做业务场景的演⽰

是不错的选择。现在很多⽹站甚⾄业务中的主要数据来源都是通过爬

⾍来获取的。

3.⼈⼯智能

Python已经是数据分析和⼈⼯智能的第⼀语⾔，早就成为Web开

发、游戏脚本、计算机视觉、物联⽹管理和机器⼈开发的主流语⾔之

⼀，随着Python⽤户的增长，它还有机会在更多领域登顶。

在未来，云计算是基础设施，⼈⼯智能才是科技的未来。⽽

Python之所以会成为⼈⼯智能⾸选编程语⾔，主要是出于以下⼏个原

因：

（1）开发效率⾼

Python开发的效率⾮常⾼，即⽤少量代码就可以做很多事。因为

⼈⼯智能涉及⼤量的研究，如果⽤Java的话，也许要写200KB的代码

来测试及验证新的假说。但⽤Python，⽤户的每⼀个想法⼏乎都可以

迅速通过⼆三⼗⾏代码来实现。

（2）强⼤的第三⽅库

Python有⾮常强⼤的第三⽅库。基本上想通过计算机实现的任何

功能都能在Python官⽅库找到对应的⽀持模块，这可以有效地避免重

复“造轮⼦”，这也是Python在DevOps领域运⽤⼴泛的原因。因为

Python具备强⼤的OS层的第三⽅库，能让我们⾮常⾼效地实现操作系

统层⾯的任何操作。⽽Python在⼈⼯智能领域提供了像Scikit-learn这样

的好框架，集成了经典的机器学习算法，这些算法是和Python科学包

（NumPY、SciPY、Matplotlib）紧密联系在⼀起的。所以Python在⼈

⼯智能⽅⾯扮演着重要的⾓⾊，Python中的机器学习实现了⼈⼯智能

这⼀领域中的⼤多数需求。

（3）灵活性强

Python具有可移植性、可扩展性、可嵌⼊性等特点。对于⼈⼯智

能来说，其灵活性的应⽤是⾮常重要的。

3.5 “世界上最好”的语⾔

3个程序员坐在格⼦间⾥编程。⼀个程序员⼀⾔不发，他⽤的是

Python；另⼀个程序员写⼀会⼉就按⼀下编译，他⽤的是C++；还有

⼀个程序员坐在那⾥浏览⽹页，不时飞快地键⼊⼀些字符。经理看

到，怒道：“你怎么不⼲活！尽在上⽹”。这个程序员回答：“我在查实

现这个功能需要⽤什么函数。”他⽤的是PHP。

通过上⾯的例⼦从侧⾯可以看出来，“PHP是世界上最好的语

⾔”已成为程序员茶余饭后的搞笑话题。更多不是说PHP有多好，更多

是众多使⽤过PHP的开发者对这门编程语⾔的缺陷的笑谈。所以只有

当你真正使⽤过PHP，深⼊体会到PHP的⼀些缺陷（⽐如PHP的核⼼函

数命名很不⼀致）后，才能真正明⽩那⼀句“PHP是世界上最好的语

⾔”的好笑之处。

⽬前，PHP虽然已没有昔⽇的辉煌，但还算不上落寞，依然是编

程语⾔排⾏榜的前⼗。其主要应⽤在Web领域，在中⼩型Web开发⽅

⾯特别⾼效。完成同⼀个Web开发，其所需的代码量相当于Java的三

分之⼀。

在云端实践中，LAMP（Linux+Apache+MySQL+PHP）、

LNMP（Linux+Nginx+MySQL+PHP）依然是成熟的热门架构。我们可

以看到，PHP和Java在云端仍是出场频率最⾼的两种语⾔。在云端实

践中，PHP相⽐于Java，在Web应⽤⽅⾯有以下3个优点：

1.性能好

FastCGI PHP-FPM多进程模式，相⽐于单进程、多线程的Tomcat

模式，其性能要好很多。在多进程模式中，我们可以根据服务器配置

（不管是低配还是中⾼配），合理灵活地规划进程数（⽐如4核8GB，

按照PHP⼀个进程消耗30MB内存进⾏预估，建议配置256个进程。⽽8

核16GB，建议配置512个进程），并且PHP-FPM中静态和动态管理进

程的⽅式能够提升进程的稳定性及抗并发能⼒。⽽Tomcat是⼀个轻量

级中间件，⼀般单台Tomcat的极限并发能⼒在1000左右。所以单台

Tomcat适合部署在中低配的服务器配置中，⽐如4核8GB是部署单台

Tomcat的完美服务器配置；⽽在8核16GB等中⾼配的服务器配置中，

运⾏单台Tomcat往往会造成服务器的性能浪费；对于中⾼配的服务

器，要想把服务器性能都利⽤起来，不让服务器的配置浪费，⼀般要

在中⾼配服务器中跑多个Tomcat。

2.⽆须相关的编译操作

PHP是脚本语⾔，我们不需要做相关的编译操作。⽽Java的运⾏

需要先把Java源代码⽂件编译成class⼆进制⽂件。所以在PHP的发布

部署、变更中，我们只需要替换以前的⽂件就能即刻验证。但在Java

应⽤中，⽐如Tomcat，变更代码后需要重启。所以⽇常维护管理中，

PHP相⽐于Java来说要简单些。但从另⼀⽅⾯来看，这也算是Java的安

全性优点，Java运⾏的都是⼆进制语⾔，可以保护源代码。

3.集成简单

PHP和MySQL、Memcache、Redis的集成很简单，甚⾄直接在

php.ini配置⽂件中简单配置⼀下就能将Session存放在本地磁盘或者

Memcache、Redis中。⽽Java做Session的集中化管理就没这么简单了，

需要通过代码来实现。

3.6 最适合⾼并发的语⾔

2016年的年度最⽕语⾔是Go语⾔，Go语⾔⼏乎已经成为⾼性能、

⾼并发的代名词。截⾄今年（2019年），Go语⾔的⽕热程度仅次于

Python。在后端应⽤中（包括我公司的CloudCare系列产品），更多⼈

选择⽤Go语⾔来替换Java，以避免Java占⽤系统性能资源过多。

Go语⾔特别适合编写⼀些有性能瓶颈的业务，内存占⽤也⾮常

少。其近C语⾔的执⾏性能、近解析型语⾔的开发效率以及近乎完美

的编译速度，使其风靡全球。特别是在云项⽬中，⼤部分都使⽤了

Golang进⾏开发。⽐如国内第⼀个“勇于吃螃蟹”的，七⽜云平台就在

产品中⼤规模地应⽤Go，⽽开发效率和系统稳定性等客观数据也在持

续证明这⼀选择的正确性。很多⼈将Go语⾔称为“21世纪的C语⾔”，

因为Go语⾔不仅拥有C语⾔的简洁和性能，⽽且还提供21世纪互联⽹

环境下服务端开发的各种实⽤特性，让开发者在语⾔级别就可以⽅便

地得到⾃⼰想要的东西。

3.7 唯⼀的前后端语⾔

我们知道，JavaScript是⼀门前端语⾔。以前我做Java开发的时

候，热门的前端框架是jQuery、Ext，现在⽐较热门的前端框架是

Angular、Vue。

⽽什么是Node.js？Node.js是⼀个基于Chrome V8引擎的JavaScript

运⾏环境。Node.js使⽤了⼀个事件驱动、⾮阻塞式I/O的模型，使其轻

量又⾼效。简单地说，Node.js就是运⾏在服务端的JavaScript，它让

JavaScript既是前端语⾔又是后端语⾔。

前⼏年Node.js如⽕如荼，最近⼀两年热度下去了⼀些。Node.js刚

出来的时候，有⼈说Node将要取代Java，也有⼈说Node要取代PHP，

甚⾄还存在JavaScript会统⼀编程语⾔这样的⾔论。让我印象深刻的

是，那时“Node.js+MongoDB”敏捷开发的概念特别⽕，搞得我这个多

年不做开发的⼈都忍不住去⼀探究竟。当时⼈们都在探

讨“Node.js+MongoDB”将要取代PHP+MySQL做⽹站开

发、“Node.js+MongoDB”是如此⾼效等话题。现在这些讨论趋于平

淡。毕竟，⽤Node的基本都是⼀些前端开发者。

云诀窍

在云端实践中，采⽤Node.js做⽹站类开发的还算⽐较常见。所以

在ECS中安装Node.js，配置NPM（Node.js包管理⼯具）也是常见的运

维部署事项。值得注意的是，Node前期没有专门的进程管理⼯具，⼀

般采⽤“Shell+nohup”⽅式来管理Node进程，或者采⽤Supervisor专门的

进程管理⼯具来对Node进程进⾏管理。后来Node推出了PM2——⼀款

专门管理Node进程的⼯具（类似PHP的进程管理⼯具PHP-FPM），这

让Node在云端的维护管理变得规范化。

3.8 不可替代的机器语⾔

机器语⾔是计算机能直接运⾏的语⾔，即⼆进制语⾔。虽然汇编

语⾔介于C语⾔和机器语⾔之间，属于低级语⾔，但在我看来汇编语

⾔就属于机器语⾔了，虽然它需要编译，但是执⾏起来和机器语⾔没

有⼤的区别。⽽⾼级语⾔是依赖操作环境的，⽐如Java、Python、PHP

等，都需要在操作系统中安装代码运⾏环境。

汇编语⾔的传统应⽤场景主要有两个：

·在单⽚机编程⾥⾯，使⽤汇编语⾔，直接操作硬件。

·在⾼级语⾔编程中，专门针对某些额外影响性能的关键函数使⽤

汇编语⾔改写，进⾏代码优化。

第4章 系统技术选型

在选择了对应的软件技术（编程语⾔）来做业务开发后，最终需

要确认使⽤什么系统架构技术来进⾏云端运维部署。本章是选型篇的

重点篇幅，其核⼼内容包含云端⽹络、云端Web服务器、云端负载均

衡、云端存储、云端缓存、云端数据库6个⼤类，基本覆盖了云端千万

级运维架构常见的运维技术。⽽通过云端实践总结出来的每个技术特

点、应⽤场景、功能及性能特性，将为你在云端运维架构技术选择上

提供重要的参考信息。

4.1 云端⽹络的三种选型策略

⽹络是企业级应⽤的⾎液，⼀⽅⾯，应⽤、数据库、缓存等服务

需要靠⽹络进⾏连接。另⼀⽅⾯，⽹络是⽤户和业务应⽤服务之间进

⾏“互动访问”的桥梁。所以⽹络的选择，直接影响服务之间的调⽤，

以及⽤户访问的性能、效率、稳定、安全等。接下来通过⽹络架构类

型、⼊请求及出请求的⽹络场景这三⼤场景，来详细介绍云端⽹络的

三种选型策略。

4.1.1 策略⼀：⽹络类型选型的五个注意点

在云端，⽹络架构的选择对后期的业务规划、安全性、架构扩展

等来说⾄关重要，云端⽬前可选的⽹络架构包括经典⽹络、VPC专有

⽹络、⾦融云⽹络等。其中，⾦融云⽹络也是基于VPC的专有⽹络，

只不过在此基础上加⼊了很多安全规则及限制保障更⾼的安全性需

求。所以整体来讲，云服务器ECS的⽹络类型分为经典⽹络和VPC专有

⽹络两种。

从技术原理上来讲，经典⽹络和VPC专有⽹络又有什么区别呢？

经典⽹络采⽤三层（⽹络层，即IP层）隔离，所有的经典⽹络类型实

例都建⽴在⼀个共⽤的基础⽹络上。VPC采⽤⼆层隔离（数据链路

层），相对经典⽹络⽽⾔，VPC具有更⾼的安全性和灵活性。在2014

年以前，阿⾥云只有经典⽹络的，其适合的业务场景是有限的。使⽤

经典⽹络和VPC专有⽹络的技术特点对⽐如下。

注意点1：⽹段⽅⾯

经典⽹络的内⽹IP是以10开头的随机IP，且内⽹IP只能随机分配，

不能⾃定义。

⽽在VPC⽹络中，每个客户都是独⽴的⽹络环境。客户可以⾃定

义⽹络的IP段、⽹络架构等。

注意点2：⽹卡⽅⾯

经典⽹络绑定公⽹的ECS（Linux系统），系统中⽹卡是两个⽹

卡。eth0是内⽹⽹卡，eth1是公⽹⽹卡。如果没有绑定公⽹，则经典⽹

络仅有⼀个内⽹eth0。

⽽VPC⽹络，即使绑定了弹性IP的ECS⽹卡也只有⼀个eth0，即不

管有没有绑定弹性IP，VPC⽹络的ECS仅有⼀个eth0⽹卡（绑定弹性IP

的时候，公⽹数据是通过阿⾥云内部NAT的⽅式流转到ECS的eth0⽹卡

上的）。

这⾥有个很重要的实践：经典⽹络下，只能在开通ECS的时候选择

绑定公⽹。如若开通ECS的时候没有选择绑定公⽹，开通后没办法再绑

定公⽹。弹性IP针对VPC⽹络，灵活性⾮常⾼。想⽤时随时可以绑定公

⽹弹性IP，不⽤了随时解绑。⽽且通过申请弹性IP，可以⾮常灵活地跟

ECS更换公⽹IP。所以在爬⾍、容易被墙需要经常更换公⽹IP的业务

中，这是⾮常好的⼀个功能应⽤。

另外，对于经典⽹络和VPC⽹络，在ECS中设置防⽕墙是有很明显

的区别的。在实践应⽤中，我们⼀般只会在开启公⽹（⼊⽹请求）的

ECS上开启Iptables来做安全规则设置（默认不推荐在只有内⽹的机器

上设置Iptables）。在经典⽹络下，由于eth1⽹卡代表公⽹流量，所以

我们可以很⽅便地⽤“iptables-i eth1”指定公⽹流量⽹卡来做安全规则。

⽽在绑定弹性EIP的ECS中，公⽹流量和内⽹流量都是经过eth0⽹卡

的，因此做Iptables规则的时候⽐较⿇烦。

注意点3：⽹络隔离⽅⾯

经典⽹络客户和客户之间的数据通过安全组三层隔离。如果需要

互通，安全组配置互访规则即可。

经典⽹络安全组实践案例：通过简单地配置安全组互访规则，实

现同地域下不同阿⾥云账号的经典⽹络内⽹互通。这在早期没有VPC

甚⾄没有RAM账号的情况下，可是⾮常热门的架构。这个架构会把服

务器放在不同的阿⾥云账号中，不同的阿⾥云账号给公司内部不同的

团队/不同负责⼈进⾏管理维护（当前在阿⾥云不⽤划分多个阿⾥云账

号了，可以通过⼀个阿⾥云账号开通RAM权限划分有效解决）。然后

通过安全组打通不同阿⾥云账号同地域的内⽹，实现业务互联。

VPC和VPC之间默认⼆层隔离（不管是同阿⾥云账号下的不同VPC

还是不同阿⾥云账号下的VPC），如果需要互通则只能⾛⾼速通道

（专线）。

从上述对⽐中能看出来，经典⽹络在内⽹隔离的安全性⽅⾯不太

好。

注意点4：⽹络功能⽅⾯

上述⽹段划分、⽹段隔离功能，仅VPC⽹络⽀持。⾃建VPN（或

者使⽤阿⾥云VPN⽹关服务）、阿⾥云⾼速通道（专线）的功能⽀

持，都需要依托VPC⽹络。这意味着，混合云的架构必须基于VPC⽹

络环境，如图4-1所⽰。

图4-1 基于VPC的云端VPN⽹络架构

通过VPN（拨号VPN，如openVPN；Ipsec VPN，如

StrongSwanVPN）或者专线，我们能将云端⽹络和线下办公⽹络或者

数据中⼼实现内⽹互通，这是VPC企业级最佳实践⽅案。如果⽤经典

⽹络环境是没办法将两个环境的内⽹进⾏互通的。另外经典⽹络仅⽀

持DNAT，不⽀持SNAT，⽽VPC⽹络却能⽀持DNAT和SNAT。

注意点5：⽹络实践⽅⾯

经典⽹络和VPC⽹络的⽹络架构不同，技术特点不同，也导致了

它们在实践上有很⼤差距。

经典⽹络：⽅便快捷，不需要设置VPC、vSwitch、⽹络规划等。

它是随机内⽹，开通即⽤。⼀般适合部署个⼈应⽤、个⼈站点等。

VPC⽹络：企业默认的⽹络架构选择，⽹段划分、⽹络隔离及相

关⽹络功能都是企业级⽹络所必需的。

我们知道⾦融类应⽤对安全性⾮常敏感，要求也是⾮常⾼的，我

见过⾦融类客户把业务还部署在经典⽹络的。若是这种情况，相关的

安全风险、架构扩展性等问题真的很严重了。

4.1.2 策略⼆：⼊⽹请求选型的四种⽅法

在云端对ECS实现⼊⽹请求的功能，可以通过以下4种⽅法实现。

·SLB⽹络：七层和四层的负载均衡，都能将公⽹的请求流量引⼊

到ECS中。

·公⽹IP：经典⽹络的公⽹IP，能直接将公⽹的请求流量引⼊到

ECS中的eth1⽹卡上。

·弹性EIP：VPC专有⽹络的弹性EIP，能直接将公⽹的请求流量引

⼊到ECS中的eth0⽹卡上。

·DNAT：通过端⼜映射能直接将公⽹的请求流量映射到ECS的内

⽹端⼜上。值得注意的是，在云端我们可以通过Iptables或者NAT⽹关

实现DNAT的端⼜映射。

通过以上4种⽅法，我们把云端⼊⽹请求的类型划分为以下两⼤

类。

1）负载均衡类：DNAT端⼜映射的基本原理就是负载均衡，即

DNAT和四层负载均衡的本质是⼀样的，在内核层修改访问者的⽬标

IP和⽬标端⼜。负载均衡类，⼀般都是多台机器同时对外提供服务，

尤其是在Web应⽤中尤为常见。⽐如，SLB+3台部署Tomcat的ECS，通

过SLB将部署在内⽹ECS上的8080端⼜（Tomcat端⼜）间接暴露给公

⽹请求。

2）公⽹IP类：经典⽹络的公⽹IP和弹性EIP的本质基本相同，都

是绑定在ECS上，直接为ECS提供公⽹互访能⼒。ECS需要暴露部署的

服务端⼜，以便访问请求公⽹其他⽬标服务、下载公⽹上其他⽂件

等。这时候直接跟ECS绑定公⽹是最便捷的做法。

公⽹IP类，是云端实践中⼤家为ECS提供公⽹访问的最常见做

法。在云端实践中，为ECS直接绑定公⽹主要的场景需求有以下3点。

·ECS服务需要暴露给公⽹。

·需要公⽹远程登录到这台服务器进⾏维护。

·ECS上部署的服务需要去公⽹调⽤及请求第三⽅的服务及接⼜。

⽽通过以上3点，我们发现，让每台服务器都绑定公⽹的⼏乎完全

没有意义。

⾸先，如果仅仅是想将在ECS上部署的相关服务，如Nginx、

Tomcat、MySQL，暴露给公⽹，采⽤SLB是最为灵活的做法，⽽且

SLB的加⼊，使后续相应的性能扩展也⼗分⽅便，只需要在SLB后再

⽔平增加对应机器即可。

其次，在很多场景中，给服务器开公⽹带宽只是为了让服务器能

够远程SSH连接⽽已。我见到过这样的场景，⼀个客户有⼆三⼗台服

务器，为每台服务器开个公⽹IP，⽬的就是⽅便远程，但这样使⽤的

合理性、安全规范性有很⼤隐患。如果仅仅只是远程使⽤，在没有使

⽤堡垒机的情况下，可以⽤SLB四层转发SSH的请求到⼀台ECS上（或

者直接绑定EIP，这台机器类似跳板机，跟堡垒机的原理差不多），然

后将这台机器与后端服务器的“SSH key”打通，这样登录⽬标服务器就

都是⼀键式，如图4-2所⽰。

图4-2 远程登录流程架构图

对于服务器需要去公⽹请求第三⽅服务及接⼜的需求，采⽤NAT

⽹关的SNAT功能即可，根本不需要单独给ECS绑定公⽹。

最后，给ECS绑定公⽹存在很⼤安全隐患，这等同于给⿊客开了

⼀道能触达ECS的门，⽅便通过端⼜扫描、漏洞嗅探实现⼊侵。

通过以上说明我们发现，在云端，出于安全性等⽅⾯的考虑，直

接让ECS绑定公⽹IP的场景是不多见的（其实在⾦融云⾥是强制性限

制了的。⽐如让ECS绑定公⽹，外⽹就不能直接访问）。直接绑定公

⽹⼀般适⽤于在服务器上部署了FTP等功能，由于服务协议的关系

等，没办法直接通过SLB负载均衡的⽅式把服务暴露给公⽹。

4.1.3 策略三：出⽹请求选型的三种⽅法

在云端对ECS实现出⽹请求的功能，可以通过以下3种⽅法实现。

·公⽹IP：经典⽹络的公⽹IP，通过ECS中的eth1⽹卡将ECS的出公

⽹请求流量发出。

·弹性EIP：VPC专有⽹络的弹性EIP，公⽹的请求流量在云平台内

部通过NAT映射出公⽹。

·SNAT：通过路由将公⽹请求的流量映射到NAT⽹关，或者⼀台

具有公⽹访问能⼒的ECS上，再由这台ECS将公⽹请求流量转发出

去。

通过以上3种⽅法，我们把云端出⽹请求的类型划分为以下两⼤

类。

·公⽹IP类：经典⽹络的公⽹IP和弹性EIP的本质差不多，绑定在

ECS上，直接为ECS提供公⽹互访能⼒。

·SNAT类：不⽀持经典环境，在VPC环境中，我们可以选择⼀台

具有公⽹访问能⼒的ECS（绑定了公⽹IP），通过配置Iptables来实现

SNAT。

实践中，不建议⽤户⾃⼰搭建SNAT，⾃⼰搭建的SNAT容易存在

单点故障。⽐如有个客户有⼀百多台机器部署的服务，有很多服务器

都需要公⽹请求第三⽅接⼜。有⼀次重启SNAT那台机器后，Iptables

的防⽕墙规则没有启动，导致线下业务⼤⾯积受损。所以在云端，应

优先使⽤对应云产品（NAT⽹关）来解决我们对SNAT的需求，以有效

避免单点故障等⽅⾯的问题。

云诀窍

阿⾥云流量带宽峰值、流量带宽费⽤针对的是出⼜流量峰值及出

⼜流量带宽费⽤。

⽐如，5Mbps的带宽峰值是指出⼜带宽峰值，并不是⼊⼜带宽峰

值，相反，⼊⼜流量峰值是不受限制的。再如，5Mbps峰值的带宽，

产⽣的费⽤只是出⼜流量产⽣的费⽤，并不是指⼊⼜流量产⽣的费

⽤。这就意味着，我们上传10GB的⽂件数据到ECS上是不收取流量费

⽤的（这是⼊⼜流量），如若要下载10GB的⽂件数据，则要产⽣流量

费⽤（出⼜流量）。

在IDC业务迁云的场景中，云端公⽹哪怕只设置1Mbps也不会影响

数据传输的速度，因为数据上云⾛的是⼊⼜带宽，⽽云端1Mbps是出

⼜带宽，不受⼊⼜带宽限制。唯⼀影响迁移速度的就是IDC机房中的

出⼜带宽，它会直接影响迁云数据传输速度。

有些客户担⼼DDoS攻击会产⽣额外的流量费⽤，其实不⽤担⼼，

DDoS产⽣的瞬时⼏⼗吉字节的流量都是⼊⼜流量，是不收费的。在这

种流量攻击中，唯⼀可能产⽣费⽤的就是CC攻击，其类似于刷⽹页，

这会导致出⼜流量增加，产⽣额外的流量费⽤。

所以，有些客户担⼼DDoS攻击会产⽣额外的流量费⽤。其实这⽆

须担⼼，DDoS产⽣的瞬时⼏⼗GB的流量都是⼊⼜流量，是不收费

的。在这种流量攻击中，唯⼀可能产⽣费⽤的就是CC攻击，就是类似

刷⽹页，导致我们的出⼜流量增加，从⽽产⽣额外的流量费⽤。

4.2 云端Web服务器的五点选型考虑

Web服务器⼀般是指⽹站服务器，是指驻留于因特⽹上某种类型

计算机的程序，可以向浏览器等Web客户端提供⽂档，可以放置⽹站

⽂件让全世界的⽤户浏览，也可以放置数据⽂件让全世界的⽤户下

载。⽬前最主流的3个Web服务器是Apache、Nginx、IIS。这是百度百

科中对Web服务器的定义，除了Web服务器，还有应⽤服务器（主要

⽤于运⾏动态语⾔PHP、JSP的服务器）。其实多年前我⼀直不明⽩

Web服务器的⽤途，甚⾄经常将其与应⽤服务器混淆，但随着相关的

案例场景运⽤增多后，就慢慢理解透彻了。⾸先来看看Web服务的发

展所经过的3个阶段。

·Web1.0：本质是联合，以静态、单向阅读为主，如早期的新浪、

搜狐门户⽹站。内容⼀般由站长更新维护，缺乏⽤户分享互动。⽽这

时候的Web服务⼀般偏向静态内容的展⽰。

·Web2.0：本质就是互动，它让⽹民更多地参与信息产品的创造、

传播和分享，如天涯论坛、微博都是Web2.0典型的应⽤。⽽这时候的

Web服务⼀般偏向复杂的动态内容的应⽤（如PHP、JSP），不仅仅是

单纯的静态内容了。

·Web3.0：是在Web2.0的基础上发展起来的，能够更好地体现⽹民

的劳动价值，并且能够实现价值均衡分配的⼀种互联⽹⽅式。在未

来，Web3.0会基于⼈⼯智能，⽤浏览器即可实现复杂的系统程序才具

有的功能。

通过这3个阶段我们发现百度百科对Web服务器的定义，还停留在

Web1.0的时代，即放置⽹站⽂件、提供数据下载。这是Web服务器中

对静态HTML/JS/CSS/图⽚内容⽀持的重要功能。

随着分布式技术的发展，推进了PHP、JSP等动态Web技术的发

展。Web服务器又简称七层服务器，在Web2.0中，Web服务器不仅仅

需要对静态内容提供⽀持，还需要提供反向代理、Rewrite等重要功

能，这是跟应⽤服务器（PHP、JSP）结合使⽤的重要功能（相关内容

会在第7章中重点介绍）。

在云端Web类应⽤中，Apache/Nginx/IIS的出场率⾼达95%以上。

Apache是Web服务器的“领头⼈”，同时Nginx作为Web服务器也是⾮常

优秀的，IIS主要作为Windows服务器下的Web类应⽤。不过我们也常

见在Windows服务器下安装配置使⽤Apache、Nginx，从架构⽅⾯来

讲，Apache/Nginx对Windows服务器的⽀持不如Linux系统。所以在

Linux下能灵活地配置调优，能让Apache/Nginx的性能和效率最⼤化。

由于IIS是Windows下⾃带的Web服务器，这⾥不做更多介绍。

在云端Web服务器的应⽤中，我更喜欢⽤OSI模型来描述，叫

HTTP七层服务器。⽽Nginx作为HTTP七层⽆所不能的软件，其在Web

领域的应⽤⼏乎完胜Apache。所以我们在云端的实践中，偏向⽤

Nginx的现象是⾮常明显的。Apache与Nginx的实践对⽐有以下4点，

这4点也是进⾏云端Web服务器选型时的考虑依据。

4.2.1 考虑⼀：稳定性

通过云端实践，我发现⼈们在Apache和Nginx对⽐⽅⾯有个很⼤

的误区需要纠正⼀下。说到Apache与Nginx的应⽤场景，很多书籍及

包括⽹络上的⽂章都说Apache是基于Select⽹络模型的，更适合运⾏动

态内容，稳定性更好些。⽽Nginx基于Epoll⽹络模型，更适合运⾏静

态内容，⾼并发性能更好些。但在实际应⽤中，我们发现Nginx运⾏动

态内容也挺稳定的。⽐如Nginx+FastCGI（PHP-FPM）运⾏PHP应⽤，

整体跑下来也挺稳定的。当前在云端

LNMP（Linux+Nginx+MySQL+PHP）架构的应⽤明显⽐

LAMP（Linux+Apache+MySQL+PHP）要多，有替代其趋势。这⾥要

注意的是，Nginx+FastCGI（PHP-FPM）经常出502错误，并不是

Nginx不稳定导致的问题（Nginx甚⾄运⾏⼏⼗年都不会出现稳定性问

题，⾄少我⼀直没见过或者听过因为Nginx稳定性导致的服务异常），

⽽更多是后端PHP运⾏出现错误，直接体现到Nginx检测出后端的异

常，从⽽报出502的HTTP状态码。

4.2.2 考虑⼆：性能

Nginx基于Epoll⽹络IO模型，Apache基于Select⽹络模型。Nginx

相⽐Apache，⾼性能、⾼并发、系统资源占⽤少。Nginx核⼼特点是

轻量级!Nginx官⽹表⽰，Nginx保持10000个没有活动的连接，⽽这些

连接只占⽤2.5MB内存。⽽在3万并发连接下，开启10个Nginx线程消

耗的内存不到200MB。因此，类似DOS这样的攻击对Nginx来说基本

上是没有任何作⽤的。⽽在性能⽅⾯，Apache是可望⽽不可即的。

Apache强⼤的处理功能导致各种模块过于臃肿，带来性能上的较⼤损

耗。

4.2.3 考虑三：对负载均衡功能的⽀持

在负载均衡/反向代理⽅⾯，Nginx是⼀款在七层及四层优秀的负

载均衡/反向代理（具体负载均衡和反向代理的区别在4.3节中详细介

绍）。在以前的版本中，Nginx只⽀持七层的负载均衡。后来从1.9.0版

本开始，Nginx也⽀持四层的负载均衡。这意味着，Nginx能对

MySQL、Redis等服务做负载均衡了。这⼀功能的出现使之前优秀的

七层/四层负载均衡HAProxy受到极⼤挑战。因为Nginx不仅能作为七

层/四层⽅⾯的负载均衡，在Web服务器、静态缓存、丰富的第三⽅插

件等其他⽅⾯的功能也很优秀，这让⽤户选择HAProxy的可能性降

低。

图4-3 Apache作为负载均衡的系统架构

⽽相⽐Nginx，Apache也⽀持七层的负载均衡功能，

Apache+Tomcat经典的组合，就是利⽤Apache七层负载均衡的功能。

在七层，Apache有专门的proxy模块来实现这样的负载均衡配置。相⽐

Nginx+Tomcat的组合，Apache针对Tomcat的集成的紧密度更深。

Apache服务器和Tomcat的连接⽅法其实有3种：JK、http_proxy和

ajp_proxy。不过Apache在七层负载均衡的性能，相⽐于Nginx来讲，

要弱太多。图4-3所⽰是我曾经做过的⼀个失败的架构案例，以供读者

参考。

在图4-3中，通过给8核32GB的⼀台服务器部署Apache作为Tomcat

的负载均衡。我们做了⼗万在线⽤户的压测，发现Apache的极限抗并

发能⼒为3000～5000。后⾯如果有更多的请求，Apache将会严重超

时，服务器负载也较⾼。这个架构是我刚毕业在第⼀家公司⾥设计

的。⽽如今，我们⽤1台4核8GB部署Nginx应该是完全没有压⼒的。当

然，在上述架构中，3台MySQL主主同步架构也不建议运⽤在⽣产环

境中，因为主主同步架构在⾼并发场景下，在不同主机上同时对某条

数据进⾏写操作，很可能导致数据不⼀致性的问题。

4.2.4 考虑四：前端静态数据缓存

在Web缓存服务⽅⾯，Nginx可通过⾃⾝的proxy_cache模块实现类

Squid等专业缓存软件的功能。在静态缓存这块，⼀般采⽤Squid、

Varnish、Nginx，当前CDN产品的实现，底层其实就是采⽤这3个开源

缓存技术。虽然Apache也能做静态缓存这块功能，但⾄少没听说过

CDN的静态缓存是⽤Apache来实现的。另外，Nginx的静态资源，如

图⽚、HTML、CSS、JS等的处理能⼒也要强于Apache。

4.2.5 考虑五：丰富的插件及⽀持灵活的⼆次开发

Nginx在热门开源软件中都有相应的丰富插件。⽐如针对

Memcache、Redis、LDAP、MongoDB的插件，让Nginx也能对

Memcache、Redis、LDAP、MongoDB做反向代理。这些令⼈激动的

好⽤功能将在第⼆篇中详细介绍。

我们都知道，虽然Nginx有很多的特性和优势，但是随着Nginx的

应⽤逐渐深⼊，原本Nginx⾃带的功能特性可能满⾜不了我们特定场景

下的需求，不可避免地需要⼀些定制化的功能，即需要做⼆次开发。

⽽Nginx源代码采⽤C语⾔开发，这将使我们的⼆次开发变得⾮常复

杂。为了⽅便开发⼈员，OpenResty整合了Nginx和Lua的框架，它帮我

们实现⽤Lua的规范开发实现各种业务，并且厘清各个模块的编译顺

序。⽽同时OpenResty在开源WAF上使⽤得⾮常⼴泛，中⼩型应⽤出

于成本考虑，觉得使⽤云端WAF产品偏贵，⽤OpenResty也是⼀个不

错的⽅案（相关应⽤场景将会在第三篇中介绍）。通过OpenResty在七

层WAF中的运⽤可知，Nginx+Lua主要实现七层复杂逻辑控制，主要

针对七层HTTP头、IP访问判断、SQL注⼊判断等。

云诀窍

OpenResty是云端开源WAF的最佳实践。

4.3 云端负载均衡选型的五个⽅⾯

负载均衡既是分布式架构的基础也是其核⼼，负载均衡的使⽤可

以实现会话同步，消除服务器单独故障；也可以进⾏请求流量分流，

提升冗余，保证服务器的稳定性。

4.3.1 对⽐⽅⾯：四⼤热门负载均衡的优缺点

在开源的软件负载均衡中，应⽤最为⼴泛的为LVS、Nginx、

HAProxy，甚⾄阿⾥云的SLB也是基于LVS及Nginx的。

1）LVS虽是负载均衡的开⼭⿐祖，但很可惜，云端实践中不⽀持

在ECS中部署使⽤LVS。因为LVS基于虚拟VIP，阿⾥云当前底层限

制，经典⽹络和VPC专有云⽹络都不⽀持虚拟VIP的功能。

2）不⽀持Keeplived的部署。类似Oracle RAC环境需要虚拟VIP的

功能，都没办法在云端⽹络环境中直接部署。不过在云端的实践中，

基于阿⾥云的VPC专有⽹络⽤N2N搭建VPN⽹络。建⽴在VPN上的⽹

络实现虚拟VIP功能，从⽽能⽀持Keeplived、Oracle RAC的部署，甚⾄

让部署LVS也成为可能。在云端的实践中，也有部署过N2N+Oracle

RAC的案例，但基于N2N⽹络的稳定性和性能不佳，并不推荐采⽤这

种⽅式，这会给维护管理带来很⼤挑战。

在云端实践中，Nginx、HAProxy的应⽤是⾮常⼴泛的。具体

LVS、Nginx、HAProxy的特性、应⽤场景，接下跟⼤家介绍⼀下。

1.LVS

LVS是Linux Virtual Server的简写，意即Linux虚拟服务器，是⼀个

虚拟的服务器集群系统。本项⽬于1998年5⽉由章⽂嵩博⼠成⽴，是中

国国内最早出现的⾃由软件项⽬之⼀。

现在，LVS已经是Linux标准内核的⼀部分，在Linux2.4内核以前，

使⽤LVS时必须重新编译内核才能⽀持LVS功能模块。但是从Linux2.4

内核以后，已经完全内置了LVS的各个功能模块，⽆须给内核打任何补

丁，可以直接使⽤LVS提供的各种功能。它具有以下⼀些特性。

·⼯作在⽹络⼆层/三层/四层之上仅作分发之⽤，对CPU和内存消耗

极低，抗负载能⼒极强。特别是在DR模式下，流量会⾛后端服务器的

⽹卡，这个特点也决定了它在负载均衡软件⾥的性能是最强的，甚⾄

能媲美硬件服务器。

·由于当前Linux内核直接集成了LVS，所以配置性⽐较低，并不需

要太多接触，没有复杂的配置项，⼤⼤减少了⼈为出错的概率。

·应⽤范围⽐较⼴，因为LVS⼯作在⼆层/三层/四层最底层，所以它

⼏乎可以对所有应⽤做负载均衡，包括HTTP、数据库、在线聊天室

等，并且LVS的3种⼯作模式、10种调度算法使其在负载均衡端有更灵

活的策略选择。

LVS也有它的缺点，下⾯⼀起来看⼀看。

·云端ECS不⽀持LVS的部署，所以对⼆层/三层/四层负载均衡需

求，只能使⽤云产品SLB的四层负载均衡功能替代，或者⾃⾏部署

Nginx/HAProxy。

·LVS不⽀持七层的虚拟主机、Rewrite正则表达式处理、动静分离

等功能。⽽现在许多Web⽹站在这⽅⾯已有较强的需求，这是

Nginx/HAPrxoy的优势所在。

·LVS适合应⽤在中⼤型应⽤中，不适合中⼩型应⽤，特别是中⼩

型⽹站的应⽤。这是因为我们部署的⽹站⼀般都会有虚拟主机、动静

分离、正则分发的需求。⼀般使⽤Nginx就能直接实现，⽽且Nginx的

万级别的⾼并发处理能⼒应对中⼩型的应⽤绰绰有余。如果中⼩型应

⽤中还部署LVS，还要在Nginx+应⽤服务前⾯加台服务器部署⼆层/四

层的负载均衡。这样不仅⽐较消耗机器，也增加了运维成本等。

2.Nginx

Nginx（Engine x）是⼀款轻量级的Web服务器/反向代理服务器及

电⼦邮件（IMAP/POP3）代理服务器，并在⼀个BSD-like协议下发

⾏。

Nginx是由伊⼽尔·赛索耶夫为俄罗斯访问量第⼆的Rambler.ru站点

（俄⽂：Рамблер）开发的，第⼀个公开版本0.1.0发布于2004年10⽉4

⽇。

其特点是占⽤内存少、并发能⼒强，加上丰富的插件功能模块，

当前是云端Web类应⽤中⾸选的⼀款软件。以下是它的具体特性。

1）可以做七层HTTP的负载均衡，可以针对HTTP应⽤做⼀些分流

的策略，⽐如针对域名、⽬录结构，它的正则规则⽐HAProxy更为强⼤

和灵活。加上现在主流还是Web应⽤，Nginx单凭七层功能特性这点，

可利⽤的场合就远多于LVS了，这也是它⽬前⼴泛流⾏的主要原因之

⼀。如果说PHP使Web⽹站“⼀统天下”，那Nginx便在Web服务器届“谁

与争锋”。

2）Nginx之前的版本只⽀持七层HTTP的负载均衡功能。从1.9.0版

本开始，Nginx⽀持对四层TCP的负载均衡功能。这让Nginx如虎添翼，

成为顶级软件。⽼版本的案例中，很多⼈选择HAProxy做负载均衡的主

要原因是Nginx不⽀持四层的负载均衡，如对MySQL做负载均衡，当前

Nginx版本已经⽀持。

3）Nginx不仅仅是⼀款优秀的负载均衡器/反向代理软件，同时也

是功能强⼤的Web应⽤服务器。LNMP也是近⼏年⾮常流⾏的Web架

构，在⾼流量的环境中稳定性也很好，⼏乎替代了LAMP的Web架构。

4）Nginx现在作为Web反向加速静态缓存越来越成熟，Nginx也可

作为静态⽹页和图⽚服务器。其速度⽐传统的Squid服务器更快，基本

上CDN在底层静态缓存服务器的选择，如今Nginx是⼀个成熟的解决⽅

案。

5）Nginx社区⾮常活跃，第三⽅模块也很多，⽐如对Memcache、

Redis、LDAP、MongoDB的插件⽀持等，甚⾄可以结合Lua在七层定制

化开发，实现更多满⾜业务需求的功能。⽐如开源WAF：OpenResty，

是七层防御中成熟的解决⽅案（相关内容在第14章中会详细介绍）。

Nginx的缺点如下。

1）对后端服务器的健康检查，只⽀持通过端⼜来监测，不⽀持通

过URL来监测。这就会导致，在七层的健康监测中，很多情况下端⼜

是正常的，但应⽤URL访问异常，Nginx却不能识别，反⽽主动剔除这

个有问题的服务器，最终导致客户端继续访问有异常的服务器。

2）相⽐于HAProxy，Nginx在七层对会话保持的功能就弱了些，

Nginx默认只⽀持通过配置ip_hash（通过识别客户端IP，将请求转给后

端同⼀个服务器达到会话保持的效果）。ip_hash在实践中虽然解决了

会话保持的问题。其实并不能在七层中做到很好的流量均衡，⽐如我

们驻云上海办公⽹络（有200⼈办公）去请求Nginx，如果Nginx配置了

ip_hash参数，这200⼈的请求都会被Nginx转发到后端的某⼀台服务器

上，并不能很好地进⾏流量负载均衡。Nginx可以通过第三⽅模块向客

户端植⼊Cookie达到会话保持的⽬的，它解决了ip_hash的缺陷，但是

这种⽅式需要重新编译Nginx增加nginx-sticky-module模块。

3.HAProxy

HAProxy是⼀个使⽤C语⾔编写的⾃由及开放源代码软件，是⼀款

主要作⽤在七层HTTP和四层TCP上的负载均衡软件。和LVS⼀样，主

要是⼀个专业级的负载均衡。以下是HAProxy的特性说明。

1）HAProxy是⼀款专注在七层/四层的软负载均衡软件，但相⽐于

Nginx少了相应的Web服务器、静态缓存、丰富的第三⽅插件等功能。

2）HAProxy的优点能够弥补Nginx的⼀些缺点，⽐如在七层中对会

话保持的⽀持，只需要简单配置对应参数就能选择不同策略⽅式来满

⾜会话保持。同时在健康检查中，⽀持通过获取指定的URL来检测后

端服务器的状态。以下是对应配置参数的说明。

·源地址HASH（⽤户IP识别）：HAProxy将⽤户IP经过HASH计算

后，指定到固定的真实服务器上（跟Nginx的ip_hash原理⼀样）。

·Cookie识别：HAProxy将返回给客户端的Cookie中插⼊HAProxy中

特定的字符串（或添加前缀）。

·基于Session：HAProxy将后端服务器产⽣的Session和后端服务器

标识存在HAProxy中的⼀张表⾥，接到客户端请求时先查询这张表。

3）HAProxy跟LVS类似，本⾝就只是⼀款专业级负载均衡软件，

少了很多其他功能。所以单纯从效率上来讲，原则上HAProxy会⽐

Nginx有更出⾊的负载均衡性能，在并发处理上也是优于Nginx的。但

在实践中区别不⼤，七层抗并发的量级都在2万～5万，四层负载均衡

的性能相差也不⼤。我之前遇到的⼀个真实案例，在电商的⾼流量⾼

并发场景下，⽤Nginx做七层负载均衡时，导致Nginx所在服务器的负

载和压⼒有点⾼。我当初的想法是⽤专业的负载均衡软件尝试提升性

能，但实际上部署了七层HAProxy基本上结果也是⼀样，性能并没有得

到改善。

4）作为⼀款专业级的负载均衡软件，HAProxy的策略⾮常多，

HAProxy的负载均衡算法现在具体有8种，这⽅⾯相⽐Nginx来讲也是⼀

个优势。

下⾯来看看HAProxy的缺点。

相⽐Nginx，HAProxy在云端的实践运⽤是⽐较尴尬的。⼀⽅⾯，

HAProxy在七层和四层的负载均衡的应⽤场景⼏乎被云产品SLB覆盖

了。另⼀⽅⾯，Nginx也⼏乎能替代HAProxy在七层和四层负载均衡的

功能应⽤。所以在云端实践中，Nginx除了能做七层/四层负载均衡外，

更有令⼈意想不到的⼀些功能应⽤，我们更加倾向于选择Nginx。⽽在

四层对MySQL、Redis、MongoDB做负载均衡时，我们可能还是会下意

识地想到要部署HAProxy，这可能是对⼀个⽼牌的四层负载均衡的⼀种

怀念和执着吧。但其实本质上，如今Nginx在四层负载均衡上的性能和

稳定性已不⽐HAProxy差。

4.阿⾥云SLB

阿⾥云SLB（Server Load Balancer）当前提供四层（TCP协议和

UDP协议）和七层（HTTP和HTTPS协议）的负载均衡服务，SLB的架

构如图4-4所⽰。

·四层采⽤开源软件LVS（Linux Virtual Server）+Keepalived的⽅式

实现负载均衡，并根据云计算需求对其进⾏了个性化定制。

·七层采⽤Tengine实现负载均衡。Tengine是由淘宝⽹发起的Web服

务器项⽬，在Nginx的基础上，针对有⼤访问量的⽹站需求添加了很多

⾼级功能和特性。

图4-4 阿⾥云SLB架构

阿⾥云七层负载均衡采⽤的Tengine，其本质就是Nginx。Tengine

是阿⾥巴巴发起的Web服务器项⽬，在Nginx的基础上，针对⼤访问量

⽹站的需求，Tengine添加了很多⾼级功能和特性。Tengine的性能和稳

定性已经在⼤型⽹站，如淘宝⽹、天猫商城等得到了很好的检验。它

的最终⽬标是打造⼀个⾼效、稳定、安全、易⽤的Web平台。

Tengine开源地址：http://tengine.taobao.org。

针对云计算场景，Tengine定制的主要特性如下：

·继承Nginx-1.4.6的所有特性，百分之百兼容Nginx的配置。

·动态模块加载（DSO）⽀持。加⼊⼀个模块不再需要重新编译整

个Tengine。

·更加强⼤的负载均衡能⼒，包括⼀致性Hash模块、会话保持模

块，还可以对后端的服务器进⾏主动健康检查，根据服务器状态⾃动

上下线。

·监控系统的负载和资源占⽤，从⽽对系统进⾏保护。

·展⽰对运维⼈员更友好的出错信息，便于定位出错机器。

·更强⼤的防攻击（访问速度限制等）模块。

其实阿⾥云早期的七层SLB还不⽀持七层虚拟主机的功能，单纯地

做七层转发功能，不能做七层的判断，所谓七层负载均衡的意义不

⼤。当然现在已经⽀持虚拟主机的功能了，但如果想要更多Rewrite等

七层正则匹配等功能，只能在后端ECS上搭建Nginx来处理。

4.3.2 分类⽅⾯：五⼤类型负载均衡的原理场景详解

1.常见负载均衡的分类

通过前⾯跟⼤家介绍的常见负载均衡LVS、Nginx、HAProxy、阿

⾥云SLB及下⽂中将要讲到的硬件负载均衡等我们发现，不同的负载均

衡应⽤场景和功能上有很⼤区别，这取决于负载均衡底层的原理，原

理不同导致了不同负载均衡应⽤场景、功能、性能的巨⼤差异。但万

变不离其宗，这些常见负载均衡可以按照底层原理进⾏归类，相信通

过本节内容会让你有很⼤收获。

说到常见负载均衡的分类，我们先来看看什么是OSI七层模型。我

们常说的⼆层/三层/四层交换机，就是基于OSI七层模型所对应的层来

命名的。我刚开始接触⽹络设备的时候，第⼀次听说⼆层交换机、三

层交换机时，还以为交换机的硬件厚度有⼆层、有三层，后来才知

道，其实是按照OSI七层模型来区别不同交换机的原理功能。

OSI七层模型主要作为⼀个通⽤模型来做理论分析，它是⼀个理论

模型。⽽TCP/IP通信协议模型（四层）是互联⽹的实际通信协议，两

者⼀般做映射对⽐及分析，如表4-1所⽰。

表4-1 OSI七层模型及对应的传输协议

⽽常见的负载均衡有很多，有出名的硬件负载均衡，如F5、

Netscaler；还有常见开源的负载均衡，⽐如LVS、HAProxy、Nginx，

甚⾄Apache也能做负载均衡（不推荐）。我们常说的七层负载均衡、

四层负载均衡，也是基于OSI七层模型的。基于OSI七层模型的底层原

理，我们把常见的负载均衡具体划分为以下⼏个类型：⼆层、三层、

四层、七层。最后再加上⼀个除OSI七层模型以外的DNS（如表4-2所

⽰），通过DNS做负载均衡的场景也是⾮常常见的。

表4-2 负载均衡的分类

当前⼆层、三层负载均衡的实现只有LVS能做到。⽽相⽐在四层、

七层的负载均衡应⽤得要更为⼴泛，⽐如硬件负载均衡、Nginx、

HAProxy热门的中间件都⽀持四层、七层的负载均衡。

2.负载均衡开⼭⿐祖——LVS的⼯作原理

前⾯已介绍了LVS的应⽤场景及特性，但在介绍⼆层/三层/四层/七

层负载均衡对⽐之前，有必要说⼀下LVS的原理。在运维领域，相信⼤

家对LVS并不陌⽣，⼏乎提到负载均衡，提到运维，都会提到LVS。在

实际负载均衡实践应⽤中，我看到了⼀些有意思的现象，接下来跟⼤

家详细分享⼀下相关的技术实践。在此之前，先来看看负载均衡技术

相关术语缩写，如表4-3所⽰。

表4-3 负载均衡技术相关术语缩写

LVS负载均衡技术的实现，主要由IPVS和Ipvsadm实现。

·IPVS：是LVS集群系统的核⼼部分，是基于Linux Netfilter框架实

现的⼀个内核模块，主要⼯作于内核空间的INPUT链上。其钩⼦函数

分别HOOK在LOCAL_IN和FORWARD两个HOOK点，如图4-5所⽰。

需要特别注意的是，IPVS是直接作⽤在内核空间进⾏数据包的修

改及转发的。⽽Nginx/HAProxy作⽤在⽤户空间，这使得LVS的性能更

为强悍（能够赶上硬件负载均衡的性能），⽽Nginx/HAProxy根本不是

⼀个量级。并且现在IPVS已经是Linux内核标准的⼀部分，在早期的

Linux系统版本中，安装LVS还需要重新编译内核，当然现在已经不需

要了。

图4-5 内核LVS数据包流向

·Ipvsadm：⽽Ipvsadm是⼯作在⽤户空间，主要⽤于⽤户定义和管

理集群服务的⼯具。所以实际在安装配置LVS时，主要是安装配置

Ipvsadm。⽐如在Redhat中安装⼀条简单命令来实现：

yum install ipvsadm

LVS的原理架构如图4-6所⽰。

图4-6 LVS原理架构

在图4-6中，在Director Server上，IPVS虚拟出⼀个对外提供访问的

IP地址，⽤户必须通过这个虚拟的VIP地址访问服务器。由于LVS是采

⽤VIP（三层IP地址）作为请求⼊⼜的，这也是很多⼈喜欢把LVS统称

为IP负载均衡的原因，即也是三层负载均衡。但LVS有DR/IP TUN/NAT

3种模式，每种模式的核⼼原理分别作⽤在⼆层/三层/四层，所以把LVS

称为⼆层/三层/四层负载均衡更为恰当些。

图4-6中具体数据包的⾛向如下。

1）访问请求⾸先经过VIP到达负载调度器的内核空间。

2）PREROUTING链在接收到⽤户请求后，会判断⽬标IP，确定是

本机IP，将数据包发往INPUT链。

3）当⽤户请求到达INPUT时，IPVS会将⽤户请求和Ipvsadm定义

好的规则进⾏对⽐。如果⽤户请求的就是定义的集群服务，那么此时

IPVS会强⾏修改数据包，并将新的数据包发往POSTROUTING链。

4）POSTROUTING链接收数据包后发现⽬标IP地址刚好是⾃⼰的

后端服务器，最终将数据包发送给后端的服务器。

对于数据包的修改，基于修改⽅式的不同，形成了LVS的3种模

式，如表4-4所⽰。

表4-4 LVS三种模式

3.⼆层负载均衡

当前的负载均衡界，只有LVS实现了⼆层负载均衡。所以⼆层负载

均衡实践主要为LVS的DR模式实践（如图4-7所⽰）。

图4-7 ⼆层负载均衡数据包⾛向原理

以下是对⼆层负载均衡数据包⾛向原理的详细说明。

1）客户端请求数据包报⽂的源地址是CIP，⽬标地址是VIP。

2）负载均衡会将客户端请求数据包报⽂的源MAC地址改为⾃⼰

DIP的MAC地址，⽬标MAC改为了RIP的MAC地址，并将此包发送给

后端服务器。这⾥要求所有后端服务器和负载均衡所在服务器只能在

⼀个VLAN（局域⽹）⾥⾯，即不能跨VLAN。根据⼆层原理我们可以

看到，在后端服务器中能直接获取客户端的源IP地址，netstat-n能直接

查看客户端请求通信的源IP。⽰例代码如下：

># netstat -n

Active Internet connections (w/o servers)

Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 192.168.3.33:80 47.100.187.71:13537 ESTABLISHED

tcp 0 0 192.168.3.33:80 115.29.209.104:49435 ESTABLISHED

tcp 0 0 192.168.3.33:80 115.19.244.124:45418 TIME_WAIT

tcp 0 0 192.168.3.33:80 115.29.233.224:59310 ESTABLISHED

3）后端服务器发现请求数据包报⽂中的⽬的MAC是⾃⼰，会将数

据包报⽂接收下来。由于数据包的MAC地址被修改，因此后端服务器

需要在lo⽹⼜绑定VIP，这样数据包才会有“归属感”。处理完请求报⽂

后，将响应报⽂通过lo接⼜送给eth0⽹卡直接发送给客户端。由于数据

包由后端服务器直接返回给客户端，因此也会要求后端服务器必须绑

定公⽹IP。

4.三层负载均衡

同样，在当前负载均衡界，只有LVS实现了三层负载均衡。所以三

层负载均衡实践主要为LVS的IP-TUN模式实践（如图4-8所⽰）。

图4-8 三层负载均衡数据包⾛向原理

以下是对三层负载均衡数据包⾛向原理的详细说明。

1）客户端请求数据包报⽂的源地址是CIP，⽬标地址是VIP。

2）负载均衡将客户端请求数据包报⽂⾸部再封装⼀层IP报⽂，将

源地址改为DIP，⽬标地址改为RIP，并将此数据包发送给后端服务

器。与⼆层负载均衡不同的是，包通信通过TUNNEL模式实现，因此

不管是内⽹还是外⽹都能通信，所以不需要LVS VIP与后端服务器在同

⼀个⽹段内，即能跨VLAN。但三层负载均衡原理导致在后端服务器中

不能直接获取客户端的源IP地址，netstat-n能查看到的是和负载均衡的

通信IP。⽰例代码如下：

># netstat -n

Active Internet connections (w/o servers)

Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 192.168.3.33:80 172.16.2.2:13537 ESTABLISHED

tcp 0 0 192.168.3.33:80 172.16.2.2:49435 ESTABLISHED

tcp 0 0 192.168.3.33:80 172.16.2.2:45418 TIME_WAIT

tcp 0 0 192.168.3.33:80 172.16.2.2:59310 ESTABLISHED

云诀窍

TUNNEL模式⾛的隧道模式，运维起来⽐较困难，在实际应⽤中

不常⽤。

3）后端服务器收到请求报⽂后，会⾸先拆开第⼀层封装，然后发

现⾥⾯还有⼀层IP⾸部的⽬标地址是⾃⼰lo接⼜上的VIP，所以会处理

次请求报⽂，并将响应报⽂通过lo接⼜发送给eth0⽹卡直接发送给客户

端。

5.四层负载均衡

LVS的NAT模式、阿⾥云的四层SLB、Nginx/HAProxy的四层，虽

然都是四层负载均衡，但是它们的底层原理有很⼤差异，这就导致它

们的功能特性也有很⼤区别。

（1）LVS-NAT下的四层负载均衡

四层负载均衡LVS-NAT数据包⾛向原理如图4-9所⽰。

以下是对四层负载均衡LVS-NAT数据包⾛向原理的详细说明。

1）客户端请求数据包报⽂的源地址是CIP，⽬标地址是VIP。

2）负载均衡将客户端请求数据包报⽂的⽬标地址改为RIP地址，

并将此数据包发送给后端服务器。同样要求所有的后端服务器和负载

均衡所在服务器只能在⼀个VLAN（局域⽹）⾥⾯，即不能跨VLAN。

同样，根据LVS的NAT模式修改数据包报⽂的原理，在后端服务器中能

直接获取客户端的源IP地址，netstat-n能直接查看客户端请求通信的源

IP。

3）报⽂送到后端服务器后，⽬标服务器会响应该请求，并将响应

数据包报⽂返还给负载均衡。每台内部的后端服务器的⽹关地址必须

是负载均衡所在服务器的内⽹地址，即要配置SNAT，这样数据包才能

经过LVS返回给客户端。

4）然后负载均衡将此数据包报⽂的源地址修改为本机并发送给客

户端。

图4-9 四层负载均衡LVS-NAT数据包⾛向原理

云诀窍

我们可以看到，⽬标服务器处理完数据包返回给客户端的时候，

会经过LVS，然后再把数据包回给客户端。由此可以看到，LVS NAT模

式存在很⼤的性能瓶颈（就是在于LVS这⼀端），⽽相⽐于DR及IP-

TUN模式，数据包后端服务器直接返回给客户端就不存在这个问题。

在实际运⽤中，我也遇到过这个真实的性能瓶颈案例。之前⼯作过的

⼀家公司主要从事电商领域，在⼀年⼀度的双⼗⼀备战中，流量⾼峰

期客户端出现严重的卡顿、丢包和延时。当时负载均衡采⽤的就是LVS

的NAT模式，我们发现⾼并发⾼流量模式下，内⽹的流量可达到千

兆。那时紧急切换到LVS DR模式，故障很快消除了。

（2）阿⾥云SLB下的四层负载均衡

阿⾥云[1]四层负载均衡针对LVS的⼀些问题进⾏了定制和优化，新

增转发模式FULLNAT，如表4-5所⽰。

表4-5 阿⾥云四层负载均衡对LVS的优化

由此可见基于LVS，阿⾥云四层负载均衡实现了跨VLAN、具备防

DDoS攻击的能⼒、采⽤集群⽅式部署。这3个⽅⾯相⽐原⽣态的LVS，

功能上做了很⼤的改进。

云诀窍

实践应⽤中，我们发现使⽤阿⾥云的四层负载均衡，数据包的⾛

向跟后端的ECS有没有绑定公⽹IP有直接关系（仅限经典⽹络）。

·当后端ECS不绑定公⽹的时候，负载均衡转发数据包给后端

ECS。后端ECS处理完将返回数据包给负载均衡，负载均衡再返回数据

包给客户端。这种⽅式类似LVS的NAT模式。

·当后端经典⽹络的ECS绑定公⽹的时候（只有经典⽹络的ECS绑

定的公⽹IP会单独分配公⽹⽹卡eth1），负载均衡转发数据包给后端

ECS。后端ECS处理完将数据包直接通过公⽹⽹卡返回给客户端。这种

⽅式类似LVS的DR模式。在ECS的公⽹⽹卡监控中看不到这块的流量

明细，这块流量内容直接归并到SLB中计算了。但我们通过Zabbix相关

监控，可以看到eth1公⽹⽹卡流量，并能抓到相应明细。有时候实际公

⽹⽹卡流量甚⾄远远超过公⽹带宽峰值，由此可以看到，这部分返回

给客户端的数据包⾛公⽹⽹卡，不受后端ECS绑定的公⽹带宽限制，且

不纳⼊ECS的流量计费，单独放在SLB流量计费中了。

如果ECS有公⽹IP和私⽹IP，禁⽤公⽹⽹卡就会影响负载均衡服

务，因为在有公⽹⽹卡的情况下，默认路由会⾛公⽹，如禁⽤就⽆法

回包，因此负载均衡服务会受影响。建议不要禁⽌，如⼀定要这么

做，需要修改默认路由为私⽹才会不影响服务。但需要考虑业务是否

对公⽹有依赖，如通过公⽹访问RDS等。

（3）Nginx/HAProxy下的四层负载均衡

四层负载均衡Nginx/HAProxy数据包⾛向原理如图4-10所⽰。以下

是对四层负载均衡Nginx/HAProxy数据包⾛向原理的详细说明。

1）客户端请求数据包报⽂的源地址是CIP，访问⽬标地址是

DIP+IP端⼜。

图4-10 四层负载均衡Nginx/HAProxy数据包⾛向原理

云诀窍

需要重点注意的是，这⾥已经跟LVS有本质的区别。LVS的NAT模

式对外是以虚拟VIP作为请求⼊⼜（IP层为三层），然后在三层负载均

衡的基础之上⽤IP+PORT接收请求，再转发到对应后端服务器，所以

LVS的NAT模式是三层负载均衡+四层负载均衡。⽽Nginx/HAProxy的

四层对外直接暴露的是DIP+TCP/UDP IP端⼜服务。

2）负载均衡在⽤户空间接收数据包，并且负载均衡和后端服务器

发起新的TCP三次握⼿，建⽴新的TCP连接。所以这时候是负载均衡代

替客户端与后端发起新的TCP请求连接。请求数据包为⼀个新的请求数

据包，报⽂的源地址是DIP，⽬标地址是RIP。所以在后端服务器中，

netstat-n查看到的是和负载均衡的通信IP。但负载均衡和后端服务器是

建⽴新的TCP连接，所以后端服务器和负载均衡所在服务器可以进⾏跨

VLAN（局域⽹）通信。

3）报⽂发送到后端服务器后，服务器响应该请求，并将响应数据

包报⽂返还给负载均衡。相⽐LVS的NAT模式，Nginx/HAProxy下的四

层负载均衡⽆须将每台内部的后端服务器的⽹关地址设为负载均衡所

在服务器的内⽹地址，即⽆须配置SNAT。因为是负载均衡和后端服务

器建⽴了新的TCP连接，不必担⼼数据包不会返回给负载均衡。

4）然后负载均衡将此数据包报⽂的响应内容进⾏重新打包并返回

给客户端。

6.七层负载均衡

在常见负载均衡分类中，其实应⽤最为⼴泛的还是七层和四层负

载均衡。⽽七层和四层负载均衡最主要的区别是，在七层负载均衡中

能获取⽤户请求的HTTP头信息。具体什么是HTTP头信息，我们以

nginx.conf配置中定义的Nginx⽇志⽂件的格式内容从侧⾯进⾏说明：

log_format '$remote_addr - $remote_user [$time_local] "$request" '

'$status $body_bytes_sent "$http_referer" '

'"$http_user_agent" "$http_x_forwarded_for"'; 然后我们在对应的⽇志⽂件中可以看到具体客户端的请求头内容

信息，如下：

45.127.220.171 - - [02/Dec/2018:14:10:17 +0800] "GET https://qiaobangzhu.cn HTTP/1.1" 301 184 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36

(KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"

可以看到在七层负载均衡中，我们能获取客户端访问的IP、HTTP

请求类型（GET/POST）、访问的域名主机地址及请求的URL明细、浏

览器的类型等，这便是HTTP请求头信息。⽽七层负载均衡的原理就是

根据HTTP请求头来做判断转发，在七层负载均衡中应⽤最为⼴泛的当

数虚拟主机功能。其实虚拟主机功能的核⼼就是获取HTTP请求头中的

HOST字段来对应匹配转发。七层负载均衡原理架构图如图4-11所⽰。

图4-11 七层负载均衡数据包⾛向原理

以下是对七层负载均衡数据包⾛向原理的详细说明。

1）和Nginx/HAProxy的四层⼀样，客户端请求数据包报⽂的源地

址是CIP。只不过在实际应⽤中，这⾥访问的⽬标地址并不是DIP+IP端

⼜，⽽是URL。

2）同样和Nginx/HAProxy的四层⼀样，负载均衡在⽤户空间接收

数据包，并且负载均衡和后端服务器发起新的TCP三次握⼿，建⽴新的

TCP连接。所以这时候是负载均衡代替客户端与后端发起新的TCP请求

连接。请求数据包是新的，报⽂的源地址是DIP，⽬标地址是RIP，并

且还有客户端请求的⽬标URL（这⾥可以看到，对于七层负载均衡，

⽬标地址可能⼀直在变，但访问的⽬标URL始终不变，除⾮修改了客

户端请求内容）。

3）报⽂送到后端服务器后，服务器响应该请求，并将响应数据包

报⽂返还给负载均衡。跟Nginx/HAProxy⼀样，这⾥⽆须额外配置后端

服务器的⽹关，即SNAT相关配置。

4）然后负载均衡将此数据包报⽂的响应内容进⾏重新打包并返回

给客户端。

综上所述，因为七层中能获取应⽤层HTTP的请求内容，所以七层

负载均衡有如下常见应⽤场景：

·七层作⽤在HTTP应⽤层，所以七层的负载均衡只能跟Tomcat、

PHP等Web服务做负载均衡。

·可以根据请求的域名来做转发。⽐如请求者访问A域名，转发到

后端A服务器；请求访问B域名，转发到后端B服务器。这个功能，在

七层叫虚拟主机功能，是七层应⽤中最为热门的应⽤实践。

·可以根据请求的URL来做转发。⽐如请求者访问的URL包含A⽬

录，就转发到A服务器；请求访问的URL包含B⽬录，就转发到B服务

器。

·可以根据请求的浏览器类型来做转发。⽐如请求者使⽤的浏览器

类型是Chrome，就转发到A服务器；请求者使⽤的浏览器类型是

Firefox，就转发到B服务器。

⽽四层只能获取访问的⽬标/源IP地址和端⼜。所以四层的负载均

衡，单纯地是将请求轮询转发到后端⽬标服务器。并不能跟七层⼀

样，做相应的逻辑判断，然后最终再转发给符合要求的后端⽬标服务

器。相⽐七层，四层的应⽤场景包括：

·对MySQL、LDAP、Redis、Memcache等四层应⽤做负载均衡。

·对七层HTTP的Web类应⽤做负载均衡，如Tomcat、PHP。

·对七层Nginx、HAProxy的负载均衡做负载均衡（具体在实践中，

四层和七层怎么来搭配使⽤，详见第⼆篇中负载均衡的相关章节）。

但四层中没办法跟七层⼀样，做虚拟主机的应⽤。我曾经在⾯试

中问过这个问题，就是LVS能不能识别域名来做转发。⽐如请求者访问

A域名，转发到后端A服务器；请求访问B域名，转发到后端B服务器。

有意思的是，有⼀些经验丰富的运维⼈员对这个问题还回答不出来，

这就需要好好看⼀下底层原理和对应负载均衡的应⽤场景了。答案肯

定是不⾏的，因为LVS在四层和⼆层，没办法识别封装在七层中的数据

包内容。

再举个七层负载均衡实践的例⼦，要访问我们驻云内部的某个系

统，要求客户端必须使⽤Chrome浏览器，可参考以下核⼼配置：

location / {

if ( $http_user_agent !~* ^.*Chrome/5|6.* ){

rewrite ^(.*)$ https://qiaobangzhu.cn/error.html permanent;

}

proxy_pass http://192.168.2.2:81/;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

实现的核⼼配置就是获取七层头信息⾥⾯的数据来做对⽐判断，

如果符合，执⾏对应的操作即可。这个是四层/⼆层负载均衡⽆法实现

的功能。

7.负载均衡的“⼀次连接”和“两次连接”核⼼总结

（1）LVS⼆层/四层的“⼀次连接”

LVS的DR模式、NAT模式对数据包的处理都仅做“⼀次连接”，即

负载均衡对数据包仅做转发，如图4-12所⽰。

图4-12 LVS的三次握⼿数据包⾛向

LVS能够做到“⼀次连接”的本质原因是LVS⼯作在内核空间。LVS

3种模式都是⼯作在内核空间，数据包的处理也仅在内核空间，这也是

LVS轻量⾼效、⾼性能的最为本质的原因，如图4-13所⽰。

云诀窍

LVS能够做到“⼀次连接”，所以通过四层SLB，我们能直接在后端

服务器ECS中netstat-n查看到客户端通信的源IP地址。

图4-13 LVS请求数据包⾛向

（2）Nginx/HAProxy四层的“⼆次连接”

相⽐于LVS，Nginx/HAProxy四层要建⽴“⼆次连接”，如图4-14所

⽰。

图4-14 Nginx/HAProxy四层三次握⼿数据包⾛向

客户端在向负载均衡进⾏TCP三次握⼿后，负载均衡会马上发起新

的TCP连接，即为“⼆次连接”。由于是负载均衡与后端建⽴新的TCP三

次握⼿及转发客户端请求的数据，所以在后端服务器netstat-n查看到的

请求通信的IP是负载均衡的IP。⽽相⽐于LVS，Nginx/HAProxy四层⼯

作在⽤户空间，对数据包的处理是在⽤户空间完成的，数据包的流转

及处理过程增多，这也是Nginx/HAProxy的性能和达不到LVS这个量级

的本质原因，如图4-15所⽰。

图4-15 Nginx/HAProxy请求数据包⾛向

（3）Nginx/HAProxy七层的“⼆次连接”

相⽐于Nginx/HAProxy四层的⼆次连接，⽽Nginx/HAProxy七层的

⼆次连接有些不⼀样，如图4-16所⽰。

Nginx/HAProxy四层的⼆次连接，是客户端和负载均衡进⾏TCP三

次握⼿后，负载均衡和后端服务器马上进⾏新的TCP三次握⼿。⽽

Nginx/HAProxy七层的⼆次连接，在客户端和负载均衡进⾏TCP三次握

⼿后，还需要等客户端Pushdata传输数据，之后负载均衡和后端服务器

才会建⽴新的TCP三次握⼿。由此可见，Nginx/HAProxy四层的⼆次连

接转发效率会更⾼。加上Nginx/HAProxy七层会进⾏⼀些Rewrite规则的

判断，会损耗⼀些CPU和内存的性能。所以相较⽽⾔，Nginx/HAProxy

四层的性能要⾼许多。

同样，由于是负载均衡跟后端建⽴新的TCP三次握⼿及转发客户端

请求的数据，所以在后端服务器netstat-n查看到的请求通信的IP是负载

均衡的IP。所以在后端服务器中，HTTP头的remote_addr虽然代表客户

端的IP，但实际值是负载均衡的IP。为了避免这个情况，七层负载均衡

通常会增加⼀个叫作x_forwarded_for的头信息，把连接它的客户端

IP（上⽹机器IP）加到这个头信息⾥，这样就能保障后端服务器可以获

取到客户端真实的IP。

但实际上，我们会遇到后端服务器再把请求转发给到下⼀个⽬标

服务器的情况，即：“客户端请求>>>Nginx>>>Nginx1>>>Nginx2”的结

构，我们在Nginx1服务器上通过x_forwarded_for的头信息获取到了客户

端的真实源IP，那如何在Nginx2上进⼀步获取客户端的源IP呢？在

Nginx1上的转发规则中，配置如下代码：

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 这样会让Nginx1转发给后端HTTP头中的x_forwarded_for信息中保

存客户的真实源IP。

图4-16 Nginx/HAProxy七层三次握⼿数据包⾛向

云诀窍

Nginx七层能够进⾏“⼆次连接”，所以通过七层SLB，我们在后端

服务器ECS中netstat-n查看到和后端服务器通信的IP为SLB的IP地址，

⽽不能直接获取客户端通信的源IP。

8.DNS负载均衡

从OSI七层模型来看，DNS的域名解析其实作⽤在第七层应⽤层。

数据包请求时序图如图4-17所⽰。

图4-17 DNS请求流向

在图4-17中，本质上DNS的负载均衡还算不上七层负载均衡，因为

DNS解析是在TCP/IP通信之前进⾏的。即如果在应⽤中⽤到了域名，

需要先去请求DNS服务器获得⽬标IP地址，才能建⽴TCP/IP通信。相

较于应⽤⼴泛的四层和七层的负载均衡，DNS做负载均衡的场景就没

那么常见了。

DNS做负载均衡会带来两个很⼤的问题，两个问题分别如下：

1）实践中，通过DNS解析配置多个A记录地址。不同的客户端来

请求DNS，返回A记录配置的不同的源IP（也可以是负载均衡的VIP地

址），从⽽达到负载均衡的效果。但我们发现，设置DNS的负载均

衡，落到不同源IP（也可以是负载均衡的VIP地址）的请求流量往往分

布得很不均匀。有可能是某个后端地址的请求量很⼤，⽽另⼀个后端

地址的请求量却很⼩。

2）由于客户端往往有DNS相应缓存，如若DNS解析的某个源IP服

务异常，⼀般它不会主动剔除这个有异常的源IP解析。这可能会导致

部分客户的解析访问还是这个有异常的服务地址。虽然现在DNS有智

能解析的⾼级功能，能主动监测后端服务的可⽤性。但是我们唯⼀不

能把控的就是客户端的DNS缓存，⼤部分客户端的电脑DNS都有缓

存。有可能是DNS已经解析到最新的IP，但这时候客户端的DNS缓存

还是会获取解析到的旧的IP，这会导致这个客户端可能⼀段时间内⼀

直解析访问到那个有异常服务的IP。

DNS的负载均衡，⼀般在超⼤规模的应⽤中，特别是跨地域的分

布式应⽤中运⽤得⾮常⼴泛，常规的中⼩型、中⼤型应⽤，不是特别

推荐尝试DNS的负载均衡。DNS作为负载均衡的应⽤场景将会在第⼆

篇中详细介绍。

9.总结

不同负载均衡的类型的功能特性汇总如表4-6所⽰。

表4-6 不同类型负载均衡的功能特性总结

[1] 阿⾥云LVS开源地址：https://github.com/alibaba/LVS

4.3.3 演变⽅⾯：负载均衡的两种演变

很多⼈容易把负载均衡和反向代理混淆。从某种程度上来说，反

向代理是负载均衡的演变应⽤。

1.演变⼀：反向代理

在实际应⽤中，Nginx/HAProxy七层/四层应⽤除了叫作负载均衡

以外，⼈们也喜欢叫它反向代理。但很少有⼈会把LVS称为反向代理，

因为LVS是单纯的负载均衡。

之所以把Nginx/HAProxy七层/四层应⽤称为负载均衡，是因为七

层/四层都带有proxy模块，能对请求流量做分流转发，起到负载均衡的

效果。

之所以把Nginx/HAProxy七层/四层也称为反向代理，是因为

Nginx/HAProxy的七层/四层应⽤有如下特性。

1）在转发客户端请求的过程中建⽴了“两次连接”。在接受了客户

端请求后会将请求重新封装，以类似“代理”的⾓⾊重新将其转发给后

端。

2）与后端服务器能进⾏跨VLAN传输，甚⾄可以基于Internet进⾏

传输。这⾥的特殊性是在南北互通的问题上，南北互通在反向代理中

应⽤得⾮常⼴泛。何为南北互通？此概念是从国内电信和⽹通分开之

后出现的，即南⽅电信与北⽅联通线路之间的⽹络互通问题。这个问

题困扰了中国⽹民很长时间，严重困扰着⼴⼤站长和⽹络内容、服务

提供商。我曾⼯作的上家公司的电商业务主要部署在上海电信双线机

房，北⽅有些联通⽤户来访问站点时就很卡。当时的核⼼解决⽅案就

是通过反向代理来实现，如图4-18所⽰。

图4-18 反向代理的实践应⽤

图4-18中，在深圳联通机房的⼀台服务器上部署了Nginx作为反向

代理服务器。⼴东地域相关联通客户访问这台深圳代理服务器的速度

肯定能得到保障，同时深圳联通这台机器⽹络由于直接在主⼲线路

上，所以访问上海电信机房的速度也能⼀定程度上得到了保障。针对

深圳地域访问时有⽹络问题的客户，在本地HOST中将域名解析强制解

析绑定指向深圳代理服务器。这样请求都会⾛向代理服务器，从某种

程度上有效提升了访问速度。Nginx反向代理的核⼼配置如下：

server {

listen 80;

server_name qiaobangzhu.cn;

index index.html index.htm;

location / {

proxy_pass http://qiaobangzhu.cn/;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

}

此外，需要在代理服务器上，在HOST中配置强制将

qiaobangzhu.cn的IP解析⾄上海电信机房的源IP。这样在深圳的客户访

问Nginx反向代理服务器时，能及时将请求转发⾄最终⽬标服务器。

之所以把LVS称为负载均衡⽽不是反向代理，是因为LVS的以下特

性：

·在转发客户端请求的过程中，只建⽴了“⼀次连接”，对客户端请

求数据包只做纯转发。

·与后端服务器只能在⼀个VLAN中，不能跨VLAN。

由以上两点可以看到，LVS单纯只做分流转发，只具备负载均衡的

功能。

2.演变⼆：正向代理

既然说到反向代理，还有个正向代理不可不知，它也是七层的应

⽤场景。正向代理和反向代理的应⽤场景与SNAT和DNAT很类似，主

要是底层原理不⼀样。

反向代理与DNAT：DNAT主要来做端⼜映射，LVS四层的负载均

衡和四层的DNAT，就如同七层的负载均衡和七层的反向代理。当访问

⽬标服务器的80端⼜时，会在内核层修改⽬标IP和端⼜并转发给到后

端服务器。如果后端仅有⼀台服务器，这时候我们称之为DNAT（端⼜

映射）；但如果后端有多台服务器，就称之为负载均衡。DNAT和反向

代理在实际运⽤中也是应⽤得⾮常⼴泛的。⽐如，想在家⾥远程登录

公司内⽹的⼀台电脑，那么可以在路由器上设置端⼜映射，我们只需

要访问公司固定公⽹IP+对应端⼜，即可访问公司内部的电脑。在云端

则可以设置对应DNAT来访问后端某台内⽹ECS上的端⼜应⽤。相⽐于

DNAT，反向代理在云端应⽤得更加⼴泛。⼏乎所有的Web类应⽤都会

在ECS前⾯挂上七层SLB（具体实践见第⼆篇中的负载均衡相关章

节）。

正向代理与SNAT：可以通过⼀台有公⽹的代理机将⼏台内⽹机器

对公⽹的请求转发出来，实现内⽹机器对公⽹的访问。这是正向代理

和SNAT的核⼼功能，只不过正向代理主要是七层的HTTP代理。即⼀

般我们要在客户端的浏览器中主动设置代理IP，且只能通过代理访问

Web⽹站。⽐如，我们想发个邮件或登录客户端QQ是不⾏的，⽽SNAT

⼀般会将客户端中的⽹关配置为代理服务器的IP。这时不仅能访问Web

⽹站应⽤，其他互联⽹的应⽤访问都没问题。所以可以看到，SNAT在

企业级应⽤中⾮常普遍，基本上在公司内⽹⽹络（有个独⽴IP）都是

通过SNAT⽅式共享上⽹的。在云端实践中，为了安全性，我们不可能

给每台服务器都开公⽹，所以SNAT在云端的应⽤也是⾮常⼴泛的。但

正向代理在云端很少应⽤。⼀般在内部企业中，限制员⼯只能访问特

定⽹页的时候应⽤。

正向代理和反向代理的具体区别如图4-19、图4-20所⽰。

图4-19 正向代理请求架构

图4-20 反向代理请求架构

正向代理中，Proxy和Client同属于⼀个LAN，对Server透明，需要

客户端主动配置代理IP和端⼜。⽽在反向代理中，Proxy和Server同属

于⼀个LAN，对Client透明，不需要客户端进⾏配置。实际上，对⽐正

向代理和反向代理中的Proxy，其所做的事情都是⼀样的，都是代为转

发请求和响应。

4.3.4 性能⽅⾯：负载均衡隐藏的性能秘密

负载均衡的应⽤所能承受的性能是决定我们选择使⽤什么样量级

性能的负载均衡⾮常重要的因素。在云端Web服务器选型的部分也跟⼤

家介绍了⼀个采⽤Apache做负载均衡的失败案例，其失败原因，⼀⽅

⾯是我当时刚参加⼯作，经验较少，正好看到Apache有这⽅⾯功能就

⽤了。另⼀⽅⾯，本质上来说还是我对负载均衡底层原理、性能⽅⾯

掌握不⾜。在负载均衡的分类部分已跟⼤家详细介绍了不同负载均衡

的底层原理，并进⾏了对⽐，相信⼤家已对不同类型的负载均衡性能

有了⼀定的概念。

关于负载均衡的性能，这也是我在⾯试过程中经常问到的问题。

Tomcat、Apache、Nginx、LVS的抗并发能⼒在⼀个什么级别，⽐如千

级别、万级别、⼏⼗万级别？实际上，90%的⼈对这个问题并不了解。

通过实践应⽤汇总的常⽤Web中间件及软件负载均衡的抗并发能⼒级别

如表4-7所⽰。

表4-7 负载均衡的性能对⽐

⽆可厚⾮的是，硬件负载均衡在抗并发能⼒及稳定性⽅⾯是最强

的。虽然它的性能是最好的但同时也是最贵的，售价⼏万元到⼏⼗万

元不等。

LVS⼯作在内核空间，⽤于处理客户端请求仅“⼀次连接”，单纯进

⾏⽹络数据包流量转发，对CPU和内存消耗极低，基本上抗并发的能

⼒取决于具体的⽹络带宽，其性能基本上跟硬件负载均衡媲美。

⽽Nginx/HAProxy⼯作在⽤户空间，⽤于处理客户端请求需要“⼆

次连接”，并且对CPU及内存有性能要求。相较⽽⾔，LVS在内核层对

性能的要求极低，与Nginx/HAProxy根本不是⼀个层次。

Nginx/HAProxy的四层相⽐于Nginx/HAProxy的七层，转发效率更

⾼，也没有七层Rewrite等复杂逻辑处理，所以性能上更胜⼀筹。

虽然都说Nginx是个轻量级，但对性能消耗很低，这仅仅是相⽐于

Apache、IIS、Tomcat、PHP等Web服务器及中间件⽽⾔。在LVS⾯前，

⾯对⼏⼗万的⾼流量并发，Nginx/HAProxy全⽆法承载。

⽽IIS、Apache、Tomcat服务器都是Web服务器，底层基于Select⽹

络模型，擅长进⾏逻辑处理，适合处理Web类请求应⽤，不适合⾼并发

场景，基本上极限并发能⼒在千这个量级别。⽽Nginx/HAProxy底层基

于Epoll⽹络模型，擅长进⾏⽹络流量转发及I/O处理，所以适合⾼并发

场景。Tomcat是⼀个轻量级的Java容器，默认不配置优化，能⽀持百以

内的并发连接。优化了Tomcat的配置⽂件server.xml，Tomcat能⽀持1k

左右的并发连接。Tomcat以单程多线程的模式来应对客户端请求，相

⽐于多进程的PHP，抗并发能⼒弱。所以在实际运⽤中，我们会选择中

低配的服务器来跑Tomcat（推荐选择4核8G），因为中⾼配的服务器配

置，跑单台Tomcat太浪费服务器性能配置，除⾮在中⾼配的服务器中

部署多个Tomcat（服务器配置相关内容会在第5章中进⾏详细介绍）。

4.3.5 选型⽅⾯：云端负载均衡的两种选型

在云端实践中，对负载均衡的选择肯定优先采⽤阿⾥云SLB（“云

产品的8/2选择原则”）。在具体实际应⽤中，若对七层有Rewrite的需

求，或者对四层有更多调度算法等的需求，这时候SLB的功能暂时达不

到要求，可能需要在ECS上搭建Nginx/HAProxy四层/七层负载均衡。但

在云端实践中，SLB的四层/七层基本上满⾜⽇常80%的需求。所以云

端负载均衡的选型，基本上也就是云端负载均衡SLB的选型。那么，什

么时候选择七层、什么时候选择四层呢？如表4-8所⽰。

表4-8 SLB的两种类型选择场景

在TCP类服务中，对于负载均衡，我们只能选择四层负载均衡。

在HTTP类的Web服务中，既能选择四层也能选择七层。这⾥选型

的区别如下：

如果需要虚拟主机的七层负载均衡（SLB中叫虚拟服务器组），我

们只能选择七层负载均衡。但这部分需求在七层负载均衡使⽤场景中

只占⽐20%。事实上，在80%的企业级HTTP负载均衡应⽤中，只有单

纯转发的功能，没有对虚拟主机的转发需求。所以这⾥优先选择的不

是七层，⽽是四层（相关内容将在第7章中进⾏详细介绍）。因为四层

在性能⽅⾯更加强悍，在应⽤⼊⼜采⽤四层负载均衡进⾏分流是标准

且成熟的企业级架构。

如果需要前端SLB挂证书SSL，也就是HTTPS，那么只能选择七层

负载均衡。但这种架构在电商⾼流量⾼并发的场景下也会出现⼒不从

⼼的性能问题，还是建议前端采⽤四层负载均衡，证书放在后端ECS中

的Nginx进⾏配置。但是在常规的中⼩型Web应⽤中，这⽅⾯的性能等

是完全没问题的。

4.4 云端存储的四种类型

在云端有很多存储类云产品，最为常见的就是云盘、OSS、

RDS，还有NAS、共享块存储等相应存储类产品。相应存储类的云产

品本质上还是为了解决数据持久化的问题，所以需要⽤到存储类的产

品。存储的数据结构类型也决定了我们选择什么样类型的存储类产

品。数据的结构类型⼀般有以下3种。

·结构化数据：类似包含预定义的数据类型、格式和结构的数据，

常见的如关系型数据库中的数据表⾥的数据。

·半结构化数据：具有可识别的模式并且可以解析的⽂本数据⽂

件，⽐如XML数据⽂件、JSON数据⽂件。

·⾮结构化数据：顾名思义，没有固定结构的数据。通常为不同类

型的⽂件，⽐如⽂本⽂档、图⽚、视频、⽇志⽂件、代码⽂件等。

根据以上3种数据结构，云端存储的产品类型主要分为以下两⼤

类：

·数据库类云产品（主要为云RDS、云MongoDB、云Redis、云

Memcache）主要⽤于解决结构化数据及半结构化数据的持久化存储的

问题。

·块存储（云盘）、共享块存储（共享云盘）、共享⽂件存储、

OSS对象存储主要⽤于解决⾮结构化数据的持久化存储的问题。

数据库选型的内容后⾯会详细介绍，下⾯主要介绍⾮结构化数据

的持久化存储，以及选择块存储（云盘）、共享块存储（共享云

盘）、共享⽂件存储、OSS对象存储的对应场景。

4.4.1 类型⼀：块存储

块存储是阿⾥云为云服务器ECS提供的块设备（云盘），⾼性能、

低时延，满⾜随机读写，您可以像使⽤物理硬盘⼀样格式化并建⽴⽂

件系统来使⽤块存储。

云盘主要解决⾮结构化数据持久化存储的问题，在云端云盘主要

分为系统盘和数据盘两种类型，这决定了云盘存储数据的应⽤场景：

·系统盘主要存储操作系统所要运⾏的⽂件及⽇志。

·数据盘可以存储Java/PHP/Python等代码⽂件，也可以存储图⽚、

⾳视频、⽇志等⽂件。

云盘在云端的应⽤⽅⾯，⼀般⼤家最为关⼼的话题有如下两个。

1.云盘的备份

云盘的三副本技术（底层基于⽹络存储的分布式⽂件系统）能保

障数据的⾼可靠性。数据在同⼀地域不同可⽤区（不同机房）多份存

储冗余，不⽤担⼼底层由于物理硬件的问题⽽丢失数据，并且基于底

层多副本冗余，云盘还提供了快照、镜像（主要针对系统盘）的备

份，这让磁盘的备份更加⽅便灵活。底层的多副本冗余+快照/镜像的备

份，基本上满⾜了企业级对磁盘数据备份的绝⼤多数需求。⾄于怎么

基于云盘来进⾏进⼀步的应⽤层⽅⾯的数据备份，将会在第⼆篇中进

⾏详细介绍。

2.云盘的性能

早期，阿⾥云底层虚拟化基于XEN，同时⽀持5000台物理机集

群。但由于底层XEN技术的限制，虚拟出的ECS在I/O隔离、I/O性能等

⽅⾯都很差。80%⽤户都表⽰I/O性能太低，甚⾄速度还没有⾃⼰的U

盘快。对于最原始的普通云盘类型，I/O确实⽆法得到保障。

云诀窍

我们在做普通云盘性能压测的时候，发现普通云盘的I/O低主要体

现在磁盘写⼊I/O⽅⾯，其实数据的读取速度基本上能满⾜需求。

官⽅为了解决这⼀问题，折中推出了本地磁盘类型的云盘产品。

即基于ECS云服务器所在物理机（宿主机）的本地硬盘设备，其底层仅

采⽤RAID10来保障数据可靠性。由于本地磁盘其实就是物理磁盘，没

有云平台的⾼可靠性的特点，某种程度上来说，这款产品的推出就是

在⾛传统VPS虚拟机的套路。由于整个飞天系统底层技术架构的限制，

只能以此来满⾜绝⼤部分⽤户对I/O的诉求。

云诀窍

云端本地磁盘推出的时候，我们也做了性能压测。主要是因为有

⽤户希望在云端部署Oracle，但又对云盘的I/O性能⽐较担⼼。当初ECS

还只能挂载4个数据盘，我们100GB×4块本地磁盘+LVM虚拟出⼀块逻

辑卷给Oracle做data⽬录，并进⾏了Oracle数据同时写⼊、删除、更

改、查询的模拟压测，Oracle的IOPS性能能达到5万左右。这时候服务

器负载已经很⼤了，不过总体来说性能压测结果还⽐较不错的。

随着KVM的推出，当前阿⾥云基于KVM⾃主研发的飞天系统已经

⽀持两万台物理机进⾏集群。在磁盘I/O上，推出⾼效云盘、SSD云

盘，彻底解决了之前云盘I/O低的问题，并且成为当前云盘默认的主流

标配产品。

云盘的性能对⽐汇总如表4-9所⽰。

表4-9 物理盘与云盘的性能对⽐

不同云盘的单路随机写访问时延如下：

·ESSD云盘：0.1～0.2ms；

·SSD云盘：0.5～2ms；

·⾼效云盘：1～3ms；

·普通云盘：5～10ms。

4.4.2 类型⼆：共享块存储

ECS共享块存储是⼀种⽀持多台ECS实例并发读写访问的数据块

级存储设备，即常规云盘只⽀持同时挂载在⼀台ECS上，但共享块存

储⽀持同时挂载在多台ECS上。共享块存储产品专为企业级客户的核

⼼业务⾼可⽤架构⽽设计，主要是为了解决Shared-Everything架构下

对块存储设备的共享访问场景，⽐如政府、企业和⾦融⾏业常⽤的

Oracle RAC数据库⾼可⽤架构、服务器High-Availability Cluster的⾼可

⽤架构等，其应⽤场景⽐较单⼀。

共享块存储产品本⾝并不提供集群⽂件系统，需要⾃⾏安装集群

⽂件系统来管理共享块存储。如果只是将共享块存储挂载到多台ECS

实例，依旧使⽤常规⽂件系统来管理时，会造成磁盘空间分配冲突和

数据⽂件不⼀致两个问题。具体如下：

（1）磁盘空间分配冲突

如果⼀块共享块存储挂载到多个实例上，当实例A写⽂件时，会

查询⽂件系统和可⽤的磁盘空间，⽂件写⼊后会修改实例A上的空间

分配记录，但不会修改其他实例的记录。因此，当实例B写⼊⽂件

时，可能会对实例A已经分配出去的磁盘空间进⾏再次分配，造成磁

盘空间分配冲突。

（2）数据⽂件不⼀致

当实例A读取数据并将其记录在缓存中时，实例A上另⼀个进程来

访问同样的数据就会直接从缓存中进⾏读取。但如果此时实例B修改

了该数据，⽽实例A并不知道，其依旧会从缓存中读取数据，从⽽造

成业务数据不⼀致。

正确使⽤共享块存储的⽅式是采⽤集群⽂件系统进⾏块设备的统

⼀管理，如GFS、GPFS等。典型的Oracle RAC业务场景中推荐采⽤

ASM统⼀管理存储卷和⽂件系统。

4.4.3 类型三：共享⽂件存储

云端Linux系统下的NFS（Network File System）服务，Windows系

统下的SMB（Server Message Block）服务，以及阿⾥云⽂件存储

NAS（Network Attached Storage）产品，都是共享⽂件存储，也叫共

享⽂件系统存储。相⽐于共享块存储，共享⽂件存储的应⽤场景就⾮

常⼴泛了，它们有以下共同特点：

·共享访问：允许⽹络中的计算机之间通过TCP/IP⽹络共享资源，

在共享⽂件存储的应⽤中，本地客户端应⽤可以透明地读写位于远端

服务器上的⽂件，就像访问本地⽂件⼀样。相⽐于共享块存储，共享

⽂件存储是基于⽹络+⽂件系统级别的共享。⽽共享块存储是基于⽹

络+块存储级别的共享，类似磁盘ISCSI技术。虽然实现效果都是共

享，但本质原理有所不同。

·强⼀致性：即任何对⽂件的修改成功返回后，后续的访问会⽴即

看到该修改的最终结果。这是和共享块存储最⼤的不同，共享块存储

需要通过集群⽂件系统保障数据读写的强⼀致性。

在云端使⽤共享⽂件存储（NFS/SMB/NAS）的典型应⽤场景如

下：

·负载均衡中的典型场景：使⽤负载均衡+多台ECS（如Web服务

器）部署的业务。多台ECS需要访问同⼀个存储空间，以便多台ECS

共享数据。

·代码共享场景：多台ECS应⽤，部署的代码⼀致。我们可以将代

码放在同⼀个存储空间，提供给多台ECS同时访问。代码的集中管理

也极⼤地节省了维护管理成本。

·⽇志共享场景：多台ECS应⽤，需要将⽇志写到同⼀个存储空

间，以⽅便做集中的⽇志数据处理与分析。

·企业办公⽂件共享场景：企业有公共的⽂件需要共享给多组业务

使⽤，需要集中的共享存储来存放数据。类似FTP的应⽤场景，只不

过FTP⾯向公司员⼯间共享。

·容器服务的场景：部署的容器服务需要共享访问某个⽂件数据

源，特别是在资源编排的容器服务。对应的容器可能会在不同服务器

中进⾏服务漂移，所以⽂件共享访问尤为重要。

·备份的场景：⽤户希望将线下机房的数据备份到云上，我们可以

通过跨地域远程挂载⽂件系统来存储数据备份。只不过这⾥需要借助

VPN⽹关或者NAT⽹关的技术，将IDC和云端⽹络打通或者进⾏映

射。具体实践可参考第8章中的内容。

在云端的NAS产品出来之前，我们⼀直是在Linux下⾃⾏搭建NFS

服务来满⾜对共享⽂件存储的需求。虽然在ECS中搭建NFS服务是⾮

常容易的，只需要简单的⼏⾏配置，但有⼀个始终困扰着我们的问

题，那就是⾼可⽤的问题，即只要NFS Server⼀宕机，那么所有NFS

Agent都没办法读取共享的⽂件。在传统的IDC应⽤中，可以采⽤

DRBD（Distributed Replicated Block Device分布式复制块设备）

+NFS+Keeplived技术来保障NFS的⾼可⽤，避免单点故障。但由于保

障NFS⾼可⽤的技术较为复杂和烦琐，且实现成本较⾼，所以基本上

使⽤NFS时都不会额外采⽤⾼可⽤⽅案（算是使⽤NFS默认的规

则）。再加上云端不⽀持虚拟VIP的技术，⾃然也不⽀持Keeplived，

这就导致云端⾃建NFS的⾼可⽤不能通过技术⼿段得到保障。但云端

NAS产品的出现彻底解决了传统⾃建NFS服务的这个问题。虽然产品

刚刚出来，NAS的I/O性能确实不尽如⼈意。但其具有的特性，免去

NFS服务的⾃建维护，我们相信，随着后续产品的优化，NAS的I/O性

能也会逐步得到改善，这使得我们在云端共享⽂件存储中将其作为默

认的选择。

4.4.4 类型四：对象存储

与块存储和⽂件存储管理数据的⽅式不同，对象存储是以对象的

形式管理数据的。对象和⽂件最⼤的不同就是在⽂件的基础之上增加

了元数据。⼀般情况下，对象分为3个部分：数据、元数据以及对象

ID。对象的数据通常是⽆结构的数据，⽐如图⽚、视频或⽂档等；对

象的元数据则指的是对象的相关描述，⽐如图⽚的⼤⼩、⽂档的拥有

者等；对象ID则是⼀个全局的唯⼀标识符，是⽤来区分对象的。

在实际应⽤中，分布式⽂件系统实现了对象存储，如常见分布式

⽂件系统GFS（Google File System）、MFS（MooseFS）、

HDFS（Hadoop分布式⽂件系统）、TFS（Taobao File System）等。阿

⾥云对象存储服务（Object Storage Service，OSS）底层就是基于淘宝

的开源分布式系统TFS。

相⽐于块存储和⽂件存储，使⽤对象存储（分布式⽂件系统）访

问数据有很⼤不同。它可以通过RESTful API接⼜对对象进⾏访问操

作，并且可以⽤HTTP动词（GET、POST、PUT、DELETE等）描述

操作。虽然在云端提供了OSSCMD/OSSUTIL等⼀系列的⼯具，⽅便⽤

户快捷地操作OSS中存储的数据，但这些⼯具本质上还是基于分布式

⽂件系统的RESTful API接⼜的，并不能像块存储、⽂件存储访问本地

磁盘数据那么⽅便。

所以我们可以看到分布式⽂件系统有如下应⽤特点：

·对象存储主要应对的是海量数据存储，不必担⼼存储容量空间的

问题，并且能应对⾼并发的场景。⽽块存储和⽂件存储都存在容量空

间扩容的问题，因此在⾼并发场景下性能较差，所以可以看到对象存

储偏向⼤型应⽤。

·由于对象存储是通过RESTful API接⼜对对象进⾏访问操作的，

所以需要通过编码来实现，才能把对象存储引⼊业务系统中。这会造

成较⼤的编码成本，建议慎⽤。在中⼩型规模的应⽤中，不推荐使

⽤。

阿⾥云对象存储OSS虽然底层也是基于分布式⽂件系统的，但是

定制了许多功能特性。其结合OSSCMD/OSSUTIL等⼀系列⼯具，进⼀

步降低了OSS的使⽤门槛。这使得OSS相⽐传统分布式⽂件系统的应

⽤场景更加⼴泛，主要使⽤场景如下：

·图⽚和⾳视频等应⽤的海量存储：OSS可⽤于图⽚、⾳视频、⽇

志等海量⽂件的存储。各种终端设备、Web⽹站程序、移动应⽤可以

直接向OSS中写⼊或读取数据。OSS⽀持流式写⼊和⽂件写⼊两种⽅

式。

·⽹页或者移动应⽤的静态和动态资源分离：利⽤BGP带宽，OSS

可以实现超低延时的数据直接下载。OSS也可以配合阿⾥云CDN加速

服务，为图⽚、⾳视频、移动应⽤的更新分发提供最佳体验。⽽CDN

没办法对块存储和⽂件存储中的数据直接做静态加速，需要结合HTTP

服务才能间接对其中的数据进⾏加速访问。

·云端数据处理：上传⽂件到OSS后，可以配合媒体和图⽚处理服

务进⾏云端的数据处理。

·云端数据备份：可以将ECS、RDS的备份或者线下IDC的数据很

⽅便地同城或异地备份⾄OSS中。

下⾯来看看阿⾥云OSS的使⽤误区。

考虑到存储空间的可扩展性、存储性能等问题，在云端存储⽂本

⽂档、图⽚、视频、⽇志⽂件等⾮结构化数据时，都会默认优先使⽤

OSS，好像ECS只适合存储代码⽂件，更有甚者建议⽤户去更改代

码。

⼀⽅⾯，在实际应⽤中，90%的是中⼩型应⽤，未来也没有太⼴

阔的业务扩展。要想提升静态资源的访问，直接在前端挂个CDN即

可，没有必要⽤OSS去做动静分离，后端⾮结构数据是不是OSS存储

不重要，只要CDN静态回源能去ECS中取到这个源数据就可以。

⽽另⼀⽅⾯，有些陈旧的系统连开发商都找不到了，这时候要花

费额外的开发成本去进⾏⼆次开发是没有意义的。直接使⽤ECS云盘

或者远程挂载NAS就能解决问题，没必要去研究及使⽤OSS。中⼩型

业务场景不会涉及复杂的分布式系统架构，所以做这个规划没有太⼤

必要。当然，具体技术的使⽤还是要取决于业务需求及场景。

4.5 云端缓存的两⼤选型秘籍

在运维实践中，缓存的⽬的是提升访问性能，这是⼀种牺牲时间

换取性能的技术。以前要获取数据时，直接去数据源获取即可。有了

缓存后，想要获取数据，先去数据源获取，如果缓存中有，则直接返

回；如果缓存中没有，则去后端数据源中取，并将取回的数据存放⾄

缓存中，以⽅便下次请求访问。可以想见，直接去缓存中获取数据，

省去了对后端数据源进⾏复杂逻辑处理后再获得数据的步骤，其性能

得到了很⼤提升。但弊端是，缓存中的数据都有时效性，⽐如5分钟、

1⼩时等，即5分钟、1⼩时内，缓存中的数据都是⼀样的，并不是实时

最新的。所以在对数据⼀致性、实时性要求较⾼的业务场景下，并不

适合做缓存。

那么在什么时间点需要考虑缓存介⼊来提升性能呢？这⾥建议参

考⼀下“I/O 5分钟法则”，我觉得其在缓存领域也⾮常适⽤：“即如果⼀

条记录频繁被访问，就应该考虑放到缓存⾥。否则的话，客户端就按

需要直接去访问数据源，⽽这个临界点就是5分钟。”

缓存的类型主要分为前端缓存和后端缓存，⽽前端缓存的应⽤就

是静态缓存，⼤家熟知的CDN就是前端静态缓存的典型代表。⽽后端

缓存的应⽤又分为动态请求（如ASP、PHP、JSP）缓存和数据库热点

数据缓存。

4.5.1 秘籍⼀：云端静态缓存唯⼀的选型

静态缓存，⼀般是指Web类应⽤中，将HTML、JS、CSS、图⽚、

⾳视频等静态⽂件/资源通过磁盘/内存等缓存⽅式提⾼资源响应速度，

减少服务器压⼒/资源开销的⼀项缓存技术。

1.静态缓存常⽤技术

静态缓存的实现技术主要有Squid、Varnish、Nginx。Squid是⼀个

代理缓存服务器，它⽀持FTP、Gopher、HTTPS和HTTP协议。⽽

Varnish也是⼀款代理缓存服务器，只不过它只⽀持HTTP代理缓存。相

较于Squid，Varnish的功能虽然不多，但Varnish的精简，也是其最⼤的

性能优势。Nginx的静态缓存需要第三⽅模块来完成，只能满⾜基本缓

存需求。不过Nginx+Memcache的组合，使其和Squid、Varnish都具备了

专业的静态缓存功能。Squid、Varnish、Nginx三者的功能特性对⽐如

表4-11所⽰。

表4-10 Squid、Varnish、Nginx缓存功能特性对⽐

单纯做静态缓存的话，Varnish技术上的优势要⾼于Squid。Varnish

采⽤了Visual Page Cache技术，对内存的利⽤更佳，它避免了Squid频繁

在内存、磁盘中交换⽂件，性能要⽐Squid好很多。有⼀个经典案例：

挪威最⼤的在线报纸Verdens Gang使⽤3台Varnish代替了原来的12台

Squid，其性能⽐以前更好。不过Squid在七层其他功能上有优势，它和

Nginx都⽀持正向代理、ACL权限控制等功能，这是Varnish所⽋缺的。

2.云端静态缓存选型

说到这⾥，不得不提CDN了，从技术层⾯来看，CDN的静态缓存

核⼼技术就是Squid/Varnish/Nginx等缓存⽅案的体现，只不过CDN将静

态缓存的技术产品化、服务化了。

CDN的技术⼿段是通过DNS智能解析+静态缓存来实现的，功能⽅

⾯就是将内容提供商的静态资源数据以最快捷的⽅式分发到离⽤户尽

可能近的地⽅与⽤户进⾏交互，以节省内容重复传输的时间。“互联⽹

⾼速公路的最后⼀公⾥”正是对CDN的形象描述。

在传统IDC的模式中，出于费⽤、维护等⽅⾯的考虑，我们⼀般都

是通过Squid/Varnish/Nginx与业务应⽤搭建静态缓存。在云计算模式

中，现在CDN已经是按需付费的模式。⼀键配置、低成本⾼效率的优

势，使得云计算模式下的静态缓存可以使⽤CDN解决静态缓存的所有

需求。在云端⼤量的实践中，我们已经很难看到有客户应⽤还⾃⾏搭

建Squid/Varnish/Nginx等静态缓存的案例了，CDN在云端实践中⼏乎已

成为静态缓存的代名词，也成为云端静态缓存选型的唯⼀选择。不过

⾯对⼤型应⽤，我们还需要在后端使⽤⼆级缓存进⼀步保障系统稳定

性，如图4-21所⽰。

图4-21 ⼆级静态缓存架构

有的读者可能会疑惑，为什么前端已经有了CDN缓存，这⾥还需

要⾃⼰再架设⼀层Web缓存呢？的确，在中⼩型常规业务中没有必要，

但做过⾼并发⾼流量项⽬的⼈应该会发现，后端NFS⽂件服务器的I/O

压⼒是巨⼤的（主要是⽤CDN回源请求来更新CDN缓存中的数据），

有时甚⾄会发⽣拒绝提供服务器的现象。这层⼆级缓存可以起到加速

后端Web服务器响应及降低NFS（或本地存储）⽂件服务器磁盘I/O压

⼒的作⽤。

4.5.2 秘籍⼆：云端动态缓存唯⼀的选型

相⽐前端缓存的静态缓存，后端缓存的动态缓存，主要是指动态

类数据的缓存，包括以下两个类型：

·动态页⾯的缓存。例如，

对.do、.jsp、.asp/.aspx、.PHP、.js(nodejs)等动态页⾯进⾏缓存。

·对数据库频繁访问查询的热点数据内容进⾏缓存。

静态缓存主要解决了⽹络带宽压⼒、服务器I/O压⼒等性能问题，

⽽应⽤动态缓存的技术主要是为了减少对数据库的压⼒。动态缓存是

典型的牺牲数据的实时性换取性能的技术。如果业务对数据的实时性

要求不太⾼，且业务访问量又很⼤，那么这时候特别适⽤采⽤动态缓

存。⽐如新闻、论坛帖⼦⽂章，⼀⽅⾯内容发布后很少更新，且数据

实时性要求不⾼，⼀些⾼访问量的新闻、帖⼦，我们就可以采⽤动态

缓存。在动态缓存应⽤中，最为重要的就是缓存时间。缓存时间不宜

设置过长，否则这段时间内，客户端访问的都是缓存数据；也不宜设

置过短，否则就不能有效抵挡压⼒。所以具体情况还是需要根据实际

业务请求压⼒，以及⽤户能承受多长时间的数据差异⽽定。

1.动态缓存常⽤技术

动态缓存的实现技术普遍采⽤Memcache、Redis。它们都是⼀款

基于内存的Key/Value数据库。两者的对⽐如下：

（1）性能⽅⾯

Redis采⽤的是单进程单线程模式，对CPU的利⽤不够理想，只能

跑满单核（在第5章会详细介绍Redis的推荐服务器配置）。⽽

Memcached采⽤的是单进程多线程模式，能充分利⽤多核CPU。

Memcache源码仅有两千多⾏，相⽐于Redis有复杂的集群模式等，

Memcache要轻量级得多。但由于两者都是基于内存的，因此速度⽅⾯

没有可⽐性，都是每秒能在内存中操作10万次左右。经常看到⼤家做

压测对⽐Redis、Memcache，对⽐⾼并发来检测两者的访问内存。虽

然它们的底层原理、运⾏模式有很⼤差异，但是这个访问速度的对

⽐，没有太⼤意义。主要是因为它们的应⽤场景都是基于内存操作，

对内存的操作速度差异不⼤，如果真有很⼤差异，只能说明访问慢的

那款软件底层源码出BUG了。

（2）功能⽅⾯

·Redis和Memcache都是将数据存放在内存中，都是内存数据库。

·Redis不仅⽀持简单的k/v类型的数据，同时还提供LIST、SET、

HASH等数据结构的存储。

（3）持久化⽅⾯

Memcache不⽀持，Redis⽀持RDB/AOF将内存数据保存在磁盘

内。

（4）分布式⽅⾯

Memcache需要在代码层通过HASH算法进⾏分布式，⽽Redis⾃带

主从、分⽚集群策略。

2.云端动态缓存选型

在云端，我们不需要在ECS上⾃⾏搭建Memcache及Redis，云数据

库Memcache版、云数据库Redis版能直接解决我们对内存数据库的诉

求。云数据库Memcache版、云数据库Redis底层是基于Tair实现的，

Tair是由淘宝⽹⾃主开发的Key/Value结构的数据存储系统。Tair有4种

引擎：MDB、RDB、KDB和LDB，分别对应4种开源的Key/Value数据

库：MemcacheDB、Redis、Kyoto Cabinet和LevelDB。

云数据库Memcache版、云数据库Redis版基本上解决了⾼可⽤、

持久化、性能等⽅⾯的问题。即我们⽆须担⼼Redis、Memcache搭

建、⾼可⽤、后期扩展等问题。所以对云端动态缓存的选型主要取决

于业务应⽤功能性⽅⾯，这也是云端动态缓存选型的唯⼀考虑。对数

据结构和处理有⾼级要求的应⽤选择Redis，其他简单的Key/Value存储

选择Memcache。

4.6 云端数据库选型的三个⽅⾯

数据是企业的⽣命，这个数据绝⼤多数情况下体现在数据库中存

储的数据上，即结构化数据。在数据库技术领域，各种数据库如同形

形⾊⾊的编程语⾔，让⼈应接不暇。但万变不离其宗，从ACID模型到

CAP定理再到BASE模型，都是数据库发展的基础，更决定了众多数据

库的类型划分。

4.6.1 分类⽅⾯：数据库的三⼤分类

1.数据库的分类及选型依据

CAP定理（CAP theorem），在2000年由Eric Brewer教授提出，又

被称作布鲁尔定理（Brewer’s theorem）。它指出对于⼀个分布式系统

来说，其不可能同时满⾜以下3点。

·Consistency（⼀致性）：所有节点在同⼀时间具有相同的数据。

·Availability（可⽤性）：保证每个请求不管成功或者失败都得到

响应。

·Partition tolerance（分区容错性）：系统中任意信息的丢失或失败

不会影响系统的继续运作。

根据定理，分布式系统只能满⾜3项中的两项⽽不可能满⾜全部

项。因此系统架构师不要把精⼒浪费在如何才能设计出同时满⾜CAP

三者的完美分布式系统上，⽽应该研究如何进⾏取舍，以满⾜实际的

业务需求。换个⾓度来讲，同样可以根据业务需求特性，我们对应选

择满⾜CAP定理的相应数据库。这是对众多数据库进⾏分类划分的依

据，更是实践中进⾏数据库选型的重要依据。

2.ACID模型所带来的“三⾼”问题

ACID模型是指在数据库管理系统（DBMS）中，事务

（Transaction）所具有的如下4个特性。

·Atomicity：原⼦性；

·Consistency：⼀致性；

·Isolation：隔离性；

·Durability：持久性。

传统关系型数据库实现了CAP定理中的Consistency（⼀致性）和

Availability（可⽤性），但对Partition Tolerance（分区容错性）不够⽀

持。关系型数据库在事务⽅⾯的特性，让其在业务关键核⼼数据（如

⽤户信息），特别是⾦融类领域中是⽆可替代的。⾄今，这也是⾦融

领域把Oracle关系数据库作为标配的重要原因。但关系型数据库对集群

的Sharding（分⽚）⽀持极弱，如Oracle、MySQL、SQL Server等典型

的关系型数据库，并没有MongoDB、Redis对应的Sharding（分⽚）集

群功能。

随着互联⽹Web2.0⽹站的兴起，以及⼤数据和云时代的到来，传

统关系型数据库⾯对“性能”问题已经⼒不从⼼，暴露了很多难以克服

的性能“三⾼”问题。

·对数据库⾼并发读写的需求：关系型数据库中的经典主从架构已

经远远满⾜不了读写⾼并发需求，特别是在⾼并发写⽅⾯的需求。

·对海量数据的⾼效率存储和访问的需求：⾯对TB和PB级别的数据

存储，关系型数据库根本⼒不从⼼。

·对数据库的⾼可扩展性和⾼可⽤性的需求：关系型数据库的集群

模型只是解决了架构在垂直扩展⽅⾯的问题，但根本不能解决通过⽔

平横向扩展添加机器来解决扩展性的问题。

3.BASE模型及⾮关系型（NoSQL）数据库的发展

BASE的英⽂意义是碱，⽽ACID是酸，可以看到BASE和ACID是

对⽴的。那什么是BASE模式呢？它具有以下特性。

·Basically Availble：基本可⽤；

·Soft-state：软状态；

·Eventual Consistency：最终⼀致性。

由此可以看到，BASE模型是反ACID模型的，它完全不同于ACID

模型。BASE思想主要强调基本的可⽤性，⽀持分区失败，允许状态在

⼀定时间内不同步，保证数据达到最终⼀致性即可。所以BASE模型也

是对CAP定理的实现，实现了CAP定理中的Availability（可⽤性）和

Partition tolerance（分区容错性），弱化了Consistency（⼀致性）。

关系型数据库所带来的“三⾼”问题，奠定了在云时代⾮关系型

（NoSQL）数据库的发展。⽽⾮关系型（NoSQL）数据库，除了实现

CAP定理的AP外（也可以称为BASE模型），也实现了CAP定理中的

CP（Consistency（⼀致性）和Partition Tolerance（分区容错性），但对

Availability（可⽤性）⽀持不⾜）。从中可以看到，不管是AP还是

CP，其中都有个字母P。这是因为对于分布式存储系统⽽⾔，分区容错

性（P）是基本需求。即NoSQL数据库中，集群（Sharding）分⽚的功

能是常态。⾮关系型数据库的⽔平横向分⽚（Sharding）功能（能够单

纯通过增加机器解决存储扩容、⾼并发读写的性能问题），解决了关

系型数据库中的垂直纵向扩展（⽐如主从、Cluster集群都是垂直扩

展，不能通过⼀直加机器解决性能问题）带来的性能问题。

4.数据库的三⼤分类

根据CAP定理，我们将数据库进⾏了分类汇总，如表4-11所⽰，这

也是我们根据业务需求进⾏数据库选型的重要依据。

表4-11 数据库的三⼤分类

5.常见的热门数据库

对于常见的热门数据库，我们可以参考DB-Engines的全球数据库

流⾏度排⾏榜。它对343个数据库进⾏了排名，这⾥取2019年1⽉的排

⾏榜结果的前20名作为参考，如图4-22所⽰。

图4-22 热门数据库排⾏榜前20名

从图4-22中的前20名排名中可以看到以下亮点：

1）Oracle、MySQL、SQL Server得分持续下滑，Oracle下滑了

14.39分，MySQL下滑了6.98分。SQL Server在近⼀个⽉内还算平稳，

只下滑了0.08分。但特别是相⽐去年同期，Oracle下滑了73.11分，

MySQL和SQL Server更是分别下滑了145.44分和107.81分。

2）PostgreSQL领衔持续增长，相⽐2017年同期，2018年增长79.93

分。以其卓越表现，蝉联2018年度数据库荣誉，或许这将是

PostgreSQL三连冠的开始。在关系型数据库整体持续下滑⽽⾮关系型

数据库持续增长的趋势下，PostgreSQL作为发布于1989年的年轻关系

型数据库，还能保持这么⾼的增长，可见是众望所归。PostgreSQL的

主要优点是，基于坚实的RDBMS实现（实现了CAP定理中的

Consistency（⼀致性）和Availability（可⽤性）），因其稳定性和功能

集⽽倍受青睐。特别是对JSON数据类型和运算符的⽀持，以及在新版

本中提⾼了分布式数据库的性能和⽀持，让其在数据库领域格外耀

眼。

3）MongoDB紧跟PostgreSQL之后，也保持着良好的增长趋势，相

⽐去年同期，增长56.24分。MongoDB作为2013年和2014年的年度数据

库，同时作为最受欢迎的NoSQL⾮关系型数据库，它的热度⼀直未曾

消退。如今，熟悉MongoDB已成为研发、运维等技术岗位招聘⼈才的

重要标准，已成为相关技术⼈员求职加薪的重要技术筹码。MongoDB

的主要优点是⾯向⽂档存储，它⽀持的数据结构是类似JSON的BSON

格式，在使⽤MongoDB的时候，⾸选要学会忘记SQL。相较于通过表

状的结构来保存数据，⽂档结构的存储⽅式能够更加便捷地获取数

据。在MongoDB中，不⽤因为增加⼀个属性⽽去声明表结构及字段类

型，⽽在MongoDB中这些都是不需要的，这⼀优势给我们的业务开发

带来了很⼤便捷性。同时MongoDB使⽤的是内存映射存储引擎，特别

是⼤内存的服务器让其性能更优越，加上提供内置Sharding+GridFS出

⾊的分布式⽂件系统功能，其在海量数据存储、⾼并发读写的场景下

有得天独厚的优势。

4）在2018年度数据库排名第三的就是Redis了，Redis是NoSQL中

最受欢迎的Key-Value数据库，主要应⽤在后端业务数据的缓存中。

Key-Value数据库还有⼀个被⼤家熟知的就是Memcache数据库，但是我

们在前20名排名中已看不到它的⾝影。在2019年1⽉的数据库流⾏度排

名中，Memcache被排在了第24名。这主要是因为Memcache的功能太单

⼀，只提供简单的K/V类型的数据结构，不⽀持数据库持久化、不⽀持

主从及Sharding集群分配功能。⽽Redis在Key-Value数据库领域提供丰

富的数据结构存储、数据持久化（内存数据保存在磁盘中）、主从及

Sharding集群的架构功能，故其适⽤于很多业务场景，⼏乎取代了

Memcache。

下⾯给出最近6年的年度数据库。

·2018年度数据库：PostgreSQL；

·2017年度数据库：PostgreSQL；

·2016年度数据库：Microsoft SQL Server；

·2015年度数据库：Oracle；

·2014年度数据库：MongoDB；

·2013年度数据库：MongoDB。

下⾯再来看看数据库排⾏⾛势，如图4-23所⽰。

前三名Oracle、MySQL、SQL Server作为关系型数据库，得分⼀直

在1000分以上。短期内还没有其他数据库可以威胁到它们，依然呈现

三⾜⿍⽴之势。还记得⼤学学的数据库这门课程，上机操作练习就是

SQL Server。我在实习做Java开发的时候才接触到MySQL，不过Java在

Windows环境下调⽤SQL Server的实践也是⾮常⼴泛的。

图4-23 关系型数据库⾛势

不过结合最近6年的趋势，我们可以看到Oracle、MySQL、SQL

Server得分⼀路下滑，它们将会迎来寒冬。相对来说，⾮关系型数据库

NoSQL却稳健增长，⾛势要明朗许多，如图4-24所⽰。

图4-24 ⾮关系型数据库NoSQL⾛势

根据图4-24所⽰的趋势可以看出前⾯所⾔⾮虚。随着互联⽹

Web2.0⽹站的兴起，也即将进⼊Web3.0。传统关系型数据库已满⾜不

了云计算/⼤数据/⼈⼯智能对海量数据存储及⾼并发读写的性能需求，

⽽这些也是⾮关系型数据库（NoSQL）的优势。

4.6.2 性能⽅⾯：数据库的性能秘密

在数据库的应⽤中，数据库能承受的性能是我们选择使⽤数据库

时要参考的⾮常重要的因素。过⾼或过低的评估都将直接影响业务系

统对外能提供的吞吐量，以及后期业务发展所带来的扩容问题。表4-12

中的性能参数可作为⼤家在云端运维架构设计中的参考。相应的性能

参数是实践经验总结，不是绝对值，具体情况需要根据业务情况来确

定。

表4-12 数据库性能对⽐

在关系型数据库中，单表存储的极限在亿级别。特别是MySQL，

单表存储过亿时，数据查询会异常缓慢。⽽Redis、MongoDB、HBase

等⾮关系型数据库，都⽀持Sharding分区功能，数据存储基本不受限

制。在QPS⽅⾯，关系型数据库的极限在万级别，⽽⾮关系型数据库，

根据集群规模不同，能轻松应对10万级别以上的⾼并发读写需求。

4.6.3 选型⽅⾯：云端数据库选型的两点考虑及⼀个步骤

1.数据库选型的两点考虑

进⾏⼀个数据库的选型，主要需要考虑如下两点：

·⼀是业务侧的背景需求，⽐如是游戏⾏业、电商⾏业还是⾦融⾏

业，存储的是游戏装备/充值记录，还是电商⽤户订单/商品信息，又或

者是⾦融交易数据等。业务侧对数据的结构、未来规划及扩展的需

求，决定了我们是选择关系型数据库还是⾮关系型数据库这⼀⼤类别

⽅向。

·⼆是运维侧的架构需求，主要表现在数据库的性能及数据库架构

扩展能不能满⾜对业务侧快速发展迭代在数据库存储、性能、扩展⽅

⾯的需求。即选择对应数据库技术能不能⽀撑业务的迭代和快速发

展。

2.传统数据库的选型步骤

在实际应⽤过程中，我们对数据库的选型会经过图4-25所⽰的环

节，这些都会影响我们对数据库的选择及考量。

图4-25 传统数据库选择步骤

业务需求主要对应的是软件代码层⾯的架构及规划：

·对数据结构、数据表及集合的规划设计，选择适合业务需求的关

系型数据库或者⾮关系型数据库，满⾜业务对数据增删查改的需求。

·需要考虑⼀些热点数据查询需不需要借助Key-Value内存数据库做

缓存，从架构上减少数据库压⼒，提升业务系统的性能效率及稳定

性。

·在代码连接池⽅⾯，设计合理的连接池，连接数不宜过⼤或过

⼩，以免导致后端数据库连接数不释放等性能问题。

·在⼀些对数据库⾼并发的场景加⼊队列的控制，也是有效减轻对

数据库直接压⼒冲击的⼀种⽅式。

运维架构层考量及规划：

·存储的数据规模及后期扩展，采⽤主从还是副本集，又或者是

Sharding的数据库架构？

·出现异常怎么进⾏快速切换，是需要代码层主动切换IP，还是数

据库结合通过DNS+LB（负载均衡）+HA（⾼可⽤）的技术完成⽆缝切

换？

硬件及基础环境部署：

·选择什么配置的服务器（数据库对服务器性能的需求是IO>内存

>CPU，在第5章中会详细介绍），服务器型号及对应磁盘阵列

（Raid0、Raid1、Raid0+1、Raid1+0、Raid5）。

·操作环境设置，Ulimit⽂件打开数、LVM磁盘管理、内核优化

等。

数据库安装配置及优化：

·选择对应数据库版本进⾏安装部署及配置。

·根据服务器配置优化数据库配置参数（⼀般从连接数、缓存、内

存占⽤数等⽅⾯进⾏优化），使数据库服务器性能达到最优。

SQL语句优化：

慢查询是DBA做的最常见的事情，我们需要对SQL语句及索引做

出优化及调整。在实践中我们得出以下两条实践经验：

·80%的数据库性能问题都出在SQL语句上。

·80%的SQL语句性能问题都是由索引引起的。

⽇常备份及恢复有如下特性：

·数据库的备份是⾮常重要的，备份永远只是为了那1%的可能性。

备份中有⼀个⾮常重要的就是备份的可⽤性，我们需要定期检测备份

可⽤性。当数据库需要回滚时却发现备份数据不可⽤⽽⽆法回滚，这

将是灾难性的事故。

·备份采⽤冷备还是热备？采⽤物理备份（数据库底层磁盘⽂件备

份）还是逻辑备份（数据SQL语句DUMP导出）？相应的备份⽅案也与

业务情况及状态相关。⽐如常规业务（业务规模、业务数据敏感

性），我们每天采⽤逻辑备份的冷备即可满⾜⼤多数备份需求。

在对传统数据库进⾏选择时都会经过以上步骤，⽽每⼀步都需要

花费较多的时间精⼒进⾏设计、规划、配置、优化，甚⾄可能因为数

据库在某⼀步骤的⼀些功能缺陷⽽导致不得不放弃对该数据库的选

择。

3.云端数据库仅有的⼀个步骤选型

在云端数据库的选型将会⾯临巨⼤转变，当前基本上不⽤考虑运

维侧的架构侧的需求，完全偏向考虑业务侧的需求，即选择对应的云

数据库，如图4-26所⽰。

图4-26 云端数据库选择步骤

·云数据库的运维架构层考量及规划：云数据库底层已经通过

DNS+LB（负载均衡）+HA（⾼可⽤）的技术保障数据库⾼可⽤，增加

主从节点、增加Sharding都可以在控制台界⾯⼀键式操作。

·云数据库的硬件及基础环境部署：云数据库已经封装成产品服

务，不需要考虑选择什么服务器配置来部署数据库，只需要开通对应

规格型号的云数据库即可使⽤。

·云数据库的安装配置及优化：云数据库在参数⽅⾯已经优化成最

优，不需要⼿动再去调优对应的数据库配置参数。

·云数据库的SQL语句优化：云数据库在控制台直接给出慢查询的

明细及优化建议。

·云数据库的⽇常备份及恢复：云数据库⾃带热备及冷备，只需要

⼿动在控制台设置对应的备份策略即可。

通过以上对⽐可以发现，维护、调优、备份、扩展等这些传统数

据库选型考虑的重要因素，在云端数据库的选择上完全不⽤担⼼。⽽

我们更多的是要从业务⾓度出发选择需要什么样类型的数据库。

·需要存储什么类型的业务数据：⽐如⽤户数据、交易数据，对数

据⼀致性上要求较⾼，需要优先考虑关系型数据库。

·需要存储什么量级的数据：⽐如TB级别数据，关系型数据库的存

储已经很慢了。

·需要提供什么访问量级的访问：⽐如上万的并发请求，关系型数

据库性能已经快到极限。

4.云数据库分类

云端常见关系型及⾮关系型汇总如表4-13所⽰。

表4-13 云端常见数据库

第5章 配置选型

我们经常会遇到这样的问题，业务端反馈给后端⼀个在线⽤户数/

活跃⽤户数，要求做架构规划时，需要⽤多少台服务器，⼤多数⼈都

是⼀头雾⽔，不知道从何⼊⼿、如何去评估设计。最终，设计完全凭

⾃⼰的感觉进⾏，⽤尽量多的服务器以及更多的成本预算，这就成了

设计这个架构⽅案的“核⼼思想和精髓”。

同样，要部署⼀个Web类应⽤或⼀个数据库，具体要⽤什么样的

服务器配置及宽带配置，相信⼤多数⼈同样还是⼀头雾⽔，仍是凭借

感觉给出配置清单，⽤尽量⾼配的服务器及宽带，这就成了给出配置

清单的“核⼼依据和精华”。

事实上，在这些实践中，都是有技巧和章法的，相信本章总结的

实践经验会让你在云端配置选项上有很⼤收获。

5.1 衡量业务量的指标

PV访问量、IP访问量、⽤户数、活跃⽤户数等都是常见衡量业务

访问量⼤⼩的指标。通过合适的指标来评估及衡量业务量，是我们做

容量配置规划的基础也是第⼀步。

5.1.1 ⼀台Tomcat跑两亿PV的笑话

我们先来看⼀个真实的案例，某⾦融投资客户的业务跑在⼀台

Tomcat上（注意，这⾥仅是⼀台4核8GB的ECS上搭建的Tomcat）。客

户开展活动时，访问压⼒会增⼤，所以要求我们做好保驾护航及扩容

⼯作。此时我们会慎重地询问客户活动时的访问压⼒是平时的多少

倍。结果得知，活动期间可能引⼊的客户流量会暴增，初步估计是两

亿PV。两亿PV的⾼访问量带给我的不只是震惊，更多的是触动，我

开始思考客户的这个需求背后隐藏着的更深⼊的⼀些问题。后来，我

也经常通过这个案例跟⼤家探讨业务真实访问压⼒与服务器性能配置

的指标关系。

这个案例引⼈反思，也反映出当前企业普遍对容量配置规划没有

概念：

·不懂PV的概念，不懂2亿PV的量级是多⼤。

·即使最近做活动有流量提升，但是仅有⼀台Tomcat跑着⼩业务的

⽇常流量，突然要求其跑2亿PV的流量，这巨⼤的反差更是说明企业

对业务流量没有清晰的认识。

5.1.2 衡量业务量的指标

衡量业务量的指标项有很多，⽐如，常见Web类应⽤中的PV、

UV、IP。⽽⽐较贴近业务的指标项就是⼤家通常所说的业务⽤户数。

但这个⽤户数⽐较笼统，其实和真实访问量有⽐较⼤的差距，所以为

了更贴近实际业务量及压⼒，我们又把⽤户数的指标分成了活跃⽤户

数、在线⽤户数以及并发⽤户数。常见衡量业务量级的指标汇总如表5-

1所⽰。

表5-1 常见衡量业务量级的指标项

5.2 业务访问量与性能压⼒指标的转换

得到业务访问量的指标数据后，我们要将其转换成为系统压⼒的

指标数据。这⼀步让抽象的业务访问量的指标数据，变成技术⼈员熟

悉的性能压⼒指标数据，是容量配置规划的关键⼀步。

5.2.1 指标转换原理

我们对业务量数据没概念的原因在于这些都是业务的运营数据，

⽆法转换成技术⼈员所熟悉的性能压⼒数据。这也是多数技术⼈员⾯

对业务量数据时，对容量规划需要多少台服务器⽆从下⼿的根本原

因，所以解决此问题的关键，就是把业务量的数据指标转换成技术⼈

员熟悉的性能压⼒指标。这样在做架构规划设计、容量规划和成本预

算时才能有章可循，从⽽使其思路更加清晰。

在配置实践中，业务访问量与性能压⼒指标的转换模型，特别是

针对业务还处于前期需求规划期间的容量规划（业务系统还未研发上

线，只能⼤体预估到未来可能的业务量，拿不到后端系统运⾏的实际

性能压⼒状态数据），最为常见的做法就是把业务量的数据指标，最

终转换成对系统的每秒请求数（某⼀秒内同时向服务器发送的请求数

量，以下简称每秒请求数）这个指标，进⽽评估对应业务量，究竟产

⽣了多少性能压⼒，最终设计出合理的架构，及要⽤多⼤规模的服务

器及配置。值得注意的是，因为实际的业务特点不同，采⽤的开发语

⾔及数据库技术也不同，所以这个转换以及要⽤多少规模的服务器及

配置，只是⼀个估算的参考值，并不是最终的真实值。

如果业务还处于前期需求规划期间，业务量和性能压⼒的转换原

理如图5-1所⽰。

图5-1 未上线业务量和性能压⼒的转换原理

在浏览器/服务器（Browser/Server）架构的Web类应⽤的实践中，

常见的做法是把PV转换成每秒请求数，或者把⽤户数最终转换成每秒

请求数。通常⼀般的做法都是将其转换成⾃⼰所熟悉的PV指标。

如果业务系统已经上线，⽣成指标转换的模型就要简单得多。⼀

⽅⾯，当前业务系统有多少⽤户量及活跃⽤户量等业务数据，运营⼈

员基本都能很直接地给出。另⼀⽅⾯，业务系统的运⾏性能状态也能

通过监控很直接地体现出来。有了这两组数据，我们就能将⽤户量与

性能压⼒进⾏转换对应，也能做出未来业务量下的容量规划等。对于

业务系统已经上线的这种情况，业务量数据指标也不⼀定⾮要转换成

对应的每秒请求数，可以根据实际情况选择合适的性能压⼒指标。当

然，在条件允许的情况下，如果能对当前业务系统进⾏⼀次压⼒测试

是最好的。压测结果能够让业务的⽤户访问数和实际系统可能出现的

性能压⼒对应起来，特别是针对未来活动及可能出现的⼤流量的情

况。

业务系统已经上线，业务量和性能压⼒的转换原理如图5-2所⽰。

如果未来业务量增加，要做容量规划和成本评估，可以直接根据

对应的业务指标将当前系统性能状态指标关联起来。常见的做法是使

⽤简单的四则运算，⽐如，100万⽤户量，当前⽤了10台服务器，业务

⾼峰期资源使⽤率是50%。如果变成200万⽤户量，⾄少要再加10台服

务器。当然，在实际应⽤中，⽤户量增加对系统的压⼒可能不是呈线

性级关系，⽽是指数级的关系，所以这个估算只是在做容量规划、成

本预算规划时的主要参考值。最终需要看实际业务情况，同时还要结

合监控看资源的具体使⽤时的性能情况。

图5-2 上线业务量和性能压⼒的转换原理

通过以上对业务数据指标的转换可以看出，在做架构设计时，核

⼼⽬的是前期在做规划的时候，能够看到未来的规模及容量⼤概要在

⼀个范围区间，所以采⽤对应的估算也是尽量保障规划设计尽可能地

接近真实情况，但这并不是绝对值，只是参考值。这也是接下来跟⼤

家介绍指标换算模型时所要注意的，真实情况还要结合监控和压测实

际来看。

5.2.2 性能指标转换计算模型实践

2013年，我⾯试过⼀家互联⽹公司的运维岗位，那是⼀家初创公

司，起步规模不⼤。我⾮常清楚地记得⾯试官问过我⼀个问题：“⼀个

500万PV的⽹站，⼤概要⽤多少台服务器？”这个问题是针对业务还处

于前期需求规划状态提出的，考查的是根据业务规划如何做配置评估

和成本预算。当时我回答这个问题的思路不是很清晰，只是说要看业

务的复杂度等。这些年我⼀直在进⾏思考和总结，寻找将运营的业务

数据跟系统的性能压⼒数据关联起来的⽅法，以便最终可合理地规划

业务所需要的服务器资源量。

⾸先，我们要弄明⽩的是500万PV的业务访问量到底会对系统产

⽣多⼤的请求压⼒。500万PV，即⼀天24⼩时中访问了业务页⾯500万

次，如果⽤500万÷24⼩时÷60分钟÷60秒即可得出每秒的页⾯请求数，

⽤这个结果表⽰对系统产⽣的请求压⼒值的话，那么得到的结果和实

际情况将会有很⼤的偏差。因为实际的业务访问过程，⽐如，凌晨等

业务低峰期，基本上没多少业务访问量。在实践中可以发现，⼀天中

的80%业务请求量主要发⽣在40%的时间内，这成为我们计算PV值对

应请求压⼒的重要依据。24⼩时的40%是9.6⼩时，即80%的请求发⽣

⼀天的9.6个⼩时当中。基本与绝⼤多数的业务场景吻合，业务请求主

要集中在⽩天，晚上则相对较少。

PV请求量计算模型如下：

每秒处理请求的数量=（80%×总PV量）/（24⼩时×60分×60秒

×40%）

从⽽100万/500万PV请求量对应的计算结果为：

（80%×100万）/（24⼩时×60分×60秒×40%）=23.1个请求/秒

（80%×500万）/（24⼩时×60分×60秒×40%）=115.7个请求/秒

即服务器⼀秒能处理23.1个请求，就可以每天承受100万PV的业务

量。服务器⼀秒能处理115.7个请求，就可以每天承受500万PV的业务

量。

其次，在真实的业务场景下，有低⾕也会有⾼峰，我们主要考虑

⾼峰期的情况。假如⼀天中⾼峰期的请求量是平时请求的两倍或3倍

（⽐如，电商之类的⼀些活动，⾼峰波动会更⼤，具体乘以多少根据

业务情况⽽定），⽰例如下：

23.1个请求/秒×2倍=46.2个请求/秒

23.1个请求/秒×3倍=69.3个请求/秒

115.7个请求/秒×2倍=231.4个请求/秒

115.7个请求/秒×3倍=347.1个请求/秒

最终，如果服务器在⼀秒内能处理46.2～69.3个请求/秒，那么就

能应对100万PV的业务请求量。

如果服务器在⼀秒内能处理231.4～347.1个请求/秒，那么就能应

对500万PV的业务请求量。

5.2.3 业务指标转换计算模型实践

通过以上指标转换模型，我们可以知道对应的PV业务访问量具体

对应多⼤的请求性能压⼒。这个数据，可以给我们做架构规划、容量

规划、成本预算提供很好的参考。如果业务还处于前期需求规划期

间，只是知道IP/⽤户数/活跃⽤户数/在线⽤户数/并发⽤户数这些业务

访问指标，我们可以先将其转换成对应的PV业务访问量，进⽽折算成

每秒请求数，或者先转化为并发⽤户数，再折算成每秒请求数。

实践案例1：IP访问量向PV访问量的转换计算模型

虽然⽹站的IP访问量、PV访问量等明细数据信息，可以通过CNZZ

等⽹站流量统计分析出来（需要在⽹站页⾯安装插件，主要分析统计

七层客户端请求数据），但这⾥还是简要地介绍⼀下，主要是想让⼤

家理解在实践背后，怎么估算⾃⼰业务的实际性能压⼒值。IP的访问

量转到PV访问量，其实转换的核⼼在于Web⽹站的业务类型，不同业

务特性的计算模型实践总结如表5-2所⽰，仅供读者参考。

表5-2 不同业务特性的计算模型

值得注意的是，假设每个⽤户都有独⽴的IP，则IP访问量等于活跃

⽤户量。但在实际⽤户场景中，活跃⽤户量是⼤于IP访问量的（偏差

⼀般为1～2倍）。这是因为很多⽤户的公⽹局域⽹通过SNAT⽅式访问

公⽹，这时候不同⽤户访问系统，其实系统中识别的只是⼀个IP。但

由于根据不同Web的业务形态，将其转换成PV量，就考虑到2～5倍、5

～10倍、10～30倍，甚⾄更⾼倍数的冗余。所以在这种⾼倍数估算的

前提下，我们就会认为IP访问量约等于活跃⽤户量。

实践案例2：⽤户数向并发⽤户数的转换计算模型

⼀般指业务系统的注册⽤户数，这个业务数据其实是“死”的。⽐

如，注册了10万个⽤户、100万个⽤户，最后没⼈访问业务系统，那就

没有任何意义了。假如⼀个10万⽤户量的Web类⽤户，⼀天活跃⽤户数

是1万⼈，同时在线的⼈员是1000⼈，那么这表⽰在最⾼峰期，有1000

⼈同时登录了系统，但这并不表⽰实际服务器承受的压⼒。因为服务

器承受的压⼒还与具体的⽤户访问模式相关，⽐如，这1000⼈同时使

⽤系统的时候：

·可能有40%的⽤户：在浏览系统内容（注意，停留页⾯“看”这个

动作是不会对服务端产⽣任何负担的，并不同于数据库查询的操

作）。

·可能有20%的⽤户：在填写复杂的表格（填写过程并不对服务器

产⽣请求压⼒，只有在“提交”的时候才会向服务端发送请求）。

·可能有20%的⽤户：在挂机（也就是什么都没有做，也不会对服

务器产⽣请求压⼒）。

·最后剩下的20%⽤户：在页⾯中做点击、跳转、提交等操作，可

能只有这种情况下才实际对服务器产⽣请求压⼒。

计算模型参考：

⽤户数×业务因⼦（10%～30%）=活跃⽤户数

活跃⽤户数×业务因⼦（10%～30%）=在线⽤户数

在线⽤户数×业务因⼦（10%～30%）=并发⽤户数≈每秒请求数

5.3 云端服务器配置模型

在实践中我们可以总结得出不同的服务器配置⼤概能跑的性能压

⼒。再结合我们根据业务访问量指标评估的性能压⼒指标，就能得出

我们在云端业务所采⽤的服务器配置模型。然后可以根据部署的应⽤

服务类型不同，对计算资源的所需的偏向不同，再具体最优选择对应

CPU与内存资源配⽐的配置。接下来跟⼤家详细分享云端服务器配置

模型的最佳实践。

5.3.1 PV量对应的服务器配置

如果业务还处于前期需求规划阶段，想知道对应PV访问量的业务

要⽤什么样的服务器配置，又需要⽤多少台，根据前⾯所说的，先通

过业务访问量与性能压⼒指标的转换，把具体访问的PV量对应到服务

器每秒处理的请求数中，然后只需要知道对应服务器每秒处理的请求

数⼀般都是⽤多少配置的服务器来运⾏即可。在实践中，⼀台8核

16GB的服务器基本上能处理Web类应⽤上百的请求，所以可以对应100

万PV。具体的PV量、服务器的⼤概配置以及所⽤的服务器台数，可参

考如表5-3所⽰。

表5-3 PV量和服务器配置/RDS配置性能对应表

如果业务系统已经上线，根据业务规划做配置评估和成本预算要

容易得多。正如前⾯所说的，业务数据指标（不仅是针对业务PV访问

量）、服务器性能状态指标都是现成的数据。以下是配置估算的三要

素：

·作为基准参考模型：平时业务访问量对应平时服务器性能状态，

采集平时所⽤的服务器配置以及⽤了多少台。特别是IDC业务迁云，云

上要⽤什么配置的服务器，要⽤多少台，当前在线下服务器的配置、

性能使⽤状态等都是重要的基准参考数据。

·作为冗余参考模型：活动⾼峰期业务访问量对应⾼峰期间服务器

性能状态，采集⾼峰期所⽤的服务器配置以及⽤了多少台，如“双⼗

⼀”电商秒杀活动，或者平时的优惠活动，需要额外增加服务器来冗余

活动访问量。这期间的性能数据，是我们规划下次活动要采⽤什么样

的服务器配置及对应台数的重要参考数据。

·作为规划参考模型：性能压测模拟业务访问量对应性能压测期间

的性能状态，采集⾼峰期所⽤的服务器配置以及⽤了多少台。系统性

能瓶颈、未来业务扩展和评估，都需要进⾏必要的性能压测，对应的

压测结果是我们未来做容量规划、成本预算的重要依据。

5.3.2 服务器CPU/内存配置模型

互联⽹公司是⽤计算机来⽀撑业务的，业务必然会消耗计算机中

的资源，这些资源包括CPU、内存、存储、⽹卡等。在服务器配置

中，最为核⼼的就是CPU和内存的配置。实践中，不管是部署什么业

务，⼤家都喜欢⽤⾼配。⽐如，部署Tomcat⽤8核16GB/8核32GB，部

署Nginx/Apache也⽤8核16GB/8核32GB，部署数据库也⽤8核16GB/8

核32GB。主要原因在于⼤家对相应中间件的特性不了解，不知道采⽤

什么样的服务器配置最合理，因此采⽤⾼配的服务器相对会⽐较保

险。虽然云平台让⼤家使⽤资源更加⽅便快捷，也省去了很多维护管

理的成本，但是在云上，服务器配置的合理性、资源使⽤过剩浪费，

这基本上是每个企业都会遇到的普遍现象。⽐如，某客户的⽤16核

64GB的服务器跑⼀个Tomcat。再如，某电商客户做活动，⽤16核

128GB的服务器跑Java应⽤，这些都是对业务软件性能特性不了解导

致资源严重过剩的问题。

云诀窍

据监控数据显⽰，互联⽹企业的服务器CPU利⽤率平均在10%～

20%，磁盘空间的利⽤率在20%～30%。在云端，有80%企业存在计算

资源和存储资源闲置浪费的现象。

当前阿⾥云在服务器配置中（2019年1⽉数据），最⾼配的配置是

160核1920GB。最为常见的配置还是1核1GB、1核2GB、2核4GB、4

核8GB、4核16GB、8核16GB、8核32GB、16核64GB、16核128GB

等。不管多少核多少GB，实践中最为常见的服务器配置都存在着⼀个

规律，即CPU与内存资源配⽐⼀般都是1∶1、1∶2、1∶4、1∶8，这是服务

器配置中的标配。具体CPU与内存的资源配⽐是1∶1、1∶2、1∶4、1∶8的

服务器，它们的应⽤场景及适合部署的软件服务，经实践汇总如下：

1.CPU与内存资源配⽐：1∶1

适⽤于个⼈⽹站、官⽹等⼩型⽹站部署，⼀般在低配机器中，如1

核1GB、2核2GB。基本上在云端实践中，很少看到基于4核4GB、8核

8GB、16核16GB的ECS进⾏运维部署。

2.CPU与内存资源配⽐：1∶2

1∶2的处理器与内存配⽐可以获得最优计算资源性价⽐，不管是线

下IDC的物理服务器，还是云端ECS服务器的配置，1∶2均为黄⾦⽐

例。⽐如，1核2GB、2核4GB、4核8GB、8核16GB、16核32GB，这些

都是实践中的黄⾦⽐例配置。1∶2的配⽐适⽤于绝⼤部分业务场景部

署，尤其是需要消耗⾼资源的计算。这个配置特别适合游戏类应⽤，

如端游、页游、⼿游等。当前在电商类⾼并发、秒杀活动类应⽤中使

⽤得也特别⼴泛。⽽在对应1核2GB、2核4GB、4核8GB、8核16GB、

16核32GB这些黄⾦配置中，应⽤最多的当属8核16GB，这是云上服务

器黄⾦⽐例配置中的最佳实践。

1∶2的配⽐，需要单独拿出来说⼀下，这个配置特别适合Web服务/

应⽤类，因为这类应⽤对CPU、内存的要求很⾼，都需要最优的计算

资源。4核8GB偏向中⼩型Web服务/应⽤类部署，8核16GB偏向中⼤型

Web服务器/应⽤类部署。常见的Web服务/应⽤类配置部署实践如下：

·Tomcat适⽤中低配：2核4GB、4核8GB，特别是4核8GB是最优选

择。因为Tomcat是单进程多线程的模式，是个轻量级且并发请求数最

多也就只能跑到1000左右。所以单台Tomcat⾼配的服务器并不能跑满

服务器的性能，会造成很⼤的资源浪费。如果想跑满中⾼配服务器性

能，常规做法就是在⼀台服务器上部署多台Tomcat。

·针对PHP的配置相对Tomcat来说就灵活得多，因为PHP是多进程

模式，常规的PHP-FPM就是PHP的FastCGI进程管理器。不管低配、中

配还是⾼配，都能跑满服务器性能，所以PHP的实践配置是根据业务

访问量来决定的。PHP的进程管理，在实践中低配适⽤于动态模式，

⾼配适⽤于静态模式，这会让PHP的性能达到最优。由此也可以看

到，PHP的多进程的模式相⽐于Tomcat单进程多线程的模式，在性能

架构⽅⾯更优。

·Nginx是轻量级的⾼性能中间件，Nginx基于Epoll⽹络I/O模型，

在⾼并发场景下对性能消耗很低。如果在服务器上仅部署Nginx做转

发，2核4G/4核8G的配置⾜够了，⽆须8核16G的⾼配。如果

Nginx+PHP做FastCGI，更多性能的消耗在于PHP，所以⼀般⽤4核

8GB/8核16GB的经典配置。

·Apache基于Select⽹络模型，偏向计算型中间件。所以在服务器

配置中，起码⽤4核8GB，有⼀定业务量推荐⽤8核16GB。

·Squid对多核利⽤不太好，所以适合⽤2核4GB、4核8GB的中低配

配置。

·Python、Node和PHP都是进程运⾏的模式，Supervisor对Python做

进程管理、PM2对Node做进程管理，就如同PHP-FPM对PHP做进程管

理。Python、Node、PHP都偏向应⽤代码运⾏，对CPU和内存性能都

有要求。中⼩型应⽤⽤2核4GB、4核8GB中低配，中⼤型应⽤⽤4核

8GB、8核16GB中⾼配即可。

3.CPU与内存资源配⽐：1∶4

1∶4的配⽐，⽐如，2核8GB、4核16GB、8核32GB。这类配⽐的配

置偏向内存，特别适合部署数据库类的应⽤。⽐如，当RDS满⾜不了

业务需求，需要⾃⾏在ECS上搭建的时候，8核32GB是保障数据库具

有良好性能的经典配置。但值得注意的是，数据库类应⽤涉及数据持

久化，需要SSD云盘提供⾼存储IOPS且低读写延时。

数据库对服务器性能的需求⾸先是I/O，因为数据库是个存储类应

⽤，涉及数据持久化，所以对I/O性能的要求是最⾼的。其次才是内

存，因为⾼内存会有效提升数据库的缓存性能，很⼤程度上提升数据

库的性能。特别是MongoDB基于内存映射，⼤内存配置能有效地发挥

出MongoDB的性能特点。最后，数据库其实对CPU的要求并不是那么

⾼，所以偏向内存的配⽐配置，特别适⽤于部署数据库类的应⽤。

4.CPU与内存资源配⽐：1∶8

处理器与内存资源配⽐为1：8，⽐如，2核16GB、4核32GB、8核

64GB，这类是⾼内存资源占⽐。尤其适⽤于数据库类中的内存型应

⽤，⽐如，Redis、Memcache的部署。

在实践中，如果⽤8核16GB部署⼀台Redis，会造成性能过剩。在

缓存选型中也跟⼤家介绍过，Redis是单进程单线程模式，对多核利⽤

得不太好，所以适合偏向⽤1∶4/1∶8的2核8GB/2核16GB⾼内存资源占⽐

的配置。当然如果想要Redis把多核的性能资源利⽤好的话，可以跟

Tomcat⼀样，在⼀台机器上部署多个Redis实例。

5.根据业务特别配置选项

根据不同业务的特点，消耗的资源偏向也是不同的。⽤户可以参

考⾃⾝业务特别来选择对应的资源，参考实例如下：

·对于存储型业务，如百度⽹盘。其主要业务就是存储⽤户的⽂

件，主要消耗的资源偏向存储空间。

·对于计算型业务，如游戏⾏业。其主要业务就是游戏引擎的计

算，主要消耗的资源偏向CPU。

·对于流量型业务，如优酷。其主要业务就是通过⽹络传输视频⽂

件，主要消耗的是⽹络带宽。

介绍到这⾥，相信⼤家对服务器CPU/内存配置选型有了⽐较清楚

的理解。但是除了CPU和内存的配置之外，服务器的配置还有磁盘、

带宽配置等。带宽配置的选型接下来会给⼤家详细介绍，⾄于磁盘空

间的选型，即⽤多⼤空间的磁盘，要简单得多。磁盘空间的选择参考

如下：

·如果没有⽂件存储，只有系统⽇常基础⽇志存储，系统磁盘就⾜

够了。

·部署代码的应⽤，都有代码⽇志存放的需求，这时候⼀般系统盘

默认的40GB容量空间满⾜不了存储需求。⼤部分场景需求都是存放业

务代码、存放代码⽇志⽂件，所以常规的100～300GB磁盘空间是标

配。磁盘空间利⽤率⼀般不⾼，建议结合线上实际⽤量，合理利⽤。

·除了存放业务代码、代码⽇志外，还有很多需求就是存放应⽤相

关的数据⽂件，如⽤户上传的⽂件数据等。对此，根据⽤户量、⽂件

⼤⼩等，都能评估出所需要的磁盘空间的⼤⼩。

·数据库类的应⽤，磁盘空间⼀般需求较⼤，都是500GB以上。要

存储数据库的Binlog、数据⽂件、备份等，则需要较⼤的存储空间。

另外，数据库主要满⾜的是数据读写的需求，所以对磁盘I/O有⼀定要

求，⼀般采⽤SSD云盘。

云诀窍

通过实践发现，100GB、300GB、500GB存储空间是企业对服务

器磁盘配置的标配，但同时80%的企业服务器的磁盘利⽤率仅在20%

～30%。

5.4 云端带宽配置选型

带宽配置的选型，同样需要经过业务访问量与性能压⼒指标转换

的这关键⼀步。然后通过得到的性能压⼒指标，就可以转换估算出⼤

概需要的带宽量。⽽云端带宽类型选择的8/2原则，也体现了云计算按

需所取的优势特点。

5.4.1 带宽配置估算模型

曾经有⼀个带宽配置的极端案例，某母婴闲置交易电商平台，开

发⼈员选择的服务器配置是8核16GB 50Mbps的固定带宽配置。还⼀次

性买了10台，每台服务器配置每个⽉消费近5000元⼈民币。这是⼀个

配置选项失败的极端案例，主要原因在于业务⼈员对带宽的配置完全

没有概念：

·采⽤50Mbps固定带宽，出现带宽利⽤严重过剩的问题。核⼼点在

于未能将业务访问量有效转换成开发⼈员所熟悉的带宽性能数据，这

导致⼤多⽤户对带宽配置选择完全没概念。相⽐于CPU/内存/磁盘的配

置，对带宽配置更是茫然⽆知，所以只好选择固定的⾼带宽。

·如果需求只是⼊⼜流量，带宽⼀般采⽤SLB，带宽性能、架构扩

展、安全性都⽐ECS直接绑定公⽹带宽要好。此⽤户业务，主要采⽤

SLB，所以如果只是⼊⼜流量需求，没必要给后端配置⾼配的固定带

宽。

·如果需求是出⼜流量，需要主动去访问公⽹服务，需要配置公⽹

带宽。这⾥采⽤SNAT的⽅式（那时候还没有NAT⽹关服务），更不需

要给每台服务器都绑定这么⾼配的固定带宽。

·即使开了50Mbps的带宽，默认也要选择按使⽤流量的带宽类型，

这样可以节省⾼昂的费⽤。即使选择固定带宽，场景也是⾮常苛刻

的，后⾯会跟⼤家详细介绍。

对于已上线的业务估算带宽配置，看平时带宽的峰值即可。如果

业务还处于前期需求规划期间，对于带宽配置的评估，关键还是先把

业务请求量（这⾥⽤的更多的是PV量，如果是其他业务请求量，要先

转换为对应的PV请求量）先转换成每秒请求量，然后再把每秒请求量

转换为带宽配置。

带宽计算模型：

带宽配置=每秒请求数量×每次请求传输的数据量

=（80%×总PV量）/（24⼩时×60分×60秒×40%）×X Mbps/s 经实践发现，在Web类的应⽤中，80%的带宽会被静态资源传输

占⽤，如果采⽤CDN，能够有效减⼩后端服务器的带宽配置。假设每

个请求页⾯平均传输数据是20KB（不包含图⽚等静态资源，否则流量

更⼤），则针对100万PV和500万PV的⽹站，要选择的带宽配置如

下：

100万PV带宽配置（平时访问量）=（80%×100万）/（24⼩时×60

分×60秒×40%）×20KB/s=23.1个请求/秒×20KB/s=462KB/s（⼤B的单

位）=3696bps/s（转换成⼩b），即3.5Mbps

100万PV带宽配置（峰值的2倍）=（80%×100万）/（24⼩时×60

分×60秒×40%）×2倍×20KB/s=46.2个请求/秒×20KB/s=924KB/s（⼤B

的单位）=7392bps/s（转换成⼩b），即7Mbps

100万PV带宽配置（峰值的3倍）=（80%×100万）/（24⼩时×60

分×60秒×40%）×3倍×20KB/s=69.3个请求/秒×20KB/s=1386KB/s（⼤B

的单位）=11088bps/s（转换成⼩b），即11Mbps

500万PV带宽配置（平时访问）=（80%×100万）/（24⼩时×60分

×60秒×40%）×20KB/s=115.7个请求/秒×20KB/s=2314KB/s（⼤B的单

位）=18512bps/s（转换成⼩b），即18.5Mbps

500万PV带宽配置（峰值的2倍）=（80%×100万）/（24⼩时×60

分×60秒×40%）×2倍×20KB/s=231.4个请求/秒×20KB/s=4628KB/s（⼤

B的单位）=37024bps/s（转换成⼩b），即37Mbps

500万PV带宽配置（峰值的3倍）=（80%×100万）/（24⼩时×60

分×60秒×40%）×3倍×20KB/s=347.1个请求/秒×20KB/s=6942KB/s（⼤

B的单位）=55536bps/s（转换成⼩b），即55Mbps

5.4.2 带宽类型选择的8/2原则

在云端配置实践中，在关于SLB、ECS、EIP的带宽类型选择上，

很多⼈选择固定带宽。⽐如，1Mbps、2Mbps、5Mbps、10Mbps、

20Mbps，事实上，⼤多数情况下是没有必要的。在云端带宽配置的选

择中：

·80%的应⽤默认选择按量带宽，即按量带宽是云端带宽类型选择

的最佳实践。

·20%的应⽤选择固定带宽。这个特定的条件就是，如若每天按量

下载的量合计费⽤超过带宽平均每天费⽤，则使⽤固定带宽。

实践案例1：固定带宽与按量带宽费⽤对⽐

固定带宽和按量带宽费⽤对⽐，如表5-4所⽰。

表5-4 固定带宽和按量带宽费⽤对⽐表

通过以上计算可知，如若使⽤5Mbps峰值带宽，每天业务产⽣的流

量超过5.25GB，那么这时候使⽤固定带宽才划算。当每天业务产⽣的

流量低于5.25GB的时候，优先使⽤按量付费。

我们发现往往80%的情况都是每天业务产⽣的实际流量是低于固定

带宽的成本的，⽐如：

·很多⽤户选择1～5Mbps的固定带宽，是为了进⾏远程连接管理，

或者访问服务器上某个应⽤需要开个公⽹带宽。⽽这时候每天访问产

⽣的流量是很低的，完全没必要使⽤固定带宽。

·⽽选择5Mbps以上的固定带宽，多半是为了业务的访问考虑。如

果数据传输（如异地备份），每天产⽣的⼤流量导致使⽤按量成本较

⾼，这时候才采⽤固定带宽。

实践案例2：按量带宽实践案例

在2014年有⼀个上云迁移的客户案例，客户主要是做股票投资的

视频直播。在IDC机房中租⽤对应的服务器和带宽，不仅费⽤⾼昂，还

经常被别⼈刷流量进⾏DDoS攻击，视频直播常在⾼峰期卡顿。想通过

迁移到云上解决安全、成本、性能的问题。其配置清单如下：

8核16GB/300GB/20Mbps固定带宽×1台费⽤：2300元/⽉

但是，迁移到云上并没有有效解决其成本问题，虽然⽐IDC的租⽤

费⽤少些，但实际上没有太⼤成本差别。另外，客户访问还是很卡。

因此，客户想把业务再迁回IDC。此时，我们在与客户接触后，了解到

其业务问题所在，并据此简单换了⼀下使⽤⽅式。变更后的配置清单

如下：

8核16GB/300GB/2Mbps按量带宽+SLB按量（峰值不限）费⽤：

896元/⽉+300元/⽉按量（实际的账单费⽤数据）

流量⾛SLB，并且放开带宽峰值且使⽤按量带宽，结果不仅降低了

成本，还提升了⽤户的访问速度。因为我们发现客户的业务特点是：

在⼀天上午特定1⼩时内进⾏直播，直播流量很⼤，并且有时候超过

20Mbps的固定带宽峰值。⽽其他时间点流量都不⾼，所以这个场景特

别适⽤按量的带宽。选择SLB并且是1Gbps的带宽峰值，相⽐于ECS带

宽的性能及稳定性更好，并且成本上可节省1100元/⽉，⽽且效率变⾼

了。2Mbps的按量带宽，也仅⽤于远程管理服务器，产⽣的流量费⽤⼏

乎可以忽略不计，并且云上的5Gbps的免费防御DDoS攻击流量，基本

上可以防御⼩规模的流量攻击。

第⼆篇 云端实践篇

·第6章 云主机实践

·第7章 云端负载均衡实践

·第8章 云端存储实践

·第9章 云端缓存实践

·第10章 云端数据库实践

·第11章 云端运维实践

·第12章 云端监控实践

·第13章 云端容器/DevOps实践

本篇是基于云端选型篇，在云端运维架构涉及的常见技术的重要

实践，也是本书的重点篇幅，包含云端云主机、云端负载均衡、云端

存储、云端缓存、云端数据库等云端最热门的技术实践，并且结合上

云迁移、云端混合云及容器、云端运维实践这3类云端最常见的热门需

求给出真实的客户案例，从⽽分享云端混合云技术架构、云端容器技

术架构、云端监控、云端⾃动化运维等当前最热门的技术实践。

第6章 云主机实践

云主机是云平台最为核⼼的产品，其最核⼼的⽤途是可直接部署

业务，即ECS是⽀撑业务运⾏的基⽯。在ECS上也可以部署数据库、

负载均衡、存储、缓存等系统服务，并提供给业务使⽤，这也是ECS

最不可少的⽤途之⼀。同时云的⾼可⽤性、⾼可扩展性、按需所取、

低成本、灵活管理等特性，也会在云主机上直接得到体现。

通过云主机的两个核⼼⽤途（⼀个是⽤于代码部署，另⼀个是⽤

于部署⼀些业务所需的系统服务），我们可以看到，云主机这款产品

随着云技术的发展，可能会被逐步淡化甚⾄淘汰掉。因为⼤部分需求

已⽆须我们⾃⾏在云主机上搭建数据库、负载均衡、存储、缓存等系

统服务来实现了，只需要⾃⾏购买RDS、SLB、OSS、CDN等云产品

即可。⽽云主机仅运⾏代码（如Java、PHP、Python、Node）的功

能，也可以被新的云产品功能替换掉。早些年，阿⾥云推出过⼀款

ACE云代码托管引擎，即可以把代码直接传到该引擎上托管执⾏，从

⽽不⽤再对它进⾏监控、维护、扩展、调优等操作。不过，可能那时

候这款产品太超前，加上其产品功能还不够完善，有诸多限制，最终

它没能存活下来。但是Kubernetes技术的⽇益成熟以及普遍应⽤，让

我们可以从中看到未来代码运⾏技术的趋势，对⽤户⽽⾔，肯定会是

⽆服务器、⽆操作系统的全新概念。

相⽐于传统硬件服务器的本地磁盘存储、⼀台物理服务器⽀撑、

共享IP、不⽀持快照/镜像的特点，云主机具有基于⽹络分布式集群存

储、多台物理服务器⽀撑、独⽴IP、云镜像/云快照等特点。它完成了

从单机版到分布式版的蜕变，因⽽有了⾼可⽤性、⾼可扩展性、按需

索取、低成本、灵活管理等特性。但云主机在⽹络、分布式架构、⾃

动化管理⽅⾯的新特性也决定了云端实践的新特性。经过多年的实践

来看，这些新特性也是具备划时代意义的。

6.1 云⽹络下的业务新架构

在如红警、魔兽等游戏流⾏的年代，其实也是IDC物理硬件盛⾏的

年代。那时候打游戏“进⼊房间”时能明显地感觉到，电信专区、⽹通

专区、移动专区的速度是不⼀样的（见图6-1）。如若你家的宽带是电

信的，那么进⼊⽹通专区⾥⾯，那真会卡的⼀步都操作不了。

图6-1 游戏中不同运营商分区⽰例

这是IDC⽹络架构的通病，即中国基础⽹络的运营商、⽤户都具有

区域性，联通⽤户多分布在北⽅，⽽电信⽤户多分布在华东、华南，

这就导致了经典的南北互通问题，即南⽅电信与北⽅联通线路之间的

互访很慢。传统IDC的双线机房就是⽤于解决这个问题的，即在服务器

上绑定两个公⽹IP，⼀个是联通公⽹IP，另⼀个是电信公⽹IP，客户发

出请求时根据⾃⾝⽹络运营商选择访问对应的⽬标IP，从⽽避免出现

卡顿的问题。但是这种解决⽅式的灵活性并不是很⾼，并没有从本质

上有效地解决该问题。

云⽹络的出现，从根本上有效地解决了该问题。云⽹络其实也不

是什么复杂的技术，其本质就是BGP⽹络，只不过云⽹络将BGP⽹络

进⾏了普及。在传统存在南北互通问题的⽹络架构下，最⼤的问题就

是路由的问题。⽐如，我们的服务器放在上海电信的机房，深圳⼀位

联通⽤户在访问我们的服务器时，要先绕到联通的⼴州总出⼜，然后

再绕回上海。⼤多数联通⽤户访问电信⽹络时都这么绕着⾛，这样总

出⼜带宽就会遇到瓶颈，然后访问就被卡住了，甚⾄直接卡到不能进

⾏正常的业务访问。事实上，BGP线路之所以能解决这个问题，就是

因为其解决了路由选择的问题，即能决定⾛什么路由过来，不绕远

路，这样⼀来，问题⾃然就解决了。路由的问题解决了，BGP不仅能

实现南北互通，⽽且也能解决其他⽹络的互通问题。⽐如，教育⽹、

移动⽹等，因为它有权限决定路由，所以也就可以优化路由，这条路

堵，就换条路。云平台使⽤BGP线路，具有较⾼的⽹络质量及速度，

这是⾮常具有吸引⼒的实⽤特性。阿⾥云杭州千岛湖机房更是可供8家

运营商同时接⼊，如果按照双线机房概念来理解，那就是⼋线机房

了，即⼀个公⽹IP能对应8家运营商⽹络线路。

所以在云端，我们就不⽤再考虑移动、⽹通、电信还需要分别对

应运营商的⽹络单独去部署了。⽽现在的⼀些⽹络竞技游戏、对战平

台等，也很难再看到所谓的电信区、⽹通区。如若业务还停留在这个

时代下的⽹络架构，那么它们终归会被云时代所淘汰。⽐如，现在如

⽕如荼的热门游戏王者荣耀，就直接按照1到100的数字排列来简单划

分不同服务区，⽽不再单独划分电信专区、⽹通专区，其云端游戏的

分区如图6-2所⽰，电信、⽹通、移动等⽤户可以直接随意进⼊。

图6-2 云端游戏的分区

6.2 云的技术本质优势

传统的物理机环境强调的是单⼀系统的纵向扩展能⼒，即

IOE（IBM⼩型机+Oracle+EMC存储）架构的硬件，就是通过单机性能

的纵向扩展来满⾜业务对计算资源的需求。随着互联⽹发展、多系统

海量计算性能的需求，传统物理机下的技术架构很难再⽀撑。云计算

的出现，解决了多系统的横向扩展问题，即通过添加⼤量廉价云主机

的横扩展来满⾜不同业务对海量计算资源的需求。我们可以看到传统

物理机技术架构单⼀作战能⼒凶猛强悍，如同猛虎。⽽云计算下的技

术架构的特点是群体作战能⼒势如破⽵，如群狼，最终猛虎也难以招

架住群狼。⽽“群狼战术”的本质就是如今分布式架构的特点，云计算

的普及，也推进了分布式架构的发展。

6.2.1 云主机与硬件服务器性能对⽐的误区

早期，很多客户觉得云主机的性能⽐较差，更有⽤户直接⽤传统

的性能压测⼯具来评估云主机的性能。最终发现两者性能的差距主要

体现在CPU和磁盘I/O上，传统硬件服务器的⾼频+超线程CPU、磁盘

阵列+SSD磁盘，让硬件服务器的性能更强悍。特别是IOE架构的硬

件，更是让云主机在性能上没办法匹配，可以说硬件服务器完胜。这

是因为云主机底层基于虚拟化，针对很多物理机虚拟出了很多的云主

机（类似VPS虚拟机，只不过和VPS虚拟机不同的是，云主机是基于

分布式的，没有单点问题），主要解决了IDC时代下资源利⽤的问

题。

云诀窍

阿⾥云飞天系统早期的底层虚拟化基于XEN技术，同时能⽀持

5000台物理机集群。后来飞天系统底层虚拟化改为基于KVM，能同时

⽀持20000台集群。技术上有了很⼤改进，并且引⼊了SSD云盘，在性

能和稳定性上相对于XEN版本来讲，得到了很⼤的改善。

所以“资源共享，按需使⽤”是云计算区别于传统IT架构的关键及

核⼼，也是云计算模式最⼤的优势所在。⽆论是计算、存储还是⽹

络，⽤户享受到的技术及价格红利都离不开共享的作⽤。可以说脱离

了共享，云计算就⽆从谈及。阿⾥云针对不同的业务场景需求，实际

上提供了两类产品：共享型、独享型，这样就可以满⾜⽤户不同场景

下对计算资源性能的需求，共享型实例如图6-3所⽰。

共享型实例系统采⽤的是随机的更贪婪的调度CPU的模式，⼀个

核的使⽤可能会调度分配给不同的云主机实例。所以如若⼀个实例占

⽤导致CPU飙⾼，可能也会导致其他实例出现CPU负载飙⾼且性能不

稳定，其实这类性能异常在实践中我们也经常遇到。相⽐于共享型实

例，独享型实例⽤系统固定调度CPU模式，⼀个核的使⽤会固定调度

给某云主机实例，不会因为其他⽤户的资源使⽤繁忙或空闲⽽产⽣波

动，独享型实例如图6-4所⽰。

图6-3 共享型实例底层物理资源分配

图6-4 独享型实例底层物理资源分配

但独享型实例系统的本质还是共享资源，只不过是在细分的核数

上看似为独享。独享型是在底层硬件计算资源上，将计算资源（核

数、磁盘、内存、⽹络）划分给⼀个公共的“⼤池⼦”（云计算平

台），⽤户按需索取相应的计算资源即可，多个⽤户共同使⽤这个⼤

的计算资源池。

虽然资源共享带来了资源利⽤、按需使⽤、弹性管理及伸缩、成

本上的优势，但是同时也带来了性能问题。可想⽽知，⼤家同时使⽤

⼀个底层计算资源与⾃⼰独占底层硬件计算资源，两者相⽐⾃然是独

占的性能最⾼。所以把云主机的性能和传统硬件服务器的性能做对

⽐，是没多⼤意义的。⼀⽅⾯，硬件服务器的性能肯定完胜，这是必

然结果。另⼀⽅⾯，云平台的优势其实并不在这⾥。所以嫌弃云主机

性能差，觉得还不如迁到IDC⾥⾯使⽤硬件服务器的⽤户，是没能真

正地理解云的特点及优势的。对云主机的性能进⾏评测，以便对容量

进⾏规划（⽤多少台服务器），这才是有意义的。

6.2.2 云的本质优势在于分布式架构

正如前⾯所说的，单纯地⽐较单台物理硬件和单台云主机的性能

是没多⼤意义的。云的发展，其实也是分布式架构的普及以及发展。

技术架构的发展，已经从单机架构到分布式架构，再到如今的微服务

架构，所以如若业务对单机性能要求很⾼，只能进⾏垂直扩展（即升

级服务器配置）来解决性能问题，⽽不能进⾏⽔平扩展（通过简单加

服务器），显然这样的业务不能真正发挥云平台的优势，甚⾄不适合

云平台。极端情况下，使⽤云主机还不如使⽤单台物理机。

所以在云端实践中，不要把云主机当成硬件服务器来使⽤，也不

要指望通过升级服务器配置来解决业务性能扩展问题。阿⾥云IOE架

构（后来业务基本全部部署在阿⾥云上）的核⼼其实也是分布式架

构，去除对底层⾼配性能硬件的依赖，在架构上考虑采⽤海量低配硬

件资源来满⾜庞⼤的业务量需求。

6.3 云时代下的资源⾃动化管理

云平台其实是⾃动化最⾼的实现，在云平台（阿⾥云管理控制

台）上管理ECS，其实就是智能操作，既简单又快捷。

·灵活的资源类型：包年包⽉、按量付费。

·灵活的地域选择：华东1（杭州）、华东2（上海）、华北1（青

岛）、华北2（北京）、华北3（张家⼜）、华北5（呼可浩特）、华南

1（深圳）、西南1（成都）、澳⼤利亚（悉尼）、马来西亚（吉隆

坡）、印度尼西亚（吉隆坡）、⽇本（东京）、新加坡、德国（法兰

克福）、英国（伦敦）、美国（硅⾕）、美国（弗吉利亚）、印度

（孟买）、阿联酋（迪拜）等。

·灵活的配置选择：1核、2核、4核、8核、16核等。

·灵活的带宽选择：按固定带宽、按使⽤流量选择。

·灵活的环境配置：各种Web类、数据库类等ECS镜像，环境⼀键

式安装。

·Web界⾯全⾃动化操作：启动、停⽌、重置密码、升降配、安全

组配置、快照/镜像管理、创建相同配置/相同环境机器等。

在IDC上架设⼀台服务器，要先购买服务器、安装基础环境，然后

上架机房，整个流程⼗分烦琐⽽且效率低下。⽽在云时代，你会发现

资源管理是如此快捷⽅便，上架⼀台服务器，就跟在淘宝⽹上购物⼀

样⽅便。进⾏环境配置、软件部署时，就跟选择商品型号⼀样简单。

⽽且，不仅是在Web控制台上操作⽅便，随着云API的推出，还能让我

们通过代码接⼜管理云端资源。API的开放，意味着云时代下⾯的资源

管理控制完全不需要⼈⼯⼲预，全部都可以交给程序完成。如图6-5所

⽰，通过简单的命令和参数，就能创建⼀台ECS。

图6-5 API创建ECS

⽐如在红⽶⼿机的秒杀活动中，会瞬间开启200台机器且持续两⼩

时来应对，然⽽IT资源才消费了600元⼈民币：

1）搭建好环境，制作好镜像。

2）活动前通过API秒开200台服务器来应对活动。

3）活动结束后，通过API瞬间释放资源。

⽽这要是在传统IT架构中，则根本不敢想象。⽐如，之前云平台

出现的电商公司，每年“双⼗⼀”，都会提前⼀个⽉准备IT资源及相关环

境部署，⽽如今采⽤云端运维，在Linux系统中通过简单的Shell或者

Python脚本就能灵活管理、控制资源。不过对于此类功能在云端已经做

成成熟的产品了，如ESS弹性伸缩，它能动态调整弹性计算资源，实现

真正意义上的⽆须⼈⼯⼲预、资源动态伸缩。

第7章 云端负载均衡实践

很多⼈把集群架构和分布式架构混为⼀谈，这其实是个很⼤的认

识误区。集群架构主要是热备的⾼可⽤架构，它通常采⽤虚拟VIP技

术（如Keeplived、Hearbeat）来解决单点故障的问题，让架构⾼可

⽤。集群的虚拟VIP技术只能让⼀台服务器平时作为Backup热备，只

有在出现故障的时候才会切换到Backup上，平时Backup热备都处于空

闲状态。分布式架构的技术特点就是引⼊了负载均衡，让不同服务器

来同时处理业务压⼒。负载均衡是分布式架构的起点，⾼可⽤架构底

层最需要及最依赖的就是负载均衡。本章在传统开源负载均衡经验的

基础上，结合云平台的最佳实践经验进⾏讲解，让读者对负载均衡技

术有个全新的认识。

7.1 “1+1>2”经典架构

“1+1>2”的经典架构是分布式架构的精髓，也是理解云的本质优势

在于分布式架构的核⼼点。

单机部署思路：⼀台配置为4核8GB的主机，部署着⼀个分布式业

务，如传统电商系统。

分布式架构部署思路：如若将4核8GB的主机拆分成两台配置为2

核4GB的主机，那么通过负载均衡部署效果会有什么不⼀样？

单机部署与两台部署的架构对⽐如表7-1所⽰。

表7-1 单机部署与两台部署的架构对⽐

相⽐于单机部署，我们可以看到拆分成两台机器+SLB部署后在成

本⽅⾯相差不⼤，但在带宽性能、磁盘性能、安全性、可扩展性、稳

定性⽅⾯都⽐单机部署要⾼出许多。值得⼀提的是，为什么说SLB具有

抗攻击能⼒？这在第⼀篇中也介绍过，SLB四层采⽤LVS，新增了

SYNProxy等TCP标志位，具有DDoS攻击防御功能。

如果要问拆分成两台部署有什么缺点，那就是在管理维护⽅⾯变

复杂了。但在如今，这也不值得⼀提，服务器动辄⼏⼗台、上百台规

模，云平台的⾃动化也会降低管理维护成本。所以总的来看，从架构

⾓度上来说“1+1”是⼤于2的，⽽且是远远⼤于2的。

7.2 单机+SLB架构的必要性

很多⼈觉得单机前⾯添加⼀个SLB是多此⼀举，有些客户甚⾄怀疑

给他们开了多余的资源，故意增加他们的预算等。下⾯先看表7-2所⽰

的单机与单机+SLB架构对⽐。

表7-2 单机与单机+SLB架构对⽐

相⽐于单机部署，单机+SLB部署虽然稳定性上也存在单点故障，

但是在性能、安全性、可扩展性⽅⾯依然有很⼤优势。关键是在可扩

展性上两者有本质区别。单机版的时候，业务的域名IP直接绑定在ECS

的公⽹IP上。如若后期业务量增加，没办法采⽤⼀台服务器来应对业

务量，那么就得引⼊SLB，或者在ECS上⾃建Nginx等负载均衡。这时

候域名要重新解析到新的IP地址上，因此需要中断业务。相⽐较⽽

⾔，单机+SLB的⽅式，虽然SLB后⾯只有⼀台机器，但业务域名解析

的IP地址⽤的是SLB的IP地址。如果后期业务量增加，只需要在SLB中

加⼊新的服务器即可，⽽且对⽤户请求端来讲，这完全是⽆感知的，

也不需要中断业务。

由此可见，单机+SLB架构并⾮毫⽆⽤处，实则是必不可少的。

7.3 被LBHA误导的架构

下⾯来看某汽车官⽹的⼀个案例（PHP）。

客户第⼀次提出的需求：要避免单点故障！

客户第⼆次提出的需求：要⾼可⽤！

客户第三次提出的需求：PHP最好配置Session化管理，因为从⽹

上资料来看，分布式Session管理要更好些。

客户最后提出的需求：Session⽂件不要放在磁盘上，⽽是放在内

存⽂件系统中（tmpfs），以保障业务访问速度。

这个案例之所以让我印象深刻，是因为⼀个简单的企业宣传官

⽹，并没有多少⼈访问，客户的三⼤需求，却是按照千万级架构标准

要求提出的，这显然是不合理的。

如果是给上海证券交易所部署阿⾥云的专有云，私有化部署驻云

CBIS云管控平台，客户提出跨机房⾼可⽤的部署⽅案。因为客户业务

是重要的⾦融领域业务，对业务⾼可⽤性有极⾼的要求，所以我们在

架构设计、架构部署上是需要额外花费巨⼤成本投⼊的，这个要求是

合理的，因为业务系统的重要性且对业务系统宕机极其敏感（损失按

秒计算）。

⼤家都知道负载均衡（LB）和⾼可⽤（HA）的概念。但是什么

时候⽤分布式架构，什么时候⽤⾼可⽤架构，其实需要根据业务情况

来定。业务没有到达⾦融证券、淘宝这样的量级，对业务中断时间的

担忧是过分的敏感和担⼼。对于⼀个本⾝没有多少业务访问量的官⽹

来说，即使宕机，对公司业务的影响也不⼤，能在⼩时级别、分钟级

别快速恢复即可。所以对简单业务⽽⾔，没必要花费额外成本在⾼可

⽤、负载均衡⽅⾯，还给后期管理维护平添⿇烦。相反，如果业务规

模、业务重要性要求能在秒级内恢复等，就需要额外的成本投⼊在⾼

可⽤的架构保障中，⽽不要单纯为了分布式⽽做分布式，为了架构⽽

做架构。

7.4 DNS的两⼤主流实践

设置域名A解析记录、CNAME解析记录、邮箱服务器等，这是

DNS域名解析设置的核⼼功能。⼤家⼀直以为DNS只能做域名解析，

并且在传统物理机架构的应⽤中，DNS作为负载均衡也⼀直不被看

好。随着分布式架构的普及和发展，DNS在云端负载均衡的实践中迎

来了“咸鱼⼤翻⾝”，并且凭借核⼼秘密的智能解析功能，在CDN、跨

地域分布式架构中得到⼴泛且重要的应⽤。

7.4.1 实践⼀：不推荐DNS作为负载均衡的误区

在传统负载均衡实践中，通常都不推荐⽤DNS做负载均衡。DNS

负载均衡⽰意图如图7-1所⽰。

在图7-1中，为域名配置多个A解析地址，这样不同的⽤户请求域

名会返回不同的解析IP地址，⽤户请求到不同的后端⽬标服务器地

址，从⽽达到了分流分压的⽬的。但DNS作为负载均衡会遇到常规的

⼏个问题：

图7-1 DNS负载均衡

·本地DNS缓存问题：DNS如若剔除IP，则可能会因为⽤户客户端

是本地DNS缓存，⽽导致他们所访问的地址还是原来的IP地址。

·负载不均衡的问题：DNS调度算法仅⽀持轮询，⽽且它会根据客

户端源IP请求来返回不同的解析地址。由于很多企业都是采⽤SNAT上

⽹的模式，如若源IP的企业⼈员多，那么⽤户请求也就会多，⽽若源IP

企业⼈员少，那么⽤户请求也少最终⽬标服务器就会出现负载不均衡

的现象。

·⾼可⽤的问题：攻击防御能⼒很弱，每次出现攻击就靠⼀台机器

⽀撑。⼀旦这台机器出现故障，后续解析到这台机器的访问请求都将

是异常的。

图7-2 DNS负载均衡在ECS中的应⽤

在云端实践中，云解析DNS在负载均衡中的实践是⾮常成熟的，

已经达到企业级应⽤标准，在很多实践⽅案中都会⽤到，基本上告别

了不推荐使⽤DNS做负载均衡的时代。但云端对DNS的应⽤，相⽐传

统使⽤DNS来做负载均衡的架构是不⼀样的。如图7-2所⽰。

DNS的A解析记录配置多条ECS的公⽹IP，但依然是传统DNS部署

架构，相⽐于物理服务器，虽然ECS的故障能快速恢复，但整体上并未

改变，⽬前不推荐这种部署架构。如果换成如图7-3所⽰的部署架构会

有什么不同呢？

DNS的A解析记录IP地址配置为SLB的IP地址，这样暴露给DNS的

解析IP是集群IP地址，负载均衡后⾯往往挂着多台服务器。相⽐DNS直

接把IP解析到ECS上，⾼可⽤的问题就解决了。但是在这⾥我们发现负

载不均衡的问题还是未能解决。即SLB1上、SLB2上流⼊的流量不均

衡，可能导致⼀个流量偏⾼，⼀个流量偏低，最终后⾯的ECS计算资源

并不能得到有效利⽤。下⾯再对架构进⾏调整，如图7-4所⽰。

图7-3 DNS负载均衡在SLB中的应⽤（1）

图7-4 DNS负载均衡在SLB中的应⽤（2）

图7-4中，ECS分别挂载到了不同的SLB上，即使前端两个SLB的流

⼊流量不同，但最终请求流量都是转到后端ECS服务器进⾏处理。所以

采⽤DNS引起的负载不均衡的问题就被解决了。但是这个架构有⼀个

新的问题，就是只有4台ECS服务器，却要⽤两个SLB，且要将DNS的

A解析到两个地址上。原本⼀个SLB就可以解决的事情，现在变成两个

SLB，增加了维护管理成本，将原本简单的事情复杂化，这显然是不合

理的。所以中⼩型架构并不适合以DNS作为负载均衡。DNS的负载均

衡架构，主要适合⼤规模应⽤。当后端有⼀两百台ECS，⽽⼀台SLB的

性能又有限时，此时采⽤多个SLB，DNS调⽤的优势和必要性就体现出

来了。通过Nslookup淘宝和阿⾥云官⽹我们发现，其实这两者都是采

⽤DNS作为负载均衡的架构，即返回了多个解析IP地址。

Nslookup查询域名www.taobao.com的DNS记录结果如下：

Server:202.96.209.133

Address:202.96.209.133#53

Non-authoritative answer:

www.taobao.com canonical name = www.taobao.com.danuoyi.tbcache.com.

Name: www.taobao.com.danuoyi.tbcache.com

Address: 114.80.184.124

Name: www.taobao.com.danuoyi.tbcache.com

Address: 101.227.209.252

Name: www.taobao.com.danuoyi.tbcache.com

Address: 114.80.174.46

Name: www.taobao.com.danuoyi.tbcache.com

Address: 114.80.184.125

Nslookup查询域名www.aliyun.com的DNS记录结果如下：

Server: 202.96.209.133

Address: 202.96.209.133#53

Non-authoritative answer:

www.aliyun.com canonical name = www-jp-de-intl-adns.aliyun.com.

www-jp-de-intl-adns.aliyun.com canonical name = www-p-de-intl-adns.aliyun.com.gds.alibabadns.com.

www-jp-de-intl-adns.aliyun.com.gds.alibabadns.com canonical name =

v6wagbridge.aliyun.com.

v6wagbridge.aliyun.com canonical name = v6wagbridge.aliyun.com.gds.alibabadns.com.

Name: v6wagbridge.aliyun.com.gds.alibabadns.com

Address: 140.205.230.13

Name: v6wagbridge.aliyun.com.gds.alibabadns.com

Address: 140.205.34.3

Name: v6wagbridge.aliyun.com.gds.alibabadns.com

Address: 140.205.32.4

Name: v6wagbridge.aliyun.com.gds.alibabadns.com

Address: 106.11.93.21

实践证明，不推荐使⽤DNS作为负载均衡其实是个认识误区。但

DNS作为负载均衡还有⼀个问题没有解决，那就是本地DNS缓存的问

题。不过随着云时代的普及以及技术的发展，这⽅⾯所带来的问题⼏

乎可以忽略不计。

⼀⽅⾯，域名云解析的TTL（域名变更⽣效时间）已经在秒级，⼏

乎是实时⽣效（个⼈版TTL是10分钟（600秒）、企业标准版TTL是1分

钟（60秒）、企业旗舰版TTL是1秒）。

另⼀⽅⾯，采⽤DNS负载均衡，在实际应⽤中后端很少采⽤ECS的

IP，后端解析的IP地址都是集群IP地址。所以本⾝来讲，集群就考虑到

⾼可⽤性，后端业务⼊⼜出现故障的可能性很⼩。这就使得在实际应

⽤中，需要调整DNS解析的情况很少。

即便要调整DNS，但在实践中，由于TTL⽣效很快，因此⼤部分客

户都是很快⽣效到最新的解析上，只有⼩部分客户访问受到影响，这

时指导异常客户清理本机DNS缓存，或者强制绑定本机host指向域名解

析，也未尝不是⼀种很好的⽅式。

7.4.2 实践⼆：DNS不为⼈知的核⼼秘密功能

DNS的智能解析功能是跨地域的分布式架构中不可缺少的核⼼功

能。在CDN或跨国际应⽤中，⽬前应该没有能替代它的解析⽅案。实

际上，智能解析是DNS的核⼼秘密功能，但很多⼈对这项隐藏的技能

不是太了解。接下来主要介绍这⽅⾯的实践。

1.智能解析核⼼功能

域名智能解析是指域名解析服务器根据来访者的IP类型，对同⼀

域名相应地做出不同的解析。智能解析的原理是，有⼀个全世界现有

的IP地址库，每个地址对应哪个地域下的运营商线路都会记录在这个IP

地址库中。客户端请求DNS服务器，DNS服务器会去查询这个IP地址

库，然后返回这个IP地址对应的地域及运营商线路。所以可以看到，

智能解析主要有两种类型：运营商线路解析、运营商地域线路解析。

（1）运营商线路解析

如果在IDC有5台服务器，分别位于电信、⽹通、移动、教育⽹、

海外，我们可以在云解析中这样填写记录：

·默认线路：电信服务器IP；

·⽹通线路：⽹通服务器IP；

·移动线路：移动服务器IP；

·教育⽹线路：教育⽹服务器IP；

·海外线路：海外服务器IP。

客户端请求源IP是来⾃电信的访问者，DNS将域名解析到该域名

对应的电信服务器的IP地址上。客户端请求源IP是来⾃⽹通的访问者，

则DNS将域名解析到该域名对应的⽹通服务器的IP地址上。可以看

到，DNS的运营商线路智能解析，其实也能解决传统IDC⽹络架构中存

在的南北⽹络互通的问题。不过在云端，如今DNS在运营商线路智能

解析这⽅⾯基本上派不上⽤场。主要是因为云端⽹络都是BGP线路，

⼀个IP对应电信、⽹通、移动、教育⽹等多家运营商线路。所以云解

析变成这样填写记录：

·默认线路：ECS/SLB公⽹IP；

·⽹通线路：ECS/SLB公⽹IP；

·移动线路：ECS/SLB公⽹IP；

·教育⽹线路：ECS/SLB公⽹IP；

·海外线路：ECS/SLB公⽹IP。

上述记录可以简化成⼀条云解析记录：

·默认线路：ECS/SLB公⽹IP。

（2）运营商地域线路解析

运营商地域线路解析，其实是运营商线路解析的细分。能够针对

某运营商解析细分到该运营商的地域级别。

●国内运营商地域线路分布

·移动：国内区域；

·联通：国内区域；

·电信：国内区域；

·教育：国内区域。

在DNS国内地域解析线路中，我们可以选择上述的移动、联通、

电信、教育这4个选择类别来细分解析。国内运营商地域线路细分案例

如图7-5所⽰。

在图7-5中，⽤户请求访问域名地址，DNS能够⾃动判断访问者的

IP地址是“上海联通”还是“北京联通”，然后智能地返回设置的对应

的“上海联通”和“北京联通”的服务器IP地址完成域名解析。

图7-5 国内运营商地域线路细分

●海外运营商地域线路分布

在DNS海外地域解析线路中，我们可以选择“海外、海外⼤洲[1]、

海外（国家/地区）[2]”这3个选择类别（这是阿⾥DNS产品设置的3个选

项）来细分解析。举个海外地域解析的实践案例，假如阿⾥云⽤三台

服务器部署海外业务，分别在新加坡、美国、德国，那么我们可以在

云解析中按如下⽅式填写记录。

·海外-亚洲地区-新加坡线路：指向新加坡服务器的IP；

·海外-北美洲-美国线路：指向美国服务器的IP；

·海外-欧洲-德国线路：指向德国服务器的IP；

·默认线路：指向新加坡服务器的IP。

这样亚洲地区⽤户请求访问域名地址，DNS会解析到新加坡服务

器的IP地址。北美洲地区⽤户请求访问域名地址，DNS会解析到美国

服务器的IP地址。欧洲地区⽤户请求访问域名地址，DNS会解析到德

国服务器的IP地址。另外，默认线路解析表⽰什么呢？是指除了亚

洲、北美洲、欧洲这三个地区的⽤户请求访问域名地址，DNS会默认

解析到新加坡服务器的IP地址。

2.CDN是智能解析的最佳实践

智能解析的最佳实践当属CDN。CDN虽然本质上是提供静态缓存

加速，但静态访问加速的“就近访问”的核⼼，就是智能解析的核⼼功

能，如图7-6所⽰。

北京终端⽤户请求流程如下：

1）终端⽤户（北京）向qiaobangzhu.cn下的某资源发起请求，会先

向本地域名服务器LDNS发起域名解析请求（这台服务器⼀般是由⽹络

带宽供应商配置的，如电信，对应⽹络带宽供应商的DNS服务器⼀般

在本市。这台服务器的性能⼀般都很好，会缓存域名解析结果，⼤约

80%的域名解析到这⾥就完成了）。

2）当LDNS解析qiaobangzhu.cn时会发现本地缓存中没有该资源，

于是它将请求转发给⽹站授权的域名解析对应供应商（⽐如阿⾥云的

万⽹云解析http://www.net.cn/）。

图7-6 CDN请求数据包流向

3）⽹站授权的域名解析对应供应商发现qiaobangzhu.cn已经配置了

CNAME qiaobangzhu.tbcdn.cn，并将qiaobangzhu.tbcdn.cn对应的IP地址

返回给LDNS。

4）LDNS得到CNAME qiaobangzhu.tbcdn.cn对应的IP地址，将解析

请求发送⾄阿⾥云CDN的DNS调度系统。

5）阿⾥云CDN的DNS调度系统根据终端⽤户的源IP判断出该终端

属于北京地域，并为该终端⽤户请求分配北京缓存节点IP，LDNS获取

DNS返回的解析IP地址1.1.1.1。

6）⽤户获取解析IP地址1.1.1.1，且此IP为北京地域的CDN缓存节

点。

7）⽤户向获取的IP地址1.1.1.1发起对该资源的访问请求。这⾥又

分为以下两种情况。

·如果是静态请求（图⽚、js、css、html等），若该IP对应的节点已

经缓存了该资源，则会将数据直接返回给⽤户，此时请求结束。若该

节点未缓存该资源，则节点会向业务源站IP地址3.3.3.3发起对该资源的

请求。获取资源后，结合⽤户⾃定义配置的缓存时间策略，将资源缓

存⾄节点（如图7-6中北京节点），并返回给⽤户，此时请求结束。

·如果是动态请求则直接转给后端源站进⾏处理，由此可见CDN只

做静态缓存加速，对动态请求是没办法进⾏加速的。

上海终端⽤户请求流程如下：

1）终端⽤户（上海）向qiaobangzhu.cn下的某资源发起请求，会先

向本地域名服务器LDNS发起域名解析请求（这台服务器⼀般是由⽹络

带宽供应商配置的，如电信，对应⽹络带宽供应商的DNS服务器⼀般

在本市。这台服务器的性能⼀般都很好，会缓存域名解析结果，⼤约

80%的域名解析到这⾥就完成了）。

2）当LDNS解析qiaobangzhu.cn时会发现本地缓存没有该资源，于

是它会将请求转发给⽹站授权的域名解析对应供应商（⽐如阿⾥云的

万⽹云解析http://www.net.cn/）。

3）⽹站授权的域名解析对应供应商发现qiaobangzhu.cn已经配置了

CNAME qiaobangzhu.tbcdn.cn，并将qiaobangzhu.tbcdn.cn对应的IP地址

返回给LDNS。

4）LDNS得到CNAME qiaobangzhu.tbcdn.cn对应的IP地址，将解析

请求发送⾄阿⾥云CDN的DNS调度系统。

5）阿⾥云CDN的DNS调度系统根据终端⽤户的源IP判断出该终端

属于上海地域，并为该终端⽤户请求分配上海缓存节点IP，则LDNS获

取DNS返回的解析IP地址2.2.2.2。

6）⽤户获取解析IP地址2.2.2.2，且此IP为上海地域的CDN缓存节

点。

7）⽤户向获取的IP地址2.2.2.2发起对该资源的访问请求。这⾥又

分为以下两种情况。

·如果是静态请求（图⽚、js、css、html等），若该IP对应的节点已

经缓存了该资源，则会将数据直接返回给⽤户，此时请求结束。若该

节点未缓存该资源，则节点会向业务源站IP地址3.3.3.3发起对该资源的

请求。获取资源后，结合⽤户⾃定义配置的缓存时间策略，将资源缓

存⾄节点（如图7-6中上海节点），并返回给⽤户，此时请求结束。

·如果是动态请求则直接转给后端源站进⾏处理，由此可见CDN只

做静态缓存加速，对动态请求是没办法进⾏加速的。

总结：

对⽐北京终端和上海终端⽤户请求流程可以看到，CDN所谓“就近

访问”的核⼼在于DNS的智能解析能分辨不同终端⽤户源IP的地域，然

后再返回该地域的CDN缓存节点IP地址，从⽽实现“就近访问”。

3.跨地域分布式架构是智能解析的最佳实践

在云端实践中，也经常遇到跨国际⽤户请求的需求：

图7-7 多个域名+多个站点

·应⽤部署在国内，海外⽤户访问不畅。

·应⽤部署在海外，国内⽤户访问不畅。

⽤什么架构可以实现海外⽤户、国内⽤户访问通畅？下⾯将给出

实践中总结出的两套成熟的标准⽅案。

⽅案1：多个域名+多个站点

该⽅案如图7-7所⽰。业务中分多个域名，⽐如海外⽤户访问

abroad.a.com，解析IP绑定到海外机房部署的业务站点。国内⽤户访问

home.a.com，然后解析IP绑定国内机房部署的业务站点。这类架构的应

⽤，在⼀些常见的热门开源类官⽹⽐较多。⽐如要下载对应的软件

包，会给出很多下载链接地址。我们可以根据⾃⼰所在的地域，选择

不同URL来进⾏“就近下载”。图7-8所⽰就是Apache的下载界⾯。

图7-8 官⽹Apache安装包下载

图7-9 单个域名（智能解析）+多个站点

⽅案2（最佳实践）：单个域名（DNS智能解析）+多个站点

在没接触到智能解析之前，我们⼀直都是推荐使⽤⽅案1中的多个

域名+多个站点部署的⽅式。这种加上多个域名的⽅式，可能很多业务

是不能接受的，⼤多数业务需求是只能⽤⼀个域名作为访问⼊⼜。⽐

如国内知名扫地机器⼈在海外的官⽹，在⽇本、新加坡、美国、德国

都部署节点，但暴露给⽤户的仅有⼀个域名地址。这时智能解析就很

好地解决了该问题，它可以根据海外不同的地域，设置多个不同的A解

析记录，如图7-9所⽰。

除了跨国际的分布式架构外，其实对国内的跨地域的分布式架

构，特别是异地多活的架构来说，智能解析的核⼼功能更是必不可

少，如图7-10所⽰。

图7-10 DNS+跨地域/跨平台+Docker分布式架构

通过智能解析把不同地域的请求引流⾄各⾃不同地域部署的节点

中，然后将节点中部署的业务再采⽤Docker进⾏部署。这样业务代码

对平台⽆依赖，即可以⽆缝地接⼊线下IDC机房、国内各⼤云运营商，

甚⾄是AWS上。虽然业务代码层的跨地域部署问题解决了，但是还有

个问题没有解决，即数据库也可能需要进⾏跨地域部署。所以底层数

据库跨地域进⾏同步时所带来的数据同步的延时问题，就成了跨地域

分布式架构的第⼆⼤难题。不过，当前在云端可以通过⾼速通道进⾏

专线打通。当前实际案例中，许多客户已经将海外部署节点和国内部

署节点通过⾼速通道打通，从⽽保障⽹络传输速度及传输质量。然后

结合DTS⼯具进⾏数据库底层的实时同步。

云诀窍

DTS数据传输（Data Transmission）是阿⾥云提供的⼀种⽀持

RDBMS（关系型数据库）、NoSQL、OLAP等多种数据源之间数据交

互的数据服务。它提供了数据迁移、实时数据订阅及数据实时同步等

多种数据传输能⼒。通过数据传输可实现不停服数据迁移、数据异地

灾备、跨境数据同步、缓存更新策略等多种业务应⽤场景，帮助⽤户

构建安全、可扩展、⾼可⽤的数据架构。DTS将会成为云端数据同

步、跨地域数据同步的最佳实践⽅案。

[1] 该选项下包括⼤洋洲、欧洲、北美洲、南美洲、⾮洲。

[2] 该选项下包括澳⼤利亚、新西兰、马来西亚、阿联酋、泰国、新加

坡、越南、⽇本、缅甸、马尔代夫、尼泊尔、印度、沙特阿拉伯、韩

国、菲律宾、印尼、⽼挝、柬埔寨、墨西哥、加拿⼤、美国、巴西、

阿根廷、瑞⼠、西班⽛、法国、俄罗斯、瑞典、荷兰、英国、意⼤

利、德国、奥地利、南⾮等国家或地区。

7.5 企业级Web架构实践

在企业的Web类应⽤实践中经常会碰到如下问题：

·Tomcat能直接对外提供Web服务，为什么前端还要加个Nginx？

·⽤Django开发的Python Web应⽤，启动的对应Web端⼜服务能直

接对外提供访问，为什么前端要加个Nginx？

·PM2启动的Node服务也能直接对外提供Web服务，为什么前端要

加个Nginx？

如果公司业务是通过Tomcat、Python Web应⽤、Node Web应⽤直

接对外提供访问，那其实这种部署架构就已经很不合理了。企业级Web

架构实践，反向代理（也称负载均衡，反向代理和负载均衡的底层原

理区别可参考4.3节）⼏乎已经成为标配。在Web应⽤中，前端加个

Nginx作为反向代理，究竟有什么优势呢？其对⽐结果如表7-3所⽰。

表7-3 Web服务器和反向代理组合的对⽐优势

所以反向代理是企业级Web架构的最佳实践，在云端亦是如此。具

体在负载均衡架构中，反向代理架构要怎么结合使⽤，会在接下来的

7.6节中进⼀步介绍。

7.6 企业级负载均衡架构实践

那么什么样的负载均衡架构才对得起“企业级”3个字？在分析很多

中⼤型项⽬时，我发现它们在使⽤负载均衡时都有⼀个共同的特点，

于是对这些特性结合在云端进⾏实践验证。

7.6.1 七层SLB性能实践案例

下⾯先来看⼀个案例：

在“双⼗⼀”活动前⼣，我们采⽤性能测试服务（Performance

Testing Service，PTS）对某电商⽤户的线上业务进⾏压测评估。

客户线上的环境配置如表7-4所⽰。

表7-4 客户线上环境配置清单

该电商⽤户线上环境压测结果如图7-11所⽰。

图7-11 某电商客户线上环境压测结果

可以看到，这⾥进⾏了峰值15000的并发压测，有179906次请求超

时。从获取的业务实时监控服务ARMS（Application Real-Time

Monitoring Service）中的监控数据来看（如图7-12所⽰），在全链路前

端请求、数据库调⽤、Redis调⽤⽅⾯的响应时间没有异常。

图7-12 阿⾥云arms监控结果

再在驻云的监控系统中对系统层⾯的性能监控数据进⾏确认，如

表7-5所⽰。

表7-5 系统层⾯监控性能数据

各个系统的性能状态及性能指标都正常，但是为什么SLB会返回⼤

量超时的请求？我们最终将问题锁定在SLB的性能上。七层SLB超强型

的规格，每秒查询数（QPS）为50000。⽽PTS压测的并发请求数是

15000，QPS已经超过七层SLB的最⼤极限，于是出现SLB返回⼤量超

时请求的现象。其实在第⼀篇关于负载均衡的选型中，已经明确了各

个类型SLB的并发性能的数量级。七层的负载均衡，在中⼤型项⽬中并

不适合作为业务请求的流量⼊⼜，特别是在电商⾼并发的场景下，七

层SLB显得格外⼒不从⼼。

7.6.2 互联⽹企业负载均衡架构实践

对于⽤户请求流量的⼊⼜，经过⼤量实践，⼀般采⽤⼆层/四层或

者硬件负载均衡来实现，从⽽实现抗并发及分流。然后将请求转发给

后端七层负载均衡，在七层负载均衡上做Rewrite、虚拟主机等业务功

能上的控制。图7-13所⽰为标准的互联⽹企业级应⽤架构流程。

按照图7-13来设计，传统互联⽹负载均衡架构的标准实践如图7-

14所⽰。

图7-13 互联⽹企业架构请求负载均衡数据包流转

图7-14 互联⽹企业架构负载均衡架构

我们并不会采⽤七层Nginx、七层Haproxy作为流量⼊⼜，也不会

采⽤Nginx四层、Haproxy四层作为流量⼊⼜，主要是因为

Nginx/Haproxy的“⼆次连接”对性能有损耗。采⽤LVS或者负载均衡作

为互联⽹架构的流量⼊⼜，可以保障⼊⼜流量最⼤性能及效率被负载

均衡转发，这是中⼤型项⽬的标准应⽤。在此之前已介绍过⼀家电商

公司的案例，“双⼗⼀”活动期间，能把LVS NAT模式的内⽹千兆带宽

跑满。LVS NAT模型都遇到了性能瓶颈，我们将其切换成LVS的DR模

式，使流量从后端服务器返回给客户端，这样才解决了相应的性能问

题。如果⽤七层的负载均衡是不可能做到的。所以中⼤型应⽤中，前

端⽤七层负载均衡，⼏乎都会成为瓶颈点。所以⼊⼜流量处仅通过硬

件或LVS负载均衡做流量分发。⽽七层虚拟主机、Rewrite等功能需

求，就放在后端服务器上通过搭建Nginx/Apache来实现。

图7-15 云端中⼩型互联⽹企业负载均衡架构

7.6.3 云端负载均衡中⼩型架构实践

如果是中⼩型应⽤，⽤户请求的QPS量级远远达不到50000，这时

候其实还是优先推荐使⽤七层的SLB作为流量⼊⼜。如图7-15所⽰。

使⽤七层SLB作为流量⼊⼜，虽然没办法应对⾼并发的场景。但

是在功能应⽤、管理维护等⽅⾯要⽐四层SLB⽅便且简单许多。主要

有以下⼏⽅⾯特点：

1.虚拟主机功能⽅⾯

虚拟主机能直接在七层负载均衡上进⾏配置，将虚拟主机进⾏集

中管理效率会更⾼，这样就不⽤单独去后端ECS中的Nginx上配置虚拟

主机。不过这⽅⾯功能既是使⽤七层负载均衡的优势，也是其劣势。

以前在⽤硬件负载均衡做七层的虚拟主机等七层规则管理的时

候，如若配置条⽬很多，⽐如有1000条规则，这时候你会发现集中管

理冗余，根本没办法集中维护这些配置。最后我们还是在服务器中⽤

Nginx拆分成不同配置⽂件来进⾏管理维护。同样，如若虚拟主机的规

则达到上百条，你会发现⽤七层SLB进⾏集中管理并不是⼀种很理想

的做法。

当前七层SLB只有虚拟主机简单七层功能，并没有Rewrite、

Allow/Deny控制功能。如果需要七层SLB的这些功能，还是只能通过

在ECS中搭建Nginx来实现。

2.证书配置⽅⾯

相⽐于四层SLB，七层SLB可直接将证书配置在其中，⽽不⽤去

后端在所有ECS的Nginx中配置证书。

云诀窍

采⽤七层SLB集中化管理证书，虽然在维护管理上提升了效率，

但是在性能上损耗严重。实践发现，前端使⽤七层SLB进⾏证书集中

管理，性能会损耗20%～30%。在⾼并发场景下尤为明显，我们在其

他的客户实践中，专门⽤PTS压测得到了这个性能数据，并对其进⾏

了验证。

3.后端服务器资源利⽤⽅⾯

采⽤四层SLB仅做请求分流转发，请求都是逐⼀轮询给后端

ECS，因此后端ECS部署的代码、Nginx配置要⼀样。⽽采⽤七层SLB

时，它会根据虚拟主机的功能将请求转发给后端不同的ECS，因此后

端ECS上可以部署不同的业务代码。所以七层SLB在资源利⽤、调度

分配等⽅⾯更加有效。

7.6.4 云端负载均衡中⼤型架构实践

如果是中⼤型应⽤，存在⾼并发访问场景。在云端，结合传统互

联⽹企业标准架构所设计的符合中⼤型应⽤的云端标准负载均衡架构

如图7-16所⽰。

图7-16 云端中⼤型互联⽹企业负载均衡架构

前端采⽤SLB四层作为请求流量⼊⼜，以应对⾼并发场景。如果

需要配置https证书的话，可将证书放在后端ECS中⽤Nginx来配置。若

还需要虚拟主机、Rewrite等功能，可⼀并放在后端ECS中通过Nginx来

实现。

7.7 通过代理+VPN提速跨国际⽹络访问

跨国际⽹络访问延时，⼀直是⽹络架构中的疑难杂症。⽐较暴⼒

直接的解决办法，就是通过专线（阿⾥云的云企业⽹及⾼速通道服

务）来解决⽹络连通的质量问题。但是专线也仅仅只解决了内部应⽤

服务之间调⽤（⽐如数据库跨国际地域同步）的⽹络问题，没办法解

决⽤户跨国际地域访问带来的⽹络延时问题。通过代理+VPN提速跨

国际⽹络访问，在云端算是经典的应⽤实践。

7.7.1 跨国际⽹络访问的延时问题

我们有个客户在云端有跨国际应⽤，在美国东部、德国、新加

坡、⽇本等地部署了业务应⽤。我们帮其部署了CSOS（Cloud Security

Operating Service）代理，但由于CSOS Server部署在我国杭州地域，美

国东部、德国的CSOS Agent由于跨国际⽹络延时，导致服务器SSH经

常连接不上。不过新加坡节点由于是亚太地域，⽹络访问延时问题⽐

较少见。为了解决此问题，我们引⼊了类似反向代理中转的架构，以

解决⽹络上带来的延时问题，如图7-17所⽰。

图7-17 跨国际⽹络请求案例

国内请求通过跨国际⽹络直接ssh美国东部节点、德国节点时，⽹

络延时较严重。此外，CSOS Agent也要跟杭州节点的机器进⾏通信，

这种直接通信⽅式的延时也特别严重。这可以通过简单的ping实验来验

证，临时在美国东部（弗吉尼亚）、德国（法兰克福）开通两台ECS，

其公⽹IP地址分别为47.90.209.124和47.254.147.13。我在⾃⼰的笔记本

上（电信100M带宽）直接ping美国东部的IP地址，命令如下：

ruijiedeMacBook-Pro:~ ruijieqiao$ ping 47.90.209.124 -c 10

PING 47.90.209.124 (47.90.209.124): 56 data bytes

64 bytes from 47.90.209.124: icmp_seq=0 ttl=49 time=315.406 ms Request timeout for icmp_seq 1

64 bytes from 47.90.209.124: icmp_seq=2 ttl=49 time=308.317 ms 64 bytes from 47.90.209.124: icmp_seq=3 ttl=49 time=318.053 ms 64 bytes from 47.90.209.124: icmp_seq=4 ttl=49 time=363.914 ms Request timeout for icmp_seq 5

64 bytes from 47.90.209.124: icmp_seq=6 ttl=49 time=402.804 ms 64 bytes from 47.90.209.124: icmp_seq=7 ttl=49 time=318.880 ms 64 bytes from 47.90.209.124: icmp_seq=8 ttl=49 time=339.382 ms 64 bytes from 47.90.209.124: icmp_seq=9 ttl=49 time=358.691 ms

--- 47.90.209.124 ping statistics ---

10 packets transmitted, 8 packets received, 20.0% packet loss round-trip min/avg/max/stddev = 308.317/340.681/402.804/30.411 ms 延时300～500ms，普遍存在丢包情况。然后我又⽤本机直接ping

德国的ECS，命令如下：

ruijiedeMacBook-Pro:~ ruijieqiao$ ping 47.254.147.13 -c 10

PING 47.254.147.13 (47.254.147.13): 56 data bytes

64 bytes from 47.254.147.13: icmp_seq=0 ttl=49 time=526.694 ms 64 bytes from 47.254.147.13: icmp_seq=1 ttl=49 time=371.693 ms Request timeout for icmp_seq 2

Request timeout for icmp_seq 3

64 bytes from 47.254.147.13: icmp_seq=4 ttl=49 time=348.080 ms 64 bytes from 47.254.147.13: icmp_seq=5 ttl=49 time=322.598 ms Request timeout for icmp_seq 6

64 bytes from 47.254.147.13: icmp_seq=7 ttl=49 time=445.749 ms 64 bytes from 47.254.147.13: icmp_seq=8 ttl=49 time=381.789 ms 64 bytes from 47.254.147.13: icmp_seq=9 ttl=49 time=400.785 ms

--- 47.254.147.13 ping statistics ---

10 packets transmitted, 7 packets received, 30.0% packet loss round-trip min/avg/max/stddev = 322.598/399.627/526.694/63.205 ms 跟ping美国东部的ECS情况差不多，延时300～500ms，普遍存在丢

包情况。

7.7.2 解决跨国际⽹络访问的代理架构

为了解决这个跨国际⽹络延时的问题，我们引⼊了代理节点。其

核⼼原理跟前⾯介绍的负载均衡中为实现南北互通以Nginx反向代理作

为中转的原理基本类似。其架构如图7-18所⽰。

图7-18 代理在跨国际⽹络请求中的应⽤

国内⽤户直接访问德国、美国东部节点，⽹络延时较严重。但若

在新加坡放置⼀台代理服务器，那么直接访问这台代理服务器的速度

⼀般都很快，这台代理服务器直接通过国际⽹络去访问德国节点、美

国东部节点，其速度也很快。临时在新加坡开通⼀台ECS，公⽹IP为

161.117.229.111。我在⾃⼰的笔记本上（电信100M带宽）直接ping新加

坡的IP地址，命令如下：

ruijiedeMacBook-Pro:~ ruijieqiao$ ping 161.117.229.111 -c 10

PING 161.117.229.111 (161.117.229.111): 56 data bytes 64 bytes from 161.117.229.111: icmp_seq=0 ttl=48 time=34.748 ms 64 bytes from 161.117.229.111: icmp_seq=1 ttl=48 time=35.535 ms 64 bytes from 161.117.229.111: icmp_seq=2 ttl=48 time=34.012 ms

64 bytes from 161.117.229.111: icmp_seq=3 ttl=48 time=35.748 ms 64 bytes from 161.117.229.111: icmp_seq=4 ttl=48 time=35.284 ms 64 bytes from 161.117.229.111: icmp_seq=5 ttl=48 time=34.699 ms 64 bytes from 161.117.229.111: icmp_seq=6 ttl=48 time=35.266 ms 64 bytes from 161.117.229.111: icmp_seq=7 ttl=48 time=35.223 ms 64 bytes from 161.117.229.111: icmp_seq=8 ttl=48 time=35.483 ms 64 bytes from 161.117.229.111: icmp_seq=9 ttl=48 time=35.369 ms

--- 161.117.229.111 ping statistics ---

10 packets transmitted, 10 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 34.012/35.137/35.748/0.486 ms 可以看到延时很低，仅34ms左右，没有出现丢包情况。基本上

ping新加坡服务器时，很少出现丢包的情况。然后再登录新加坡服务

器，通过这台服务器ping美国东部服务器，命令如下：

[root@iZj6c31zbo0drgkckak1nvZ ~]# ping 47.90.209.124 -c 10

PING 47.90.209.124 (47.90.209.124) 56(84) bytes of data.

64 bytes from 47.90.209.124: icmp_seq=1 ttl=50 time=261 ms 64 bytes from 47.90.209.124: icmp_seq=2 ttl=50 time=264 ms 64 bytes from 47.90.209.124: icmp_seq=3 ttl=50 time=269 ms 64 bytes from 47.90.209.124: icmp_seq=4 ttl=50 time=263 ms 64 bytes from 47.90.209.124: icmp_seq=5 ttl=50 time=250 ms 64 bytes from 47.90.209.124: icmp_seq=6 ttl=50 time=268 ms 64 bytes from 47.90.209.124: icmp_seq=7 ttl=50 time=252 ms 64 bytes from 47.90.209.124: icmp_seq=8 ttl=50 time=265 ms 64 bytes from 47.90.209.124: icmp_seq=9 ttl=50 time=268 ms 64 bytes from 47.90.209.124: icmp_seq=10 ttl=50 time=269 ms

--- 47.90.209.124 ping statistics ---

10 packets transmitted, 10 received, 0% packet loss, time 9275ms rtt min/avg/max/mdev = 250.621/263.351/269.341/6.355 ms 延时260ms左右，重点是⽹络稳定，不会出现丢包的情况。同样，

登录新加坡服务器，通过这台服务器ping德国服务器，命令如下：

[root@iZj6c31zbo0drgkckak1nvZ ~]# ping 47.254.147.13 -c 10

PING 47.254.147.13 (47.254.147.13) 56(84) bytes of data.

64 bytes from 47.254.147.13: icmp_seq=1 ttl=49 time=266 ms 64 bytes from 47.254.147.13: icmp_seq=2 ttl=49 time=269 ms 64 bytes from 47.254.147.13: icmp_seq=3 ttl=49 time=264 ms 64 bytes from 47.254.147.13: icmp_seq=4 ttl=49 time=266 ms 64 bytes from 47.254.147.13: icmp_seq=5 ttl=49 time=264 ms 64 bytes from 47.254.147.13: icmp_seq=6 ttl=49 time=260 ms 64 bytes from 47.254.147.13: icmp_seq=7 ttl=49 time=264 ms 64 bytes from 47.254.147.13: icmp_seq=8 ttl=49 time=259 ms 64 bytes from 47.254.147.13: icmp_seq=9 ttl=49 time=267 ms 64 bytes from 47.254.147.13: icmp_seq=10 ttl=49 time=266 ms

--- 47.254.147.13 ping statistics ---

10 packets transmitted, 10 received, 0% packet loss, time 9266ms rtt min/avg/max/mdev = 259.883/264.890/269.217/2.858 ms

延时也是260ms左右，同样，重点是⽹络稳定，不会出现丢包的情

况。所以结合对⽐测试，加⼊新加坡的代理节点，⽹络的传输延时不

仅会减少，还会使⽹络质量更稳定，不会出现丢包、不稳定等问题

了。

同样，美国东部节点、德国节点的CSOS代理要跟我国杭州节点的

CSOS服务器通信时，也让请求通过新加坡代理转发⾄我国杭州节点

上。将CSOS代理中要跟csos.cloudcare.cn通信的请求通过配置VPN强制

⾛新加坡代理即可实现。通过以上架构优化，基本上可以避免延时抖

动的情况。

云诀窍

代理是跨国际⽹络应⽤中不可多得的成熟解决⽅案，但要确保代

理节点的⽹络通畅，否则就失去了代理节点中转的意义，即国内到国

外代理节点的⽹络要通畅，国外代理节点到⽬标服务器的⽹络也要通

畅。

7.8 通过反向代理提速跨国际⽹站访问

接着上⽂跨国际⽹络访问的延时话题，还有另外⼀个场景，就是

国内客户跨国际访问国外部署的⽹站（主要为亚洲地域外的其他地

域）延时很⾼的问题（主要受访问出⼜带宽限制）。⽐如假设

qiaobangzhu.cn⽹站部署在美国（弗吉尼亚），服务器的IP地址为

47.90.209.124，那么国内⽤户直接访问qiaobangzhu.cn，可能经常出现

卡顿，或者由于⽹络延时直接访问不了。怎么解决国内⽤户访问国外

⽹站慢的问题呢？同样我们可以借助新加坡的服务器通过反向代理解

决，架构如图7-19所⽰。

图7-19 反向代理提速跨国际⽹站访问架构

除了要依靠新加坡的服务器外，核⼼技术还需要在该代理服务器

上部署Nginx来中转⽤户请求。Nginx是百年难遇的“神⼀般”的软件，

只有你想不到的，没有它做不到的。本⽂主要介绍Nginx七层反向代理

的技术特性，我们主要有两个⽅案实现，明细如下⽂。

7.8.1 ⽅案⼀：双域名反向代理架构⽅案

双域名架构的⽅案跟7.4.2节中DNS实践的“多个域名+多个站点”⽅

案⽐较类似，都是传统成熟的解决⽅案。具体配置流程主要有以下三

⼤步。

（1）需要⼀台新加坡的ECS

在新加坡开通⼀台ECS作为反向代理服务器，⽐如开通的服务器

公⽹IP为161.117.229.111。跟7.7节的案例⼀样，我们通过该代理服务

器来中转国内⽤户的请求，从⽽达到提速的效果。

（2）需要⼀个⼆级域名

这⾥将⼀个新的⼆级域名（⽐如sg.qiaobangzhu.cn）的A解析地址

直接解析到新加坡服务器的IP地址161.117.229.111上，国内⽤户访问

sg.qiaobangzhu.cn时，该服务器将请求中转给源站qiaobangzhu.cn服务

器。当然这⾥也可以直接将qiaobangzhu.cn解析到该服务器的IP地址

161.117.229.111上，虽然国内⽤户访问延时的问题解决了，但是国外

⽤户访问qiaobangzhu.cn的请求都要通过该服务器绕着再⾛到源站，有

些得不偿失。

（3）部署Nginx反向代理

在新加坡服务器上部署Nginx作为反向代理，将sg.qiaobangzhu.cn

请求中转⾄qiaobangzhu.cn上，Nginx核⼼配置如下：

server {

listen 80;

server_name sg.qiaobangzhu.cn;

index index.html index.htm;

location / {

proxy_pass http://qiaobangzhu.cn/;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

}

虽然这个配置是Nginx反向代理的常规配置，但其实在这个场景下

是有问题的，可能会导致国内⽤户访问sg.qiaobangzhu.cn找不到站点的

异常。这是因为国内⽤户访问请求的域名是sg.qiaobangzhu.cn，Nginx

将sg.qiaobangzhu.cn请求转到源站qiaobangzhu.cn上，域名请求出现不

匹配，因⽽出现报错。

那怎样解决这个问题呢？Nginx这时候就能发挥HTTP七层⽆所不

能的价值了。在HTTP请求头信息中，host字段表⽰请求的服务器⽹

址，即我们只要修改这个字段的值，让转给源站的HTTP请求host字段

的值为源站真实的域名地址即可。所以通过Nginx修改host字段的值，

最终Nginx核⼼的正确配置如下：

server {

listen 80;

server_name sg.qiaobangzhu.cn;

index index.html index.htm;

location / {

proxy_pass http://qiaobangzhu.cn/;

proxy_set_header Host 'qiaobangzhu.cn';

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

}

另外，值得注意的是，很多⼈把302重定向和反向代理容易搞混

淆。⽐如Nginx对302重定向的配置如下：

server {

listen 80;

server_name sg.qiaobangzhu.cn;

index index.html index.htm;

location / {

rewrite ^ http://qiaobangzhu.cn$request_uri permanent;

}

}

我们访问sg.qiaobangzhu.cn被重定向跳转到qiaobangzhu.cn上了，

本质上最终还是要直接访问qiaobangzhu.cn，这并没有解决访问⽹络延

时的问题。

7.8.2 ⽅案⼆：单域名反向代理架构⽅案

相⽐⽅案⼀中的双域名⽅式，⽤户要记住两个域名，这在⽤户体

验上肯定没有只访问⼀个域名更友好。那能不能只通过⼀个域名结合

反向代理，来解决跨国际⽹站访问延时的问题呢？答应是可以的，我

们需要借助DNS智能解析的核⼼功能。具体配置流程同样也有以下三

⼤步。

（1）需要⼀台新加坡的ECS

同样需要在新加坡开通⼀台ECS作为反向代理服务器，⽐如开通

的服务器公⽹IP为161.117.229.111。

（2）设置DNS智能解析

在DNS的云解析中，我们需要将qiaobangzhu.cn解析线路明细设置

如下：

·默认线路：指向美国服务器的IP47.90.209.124

·海外-北美洲-美国线路：指向美国服务器的IP47.90.209.124

·国内：指向新加坡服务器的IP161.117.229.111

通过DNS智能解析设置后，国内⽤户访问qiaobangzhu.cn会⾃动解

析到新加坡服务器的IP161.117.229.111上，⽽海外⽤户访问

qiaobangzhu.cn会⾃动解析到美国服务器的IP47.90.209.124上。

（3）部署Nginx反向代理

同样在新加坡服务器上部署Nginx作为反向代理，将国内⽤户访问

qiaobangzhu.cn的请求中转⾄源站qiaobangzhu.cn上，Nginx核⼼配置如

下：

server {

listen 80;

server_name qiaobangzhu.cn;

index index.html index.htm;

location / {

proxy_pass http://qiaobangzhu.cn/;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

}

值得注意的是，新加坡的服务器将国内⽤户访问qiaobangzhu.cn的

请求反向代理给qiaobangzhu.cn，这时候新加坡的服务器解析

qiaobangzhu.cn的IP地址得到的已经是美国服务器的IP地址

47.90.209.124了。为了保险起见，我们可以在新加坡的代理服务器上

的host配置⽂件（/etc/hosts）中将qiaobangzhu.cn的解析本地强制绑定

到美国服务器的IP地址47.90.209.124上，这样就可以保障请求最终被

转到美国服务器的源站上了。

第8章 云端存储实践

云端存储实践，主要是数据持久化实践。数据是企业的⽣命，这

⾥的数据主要体现为存储中的数据。本章主要讲⾮结构化类型数据的

持久化存储实践，即块存储（云盘）、共享块存储（共享云盘）、共

享⽂件存储、OSS对象存储的云端实践。⽽结构化数据类型及半结构

化数据类型的存储实践，即数据库类实践，将在第10章重点介绍。

8.1 云端块存储⼋⼤实践技巧

块存储（云盘）是⾮结构化数据（⽐如⽂本⽂档、图⽚、视频、

⽇志⽂件、代码⽂件等）存储的重要⼿段，⽽在云端如何应⽤好云

盘，接下来的这⼋⼤实践技巧能够让⼤家对看似简单的云盘有更加清

晰的认识。

8.1.1 提升云盘I/O的三⼤技巧

云盘的I/O性能⼀直是⽤户热议的话题，基于虚拟化的技术，其实

在底层I/O隔离⽅⾯不太理想。所以在上⼀代基于XEN技术的阿⾥云集

群，常被认为I/O速度太慢，甚⾄有时还没有U盘快。虽然在新⼀代基

于KVM技术的阿⾥云集群推出了⾼效云盘、SSD云盘，这使得其在I/O

性能⽅⾯得到了很⼤改善，这些提升I/O的性能实践，现如今依然具有

实践参考价值，特别适⽤于对I/O性能要求很⾼的场景。

技巧⼀：分布式部署

分布式部署案例如下。

案例1：云端某⾳频播放FM平台

⾳视频业务对I/O要求很⾼，这通过案例可以看出来。例如，某客

户在云端杭州和青岛地域各开了两百多台ECS，他们的业务在云端ECS

的配置清单如表8-1所⽰。

表8-1 某⾳频播放FM平台的配置清单

案例2：携程某业务平台

携程某业务平台对I/O也有很⾼的要求，它们的业务在云端ECS的

配置清单如表8-2所⽰。

表8-2 携程某业务的配置清单

结合以上两个案例与前⾯讲的“1+1>2”经典架构案例，我们发现把

⼀台机器拆分到不同低配机器磁盘上，其I/O性能呈线性增长。所以在

云端可采⽤⼤量机器进⾏分布式部署，此架构是提升I/O性能最有效的

做法。

技巧⼆：夜间活动减少资源共抢

我们发现，夜间看电影或玩游戏时速度⾮常快。这是因为绝⼤多

数互联⽹⼀天中80%的业务请求量主要集中在40%的时间内，即80%的

业务请求量发⽣在⼀天的9.6⼩时当中，⽽这9.6⼩时绝⼤部分是⽩天请

求访问量。所以在夜间，随着时间的推移，⽤户请求访问量会越来越

少。

我们通过⼀个简单有趣的实验就能验证：

在⽩天业务⾼峰期，⽐如中午12时的时候，去wget oss中的⼀个GB

级别的⼤⽂件，可发现下载速度⼀般是2～5M/s。

在夜间业务低峰期，⽐如凌晨2时的时候，我们再去wget oss中的

⼀个GB级别的⼤⽂件，这时候下载速度是10～30M/s。

在云平台中，夜间的资源竞争少了很多，这时候也是I/O性能最好

的时候。所以在进⾏架构设计的时候，可把需要I/O、需要CPU计划的

任务放在晚间进⾏。

技巧三：云盘的拆分及合并

云盘的拆分是指将⼀块云盘拆分成不同云盘来购买，把⼀块⼤空

间分为⼏块⼩空间购买，⽐如需要200GB磁盘空间，可以分两次进⾏

购买，⼀次购买100GB。⽽且两次购买的时间间隔尽量拉长⼀点，这

样多数情况下，这两块云盘的空间会被分配在底层不同的物理硬盘

上。在两块物理硬盘上读写总⽐在⼀块物理硬盘上读写性能要好，尤

其是将不同的应⽤部署在不同的磁盘空间上时效果更加明显。所以把

⼀块云盘拆分成不同云盘进⾏挂载，在不同云盘中部署不同应⽤程

序，也能有效提升I/O性能，这就是云盘的拆分。

⼀块云盘被拆分成多块云盘后就对应多块物理卷。我们需要格式

化这些不同的云盘，并将其挂载在不同的⽬录中。如果我们有个程

序，⽐如部署的数据库，需要把这些不同的物理卷⽬录都利⽤起来，

这时候可以采⽤LVM虚拟出⼀块逻辑卷提供给数据库做data⽬录，通过

LVM管理不同云盘。通过实践，我们发现I/O性能提升了20%～40%。

关于这⽅⾯我们也通过压测⼯具进⾏了验证。可见，通过LVM合并不

同的云盘，⼀定程度上也能提升I/O性能。

8.1.2 云盘使⽤的五⼤技巧

云盘使⽤的五⼤技巧分别如下。

技巧⼀：在云盘中不建议进⾏分区

在云端实践中，建议直接格式化⼀块云盘，不建议进⾏分区。后

续如若这块云盘要升级扩容，只需要使⽤resize2fs指令扩⼤⽂件系

统，然后重新挂载即可。

相反，如果这块云盘提前进⾏了分区。后续进⾏升级扩容时，就

需要针对不同的分区来进⾏额外的扩容，操作烦琐且复杂。

技巧⼆：在云盘中不建议使⽤LVM

在传统IDC中，使⽤LVM做磁盘管理默认是必需的。特别是LVM

的快照功能，如同云盘的快照功能，是传统硬件磁盘中重要的数据备

份⼿段。但在云端默认的情况下，不再推荐使⽤LVM进⾏磁盘管理，

除⾮想提升I/O等。原因是阿⾥云云盘的快照是针对单块云盘进⾏的，

如果采⽤LVM把多块云盘虚拟成⼀个逻辑卷。后续通过LVM存储的数

据，如若发⽣异常需要回滚，那就没办法使⽤阿⾥云快照这个功能

了。因为若多个云盘回滚的时间点不⼀致，就会导致LVM逻辑卷中的

数据恢复不⼀致（当然如若想多个云盘的快照数据⼀致，我们可以停

机跟系统盘、数据盘快照。因为这时候系统盘和数据盘中数据不再变

更，所以快照不会导致数据不⼀致性的问题）。如果为了使⽤LVM，

⽽没办法使⽤阿⾥云云盘的快照功能，结果得不偿失。

技巧三：云盘的系统盘不建议做数据存储

在开ECS的时候，建议系统盘只选择40GB。系统盘的空间仅⽤于

存储系统⽇志、⼀些系统中间件软件的主⽬录数据，不建议存储业务

代码、业务⽇志、数据库数据等。有些⽤户为了⽅便，直接将系统盘

开成500GB，并且将代码、业务⽇志直接放在系统盘⾥，这会带来很

⼤的安全隐患。⽐如，我们有时候需要进⾏系统调优、内核升级，或

者装⼀个软件，若此时系统出现问题需要回滚系统盘，那么就会导致

存放在系统盘中的业务数据、数据库数据⼀起回滚。

技巧四：云盘最好不要依赖ECS

对于⼀些重要数据的存储（⽐如⽤于搭建数据库的ECS），在磁

盘的选择上，不建议开通ECS的时候就选择云盘配置。这时候云盘跟

ECS绑定在⼀起，ECS释放，云盘也会跟着释放。在云盘的选择上，

建议在ECS创建完成后单独创建云盘，然后再给对应的ECS绑定挂载

云盘。这样云盘并不会随着ECS的释放⽽释放，安全性得到很⼤保

障，并且云盘也能解绑再绑定在其他ECS上，这使得磁盘挂载应⽤具

有更好的灵活性。

云诀窍

同样，在IP上通常不建议开通ECS的时候直接勾选绑定公⽹IP，

这时候这个公⽹IP会跟ECS绑定也会随着ECS的释放⽽释放。公⽹IP有

时候在业务中也是⾮常重要的，建议单独开通EIP，然后再跟ECS绑

定，这样使⽤起来⾮常⽅便。

技巧五：云盘挂载最好放在/etc/fstab中

在实践中，我们经常遇到服务器重启后，虽然上⾯的服务都启动

了，但是业务还是异常的情况，最后发现云盘、NFS或NAS在本地没

有挂载，导致业务数据读取不到。可能有的读者为了⽅便，喜欢把开

机⾃启动的命令（包含磁盘挂载）放在/etc/rc.local中。由于rc.local中

的内容是顺序执⾏的，⼀些执⾏异常、⽂件权限、环境变量等问题，

都可能导致rc.local中的命令没办法开机⾃启动，所以在磁盘挂载的开

机⾃启动中，默认需要把挂载命令放在/etc/fstab中。

8.2 云端共享⽂件存储的五种⽅法

图8-1 负载均衡中的⽂件读写请求

在云端共享⽂件存储的实践场景也⾮常多，在“云端选型篇”中云

端存储的选型也概要说明了共享⽂件存储常⽤的实践场景：负载均衡

中的典型场景、代码共享场景、⽇志共享场景、企业办公⽂件共享场

景、容器服务的场景、备份的场景等。特别是在负载均衡中的场景，

⽂件共享是⽀撑分布式架构的基础，如图8-1所⽰。

在负载均衡的架构中，⽤户第⼀次写⼊⽂件的请求，可能会被负

载均衡调度到后端服务器1上进⾏写⼊处理。⽽⽤户第⼆次读⽂件的请

求，可能会被负载均衡调度到后端服务器2上进⾏读取操作，结果却读

不到这个⽂件。在这种情况下，需要将不同服务器之间的⽂件进⾏共

享或者集中管理。下⾯将介绍⼏种常见的实践⽅案。

8.2.1 ⽅法⼀：Rsync⽂件共享实践

Rsync是Linux系统下的数据镜像备份⼯具，在数据增量备份、数

据迁移、数据同步等⽅⾯有着⽆可替代的地位。Rsync⾃带MD5传输

校验、⽂件传输压缩、⽂件传输限流等很多实⽤功能。很多迁移、备

份⼯具，其底层实现原理跟Rsync差不多，所以服务器之间数据⽂件的

同步⾸选Rsync，服务器间通过Rsync做双向同步。不过Rsync在数据共

享、⽂件集中化管理⽅⾯有着⾮常明显的缺陷。

图8-2 3台服务器Rsync同步

·Rsync不是实时同步的，每次同步需要⼿动执⾏rsync命令，或者

结合crontab进⾏定时执⾏。

·Rsync只适合进⾏两台服务器之间的数据同步。当服务器较多的

时候，⽐如有3台服务器，同步就成为环状，如图8-2所⽰，这如同3台

MySQL做主主环状同步⼀样，因此在⽣成环境中并不推荐多台同步。

主要是环状⼀个环节同步失败，就会导致整体数据不⼀致。

8.2.2 ⽅法⼆：Rsync+Inotify⽂件共享实践

Rsync只是实现了定时同步数据，但是定时任务的同步时间粒度并

不能达到实时同步的要求。在Linux Kernel 2.6.13后提供了Inotify⽂件

系统监控机制，通过Rsync+Inotify组合可以实现实时数据同步。

Inotify是监控⼯具，监控⽬录或⽂件的变化，然后调⽤Rsync进⾏

数据同步，以达到实时同步的效果，这是Rsync+Inotify组合的实现原

理。Inotify的实现⼯具有3款，分别是Inotify本⾝、Sersync、Lsyncd，

在实践中建议优先使⽤Sersync。主要是因为Inotify应⽤中有对应的

BUG：“当向监控⽬录下复制⼤量⽂件，或者复制复杂层次⽬录（多

层次⽬录中包含⽂件）时，Inotify经常会随机性地遗漏某些⽂件。这

些遗漏掉的⽂件由于未被监控到，因此就会导致这些漏掉的数据没办

法同步”，⽽Sersync对Inotify这⽅⾯的缺陷进⾏了优化。由于篇幅等原

因，这⾥不再介绍Sersync的安装配置及使⽤⽅法，⽹络上这⽅⾯的教

程⾮常多，有兴趣的读者可以查询相关⽂献。

云诀窍

如若需要Rsync进⾏实时同步，Sersync是⽐较好的选择。但实践

中需要进⾏实时同步的场景中，⼤家更倾向于使⽤NFS，这样更加⽅

便快捷。

8.2.3 ⽅法三：NFS⽂件共享实践

实践中，Rsync、Rsync+Inotify、Sersync更多应⽤于定时/实时的

单向同步，很少看到双向同步的案例。所以Rsync、Rsync+Inotify、

Sersync偏向于做数据同步，但在数据共享⽅⾯，特别是针对多台机器

的数据共享，⼀般建议使⽤NFS（Network File System，⽹络⽂件系

统）。在开源的解决⽅案中，NFS是标准的⽂件共享解决⽅案，如图

8-3所⽰。

图8-3 NFS原理架构图

在客户端中我们能直接通过mount命令把NFS Server的⽬录挂载映

射到本地⽬录中。对该⽬录的读写，就如同在本地磁盘上读写⽬录⼀

样，可多个客户端共享该⽬录，实现数据的实时共享及同步。但NFS

实践中有⼏个缺点⼀直被⼤家热议，下⾯分别讨论⼀下。

1.NFS的⾼可⽤问题

NFS的Server存在单点问题，如若Server出现异常，会导致客户端

共享的数据都不可⽤。不过结合7.3节所提到的知识可知，⼀些中⼩型

应⽤中没必要过多考虑NFS的⾼可⽤性，因为这些设计需要投⼊额外

的成本。⽐如，有位客户的业务使⽤两台4核8GB的Web应⽤，前⾯挂

着⼀个SLB，这两台ECS⽤NFS做共享，当时客户就提出NFS单点问题

怎么解决等问题。事实上，在⼩型业务中，基本上不⽤考虑NFS的⾼

可⽤问题，通过云盘快照的功能保障数据备份即可满⾜需求。

在传统互联⽹业务使⽤中，⼀般使⽤DRBD+Keeplived来保障NFS

的⾼可⽤，NFS⾼可⽤架构如图8-4所⽰。

DRBD（Distributed Relicated Block Device，分布式复制块设备）

可以解决磁盘单点故障，⼀般情况下只⽀持两个节点。

DRBD的核⼼功能通过Linux的内核实现，最接近系统的I/O栈，但

它不能添加上层的功能，⽐如检测到EXT3⽂件系统的崩溃。DRBD的

位置处于⽂件系统以下，⽐⽂件系统更加靠近操作系统内核及I/O栈。

在实践中，DRBD可以在两个节点中配置主从模式及双主模式，跟

MySQL的主从和主主概念类似。不过在云端，由于不⽀持Keeplived虚

拟VIP技术，所以以上⾼可⽤架构仅适合传统IDC业务架构。

在云端有没有⾼可⽤的架构可以保障NFS的⾼可⽤？答案肯定是

有的，如图8-5所⽰。

两台ECS部署的NFS，采⽤DRBD或者Sersync来实时同步数据⽂

件。我们在内⽹⾃建DNS服务DNSmasq（⼀个⼩巧且⽅便的⽤于配置

DNS和DHCP的⼯具，适⽤于⼩型⽹络，它提供了DNS功能和可选择

的DHCP功能），然后结合Consul（⼀个⽤来实现分布式系统的服务发

现与配置的开源⼯具）做服务⼼跳检测。客户端挂载的NFS Server地

址为域名，⽽不是NFS Sever的IP。如若NFS Server异常，Consul服务

会发现此异常，并将域名解析中这个异常IP的解析换成另外⼀个服务

正常的NFS Server的IP地址。这样客户端连接就感知不到异常从⽽实

现⾼可⽤切换。

图8-4 NFS⾼可⽤架构

图8-5 云端NFS⾼可⽤架构

2.NFS的性能问题.

若NFS客户端超过10台，在中⼤型项⽬中会对NFS Server造成较⼤

的读写压⼒，那么这时候NFS Server在I/O、⽹络带宽中都会出现较⼤

的性能瓶颈。⾼并发I/O读写的场景下，已经不适合NFS部署了。这时

候需要采⽤分布式⽂件系统进⾏数据集中存储管理，在云端可采⽤

OSS对象来存储（底层基于淘宝开源分布式⽂件系统TFS）。

8.2.4 ⽅法四：NAS⽂件共享实践

虽然NFS的部署配置⾮常⽅便快捷，但其实它的⾼可⽤配置、管理

维护还是很复杂的。NAS（Network Attached Storage，阿⾥云⽂件存

储）的推出，彻底解决了NFS安装配置、维护管理、⾼可⽤等⽅⾯的运

维问题。它实现了“开箱即⽤”，这使得ECS之间进⾏⽂件共享变得⾮常

⽅便快捷。

NAS⽀持NFSv3、NFSv4及SMB协议，使⽤标准的⽂件系统语义访

问数据，主流的应⽤程序及⼯作负载⽆须任何修改即可⽆缝配合使

⽤。这使得NAS⽀持在跨地域及混合云的模式下使⽤，且IDC的线下业

务能直接挂载到云端NAS⽂件系统上。NAS主要在VPC内⽹，所以在

⽹络上内⽹打通即可实现NAS跨地域挂载。

1.通过VPN⽹关实现⽤户IDC或者跨地域挂载NAS

通过阿⾥云VPN⽹关服务，可以将IDC内⽹和阿⾥云VPC内⽹打

通，也可以把同城/异地的阿⾥云VPC内⽹打通。阿⾥云VPN⽹关基于

公⽹传输，如若对传输质量、传输速度有⼀定要求，可以使⽤⾼速通

道（Express Connect）专线服务来保障⽹络传输质量。如图8-6所⽰。

底层⽹络打通后，可以⽅便地进⾏以下操作：

·IDC挂载阿⾥云NAS⽂件系统。

·ECS同城/异地挂载阿⾥云NAS⽂件系统。

图8-6 云端跨平台基于VPN⽹络的远程挂载

图8-7 云端跨平台基于NAT⽹络的远程挂载

2.通过NAT⽹关实现⽤户IDC或者跨地域挂载NAS

VPN⽹关或者⾼速通道的部署配置还是有⼀定难度及门槛的，通

过NAT⽹关DNAT将内⽹的NAS服务映射⾄公⽹，这样就可以在IDC机

房中或者在阿⾥云异地地域进⾏远程mount挂载，如图8-7所⽰。

8.2.5 ⽅法五：OSS⽂件共享实践

在⼤型项⽬中，I/O读写压⼒较⼤的⾼并发场景下，如果读写性

能、存储空间都已经满⾜不了现有业务需求，这时候就需要考虑分布

式⽂件系统（对象存储）。在云端OSS对象存储使⽤门槛⽐较⾼，需

要通过代码在RESTful API接⼜对对象进⾏访问操作，从⽽实现⽂件数

据的增删查改及集中化存储管理。在第⼀篇中，云端存储选型也提到

过OSS的使⽤误区及门槛，除⾮业务规模需要，否则不建议使⽤这么

笨重的分布式集群系统。

8.3 OSS⽂件管理的六⼤技巧

OSS作为对象存储（分布式⽂件系统），有很⼤⼀部分偏向业务

侧的实践内容。⽐如：

·如何使⽤OSS存储业务的海量⽂件数据？

·如何使⽤OSS对业务中的⾳视频数据进⾏转码，对业务中的图⽚

数据进⾏格式转换、图⽚缩放/裁剪/旋转等处理？

·如何使⽤OSS结合Hadoop、Spark、DataLakeAnalytics、

MaxCompute进⾏⼤数据处理与分析？

以上这些都是偏向于结合业务的场景，通过OSS的RESTful接⼜完

成。⽽本章讲解的重点是云端对象存储运维层⾯的实践，关于

OSS+CDN⽅⾯的实践，将在第9章中进⾏介绍。

OSS的使⽤，最为重要的是在⽇常运维及业务开发中，怎样对

OSS中的⽂件对象进⾏管理，即如何对OSS中的⽂件对象进⾏增删查

改。

8.3.1 技巧⼀：使⽤API接⼜/SDK管理OSS

OSS API主要通过HTTP请求接⼜来对OSS中的⽂件对象进⾏管

理，API包含的内容主要是请求的语法、请求的相关参数以及请求返

回的⽰例结果。以下是创建bucket接⼜的实例。

请求⽰例如下：

PUT / HTTP/1.1

Host: oss-example.oss-cn-hangzhou.aliyuncs.com

Date: Fri, 24 Feb 2017 03:15:40 GMT

x-oss-acl: private

Authorization: OSS qn6qrrqxo2oawuk53otfjbyc:77Dvh5wQgIjWjwO/KyRt8dOPfo8=

<?xml version="1.0" encoding="UTF-8"?> <CreateBucketConfiguration> <StorageClass> Standard</StorageClass> </CreateBucketConfiguration> 返回⽰例如下：

HTTP/1.1 200 OK

x-oss-request-id: 534B371674E88A4D8906008B

Date: Fri, 24 Feb 2017 03:15:40 GMT

Location: /oss-example

Content-Length: 0

Connection: keep-alive

Server: AliyunOSS

阿⾥云控制台、OSS图形化⼯具、OSS命令⾏⼯具、OSS本地⽂件

系统挂载⼯具、OSS FTP⼯具，底层都是基于OSS API接⼜进⾏⼆次开

发。对OSS API的使⽤，⼀般都是在业务场景中，对开发⼈员的研发

能⼒要求较⾼，使⽤门槛也较⾼。如果要快速进⾏⼆次开发，建议使

⽤OSS的相关SDK（Software Development Kit，软件开发⼯具包），

当前已经⽀持Java、Python、Android、iOS、.NET、Node.js、

Browser.js、React Native、PHP、C、Ruby、Go、Media-C。

8.3.2 技巧⼆：使⽤阿⾥云管理控制台管理OSS

既然OSS API/SDK的使⽤门槛都⽐较⾼，那下⾯就来介绍另⼀种

简单智能化的操作——在阿⾥云管理控制台管理OSS中的数据，如图8-

8所⽰。

阿⾥云的OSS管理控制台，主要偏向于对OSS的整体管理（OSS整

体使⽤情况、OSS基础设置、域名管理等），不适合做OSS的⽂件数据

管理，原因是阿⾥云的OSS管理控制台有以下两个缺点：

·阿⾥云OSS控制台要求上传的⽂件要⼩于5GB。

·阿⾥云OSS控制台不⽀持Multipart Upload的分⽚上传。

所以阿⾥云OSS管理控制台只适合进⾏⼀些简单的⽇常⽂件管理，

当数据量较多较⼤时，使⽤效率就会很低。

图8-8 阿⾥云OSS管理控制台

8.3.3 技巧三：使⽤图形化⼯具管理OSS

使⽤阿⾥云的OSS管理控制台存在诸多不便，要登录阿⾥云控制

台，进⼊OSS管理，再进⼊⽂件管理等，⽽且OSS管理控制台的⽂件管

理功能也⽐较少。为了更加⽅便快捷地管理OSS中的⽂件，可以使⽤相

应的OSS图形化客户端管理⼯具。OSS Browser是OSS官⽅提供的图形

化管理⼯具，⽀持Windows x32、Windows x64、MAC、Linux x64的安

装，缺点是仅⽀持5GB以下的⽂件上传或复制，因此⼀般不推荐使

⽤。OSS客户端的图形化管理⼯具，推荐使⽤驻云的OSS控制台客户端

（⽀持Windows和MAC，阿⾥云的云市场能找到相应⼯具）。OSS图

形化管理客户端⼯具如图8-9所⽰。

图8-9 OSS图形化管理客户端⼯具

这款⼯具主要有⼋⼤功能亮点，如表8-3所⽰。

表8-3 OSS图形化管理客户端⼯具的⼋⼤功能亮点

8.3.4 技巧四：使⽤本地⽂件系统挂载管理OSS

OSSFS能在Linux系统中把OSS Bucket挂载在本地⽂件系统中，能

够像操作本地⽂件⼀样操作OSS对象，实现数据共享。

OSSFS基于S3FS构建，具有S3FS的全部功能。其中包括以下⼏

点：

·⽀持POSIX⽂件系统的⼤部分功能，包括⽂件读写、⽬录、链接

操作、权限、UID/GID，以及扩展属性（extended attributes）等。

·使⽤OSS的multipart功能上传⼤⽂件。

·⽀持MD5校验，保证数据完整性。

OSSFS的数据⾛向原理如图8-10所⽰。

图8-10 OSSFS原理架构图

客户端对本地⽂件请求⽂件读写时，将经过File System→buffer

cache→OSSFS（其实是调⽤OSS API）→OSS来实现，OSSFS允许本

地⽂件系统的读写请求通过OSS API直接读写操作OSS中的⽂件对象。

但OSSFS使⽤有如下缺陷：

·多个客户端挂载同⼀个OSS Bucket或重命名/⽂件夹时，可能会出

错，导致数据不⼀致。

·不适合⾼并发读写场景，性能及稳定性不⾜。

所以并不推荐在业务场景中使⽤OSSFS，但可以将其作为⼀个运

维类⼯具，⽤在数据备份、数据同步等⽅⾯，⽅便⽤户⽇常管理OSS

中的⽂件数据。

云诀窍

相⽐于OSSFS，建议优先使⽤2019年新推出的阿⾥云云存储⽹关

产品。⽽且商业产品，也适⽤于⽣成环境，OSS存储资源会以Bucket

为基础映射成本地⽂件夹或者磁盘。

·云存储⽹关提供了NFS和SMB（CIFS）两种⽂件访问协议，从⽽

实现基于OSS的共享⽂件夹访问。

·云存储⽹关还提供了iSCSI协议，将海量的OSS存储空间映射为本

地磁盘，并提供⾼性价⽐的存储扩容⽅案。

8.3.5 技巧五：使⽤FTP管理OSS

相⽐于OSSFS，OSS FTP⼯具能将FTP请求映射⾄OSS中。它是⼀

个特殊的FTP Server，在接收普通的FTP请求后，它会将对⽂件、⽂件

夹的操作映射为对OSS的操作，从⽽使得⽤户可以基于FTP协议来管理

存储在OSS上的⽂件。

OSS FTP主要功能如下：

·⽀持⽂件和⽂件夹的上传、下载、删除等操作。

·通过Multipart⽅式分⽚上传⼤⽂件。

·⽀持⼤部分FTP指令，可以满⾜⽇常FTP的使⽤需求。

OSS FTP的数据⾛向原理如图8-11所⽰。

图8-11 OSS FTP原理架构图

客户端将FTP的请求中与⽂件、⽂件夹相关的操作通过OSS FTP映

射为对OSS的操作。同样，OSS FTP和OSSFS主要⾯向个⼈⽤户，运维

也可将其视为辅助⼯具，但并不推荐在业务场景中使⽤。

8.3.6 技巧六：使⽤命令⾏⼯具管理OSS

使⽤阿⾥云控制台管理OSS、使⽤图形化⼯具管理OSS、使⽤本地

⽂件系统挂载管理OSS、使⽤FTP管理OSS，可见，虽然底层都是基于

OSS API开发的对应⼯具，但是都是⾯向个⼈⽤户的。虽然业务上可能

直接底层调⽤OSS API来向OSS中进⾏⽂件数据的存储及管理，但是有

没有⼀款基于OSS API的企业级⼯具可以提升我们⽇常维护管理的效率

呢？在之前，我个⼈⼀直特别喜欢⽤OSSCMD这款⼯具来对OSS

Bucket及⽂件进⾏管理。主要是因为这款⼯具基于Python 2.x，也可以

直接修改源码来定制⼀些功能。⽐如，OSSCMD可以通过config命令将

AK保存在配置⽂件中，以使下次执⾏命令时不需要再输⼊AK信息。

但存储在配置⽂件中的AK是明⽂，安全性上较敏感。当初我就直接修

改了OSSCMD的源码，将存储的明⽂改为加密的密⽂，避免别⼈读取

配置⽂件时直接获取AK信息。

当前，对OSS进⾏管理的命令⾏⼯具，官⽅推荐使⽤OSSUTIL。

OSSUTIL是⼀个⼆进制Binary的⼯具包，不需要依赖Python环境，直接

下载就能运⾏，同时OSSUTIL⽀持在Windows、Linux、MAC下运⾏。

从这⼏个功能特性可以看出，OSSUTIL⽐OSSCMD更加⽅便。由于

OSSUTIL是⼀个命令⾏⼯具包，系统中能够通过Shell、Python甚⾄业

务代码直接调⽤，如图8-12所⽰。OSS命令⾏的推出，可以说⼀定程度

上引领了云时代下运维备份的新篇章。这在接下来的云端容灾备份的

实践内容中将进⾏详细介绍。

图8-12 OSSUTIL原理架构图

8.4 四招搞定OSS数据迁移

由于使⽤OSS有⼀定门槛，上⽂通过OSS⽂件管理的六⼤技巧，

介绍了OSS⽂件管理的常⽤应⽤⼯具。正是因为有这些⼯具的存在，

才降低了我们使⽤OSS的门槛。同样，当我们遇到涉及OSS海量数据

迁移场景的时候，我们也需要借助对应⼯具或者阿⾥云⾃带对应的产

品服务功能完成这块数据迁移，提⾼这块迁移效率。

8.4.1 第⼀招：OSSImport⼯具

OSSImport是⼀款基于Java开发的⼯具，可以将本地、其他云存储

的数据迁移到OSS，它有以下特点：

·⽀持丰富的数据源，有本地、七⽜、百度BOS、AWS S3、Azure

Blob、又拍云、腾讯云COS、⾦⼭KS3、HTTP、OSS等，并可根据需

要扩展；

·⽀持断点续传；

·⽀持流量控制；

·⽀持迁移指定时间后的⽂件、特定前缀的⽂件；

·⽀持并⾏数据下载、上传；

·⽀持单机模式和分布式模式，单机模式部署简单，使⽤⽅便，分

布式模式适合⼤规模数据迁移。

之前给客户做OSS的跨账号迁移时，使⽤的是OSSImport迁移⼯

具，它的整体配置及迁移效率⾮常⾼，给我留下了深刻的印象。作为

码农兼运维，个⼈还是偏向于使⽤这些开源的⼯具，因为它们操作起

来⽅便快捷，⽐Web界⾯更加灵活。只需4步即可完成OSSImport配置，

从⽽完成OSS数据迁移，如表8-4所⽰。

表8-4 OSSImport⼯具迁移配置步骤

8.4.2 第⼆招：OSS在线迁移服务

OSS在线迁移服务是官⽅在2018年下半年推出的，阿⾥云在线迁移

服务是阿⾥云提供的存储产品数据通道。使⽤在线迁移服务，可以将

第三⽅数据轻松迁移⾄阿⾥云的对象存储OSS上，也可以在对象存储

OSS之间灵活地进⾏数据迁移。OSS在线迁移服务基本上覆盖了常见的

OSS数据迁移场景：

·阿⾥云OSS之间的数据迁移；

·ECS数据迁移⾄OSS；

·HTTP HTTPS源数据迁移⾄OSS；

·腾讯云COS源数据迁移⾄OSS；

·AWS S3源数据迁移⾄OSS；

·七⽜云源数据迁移⾄OSS；

·Azure Blob源数据迁移⾄OSS；

·又拍云源数据迁移⾄OSS；

·百度云BOS源数据迁移⾄OSS；

·⾦⼭云KS3源数据迁移⾄OSS；

·NAS源数据迁移⾄OSS；

·NAS之间的数据迁移。

四步智能化Web界⾯操作即可搞定OSS数据迁移，如表8-5所⽰。

表8-5 OSS在线迁移服务迁移配置步骤

OSS在线迁移服务的步骤其实跟OSSImport⼯具的迁移步骤基本⼀

致，相⽐之下，OSS在线迁移只需要在Web控制台进⾏简单配置即可，

不需要安装配置，也不⽤理解每个参数的含义等。

8.4.3 第三招：跨区域复制

跨区域复制是在不同OSS地域之间⾃动、异步复制⽂件，将源存储

空间中⽂件的改动（新建、覆盖、删除操作）同步到⽬标存储空间

中。跨区域复制是OSS⾃带的⼀个功能，通过配置跨区域复制能完成同

阿⾥云账号下不同Bucket之间的数据迁移，如图8-13所⽰。

图8-13 跨区域复制配置

相⽐OSSImport⼯具、OSS在线迁移服务，跨区域复制功能不⽀持

跨阿⾥云账号，只⽀持同个阿⾥云账号下不同地域的Bucket迁移。所以

在同个阿⾥云账号下不同地域的Bucket迁移，使⽤跨区域复制的功能来

实现⾮常简单。

8.4.4 第四招：OSS离线迁移

OSS数据迁移的最后⼀种⽅式就是离线迁移，那离线迁移适合哪些

场景呢？当⽤户有TB级别的数据需要上传⾄阿⾥云OSS时，普通的⾛

公⽹⽅式需要很长时间（如10TB的数据，上⾏链路为20Mb/s，约需20

天），⽽且难以保障数据的完整性、安全性等。所以海量数据迁移

OSS，采⽤离线迁移的⽅式就是在线下机房把数据导⼊磁盘，然后再把

磁盘寄到阿⾥云机房，并导⼊OSS中。

驻云海量数据迁移OSS的优势如下：

·10GB⾼速专线连接⾄OSS，确保最快速度上传。注意，⽬前OSS

区域⽀持北京、杭州、深圳。

·深⼊结合OSS产品，通过⾃主研发的⼯具实现数据切⽚多并发上

传，⽆论是GB级⼤⽂件还是KB级⼩⽂件，都可以最快速度上传⾄

OSS。

·通过数据加密、压缩、完整性验证、断点续传⼿段，确保整个上

传过程快速便捷。

·⽀持数据不同加解密⽅式。

·根据客户需求定制数据上传OSS。

海量数据离线迁移⾄OSS的基本流程如图8-14所⽰。

图8-14 海量数据离线迁移⾄OSS的流程

对于海量数据进⾏离线迁移，我也有⼀些经验。2014年我们帮陌

陌（⼀款著名聊天软件）公司，从线下IDC机房迁移了⼀个PB级数据

⾄阿⾥云OSS中。当初我们3个运维⼈员在陌陌公司的天津物理机房花

费了⼀个⽉的时间，将数据导出⾄物理硬盘中（采⽤驻云⾃主研发的

TFS2OSS⼯具），然后再将物理磁盘寄到北京阿⾥云机房，将数据从

磁盘复制⾄OSS中（采⽤驻云⾃主研发的Disk2OSS⼯具）。

对于当前的OSS离线迁移，阿⾥云官⽅已推出闪电⽴⽅离线迁移的

产品服务，将海量数据上云离线迁移标准化了。闪电⽴⽅离线迁移是

阿⾥云提供的安全、⾼效、便捷的数据迁移服务，致⼒于保障⼤规模

数据⾼传输效率、安全等。企业通过定制化的迁移设备（闪电⽴

⽅），可实现TB到PB级别的本地数据迁移上云。

⽬前，闪电⽴⽅提供三种类型的设备，分别适⽤不同数据量的迁

移场景，并且可多套设备叠加使⽤：

·闪电⽴⽅Mini为塔式设备，存储计算⼀体，已经预装闪电⽴⽅

Agent。其可开机直接使⽤，提供图形化控制界⾯。

·闪电⽴⽅II和闪电⽴⽅III为存储节点，需要使⽤额外的服务器部

署闪电⽴⽅Agent（即需要单独准备虚拟机或者物理机）。

·闪电⽴⽅所有系列产品都有两个万兆的光⼜和电⼜，你可以根据

交换机情况灵活选择。

闪电⽴⽅的三种类型设备的详细数据参考表8-6（更多产品信息可

参考阿⾥云官⽅产品帮助⼿册）：

表8-6 闪电⽴⽅三种类型产品的详细数据

8.5 运维容灾备份新篇章

传统的IDC进⾏数据备份的⽅式如图8-15所⽰。

图8-15 传统数据备份流程

传统运维容灾备份中有个很重要的⾓⾊就是备份服务器，可在内

⽹中放置⼀台磁盘存储空间很⼤的备份服务器来集中存放业务数据的

备份⽂件。如果是⼀些⽐较敏感的重要业务数据，那么可进⼀步将数

据存放⾄远程备份服务器，甚⾄进⾏刻盘归档即可。⽽在云端，对象

存储OSS彻底替代了传统备份服务器的⾓⾊。云端运维容灾备份架构如

图8-16所⽰。

在云端，快照基本上能满⾜我们ECS的数据备份需求。不过，快照

是针对磁盘级别进⾏备份的，若针对单个⽂件等更细粒度的备份，可

以结合OSSFTP、OSSFS、OSSUTIL、OSS客户端、OSS⽹关服务直接

将数据从内⽹备份⾄OSS中。我们也可以将线下IDC的数据直接备份⾄

云端OSS中。现在的混合云的结构中，异地容灾备份是⾮常热门的容灾

⽅案。相⽐于传统IDC的备份⽅案，我们已经不再需要单独设置备份服

务器了。

图8-16 云端数据备份流程

第9章 云端缓存实践

缓存是⼀种典型的以牺牲数据时效性换取访问性能的技术，是中

⼤型架构中应⽤最为⼴泛的技术。静态缓存，主要应⽤在Web应⽤

中，提供⽹站访问性能。⽽动态缓存，除了常见的数据库热点数据缓

存外，还应⽤在Session缓存及动态页⾯缓存中。除了⼤家常见的CDN

静态缓存、Memcache/Redis数据库动态缓存技术实践外，本章还介绍

了Session缓存共享、动态页⾯缓存等缓存领域其他⽅⾯的技术实践内

容，相信对云端缓存技术的实践、架构规划等⽅⾯都是不错的参考。

9.1 使⽤静态缓存提升⽹站性能的四种⽅法

静态缓存，⼀般是指Web类应⽤中，将HTML、JS、CSS、图⽚、

⾳视频等静态⽂件/资源通过磁盘/内存等缓存⽅式来存储，从⽽提⾼

资源响应⽅式，减少服务器压⼒/资源开销。说起静态缓存技术，CDN

是经典的代表作。静态缓存的技术⾯⾮常⼴，涉及的开源技术包含

Apache、LigHttpd、Nginx、Varnish、Squid等。在第⼀篇中也跟⼤家

详细介绍了静态缓存相关的技术选型，本⽂主要介绍静态缓存在实际

运⽤中的5种实践⽅法，⽤以全⾯提升⽹站访问性能。

9.1.1 ⽅法⼀：浏览器缓存

浏览器缓存，也称为客户端缓存，是静态缓存中最常见、最直接

的表现形式，然⽽往往会被⼈忽略掉。

我们经常会在Nginx的配置⽂件中看到以下缓存配置（案例1）：

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$

{

expires 1d;

}

location ~ .*\.(js|css)?$

{

expires 15d;

}

在写JSP的时候，经常也会在HTML标签中关于HTTP的头信息中看

到“expires”的字样（案例2）：

<title>My JSP 'index.jsp' starting page</title>

<meta http-equiv="expires" content="60">

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

<meta http-equiv="description" content="This is my page"> 在案例1和案例2中（Nginx设置的expires优先级⼤于代码中设置的

expires优先级），expires⽤于给⼀个资源设定⼀个过期时间，也就是说

⽆须去服务端验证，直接通过浏览器⾃⾝确认是否过期即可，所以不

会产⽣额外的流量。此种⽅法⾮常适合不经常变动的资源。但如果⽂

件变动较频繁，则不要使⽤expires来缓存。⽐如对于常见的类Web⽹站

来说，CSS样式和JS脚本基本已经定型，所以最适合通过expires来缓存

⼀些内容到访问者的浏览器上。图9-1所⽰为通过Chrome访问服务器端

的⼀张图⽚，通过F12键打开开发者前端调试⼯具。

图9-1 ⾸次访问服务器图⽚的HTTP状态码

第⼀次访问时，响应的状态是200，当第⼆次及后续访问的时候，

响应状态变成了304，如图9-2所⽰，这表⽰客户端已经开始获取浏览器

缓存内容，不需要去服务器端获取对应的请求内容了，即Nginx中

expires参数设置已经⽣效。待客户端缓存时间过期后，会再次请求服

务器端内容来更新本地缓存。

图9-2 第⼆次访问服务器图⽚的HTTP状态码

这⾥介绍⼀个有意思的需求。⽐如，访问⼀个静态⽂件时，不想

让客户端缓存，⽽是希望每次都去服务器端获取数据。那要如何实现

呢？我们可以⽤last-modified参数来实现，last-modified是根据⽂件更新

时间来确定是否再次发送加载的。Nginx的核⼼配置如下：

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$

{

add_header Last-modified 10;

expires 1d;

}

更改掉服务器传回客户端的“last-modified”⽂件，修改时间参数的

值，这样就致使客户端本地保存的⽂件时间跟服务器端传回来的时间

每次都不⼀致，所以每次客户端都会“误认为”服务器端有静态⽂件更

新，然后每次都会去服务器端获取所谓的最新数据。这样我们就可以

看到，不管浏览器访问多少次，返回的HTTP状态都是200，再也找不

到304状态了。

云诀窍

在Nginx中设置expires，并不是指把静态内容缓存在Nginx中，⽽

是设置客户端浏览器缓存的时间，这是很多⼈理解的误区所在。

9.1.2 ⽅法⼆：磁盘缓存

除了存储在客户端的静态缓存（浏览器静态）技术外，服务器端

的静态缓存技术主要分为磁盘缓存类和内存缓存类两⼤类。在第4章中

已跟⼤家详细介绍了静态缓存常⽤技术，主要通过Squid、Varnish、

Nginx⼀类中间件来实现，不仅处理静态数据的性能⼗分优秀，还能将

静态资源通过磁盘/内存进⾏缓存，从⽽进⼀步提升访问性能。

所谓磁盘缓存，顾名思义，是指将静态资源⽂件通过磁盘进⾏缓

存的技术。以Nginx配置为例：

#levels设置⽬录层次

#keys_zone设置缓存名字和共享内存⼤⼩

#inactive在指定时间内⽆⼈访问则被删除，在这⾥是1天

#max_size最⼤缓存空间

proxy_cache_path /alidata/www/default/cache_dir/ levels=1:2

keys_zone=cache_one:200m inactive=1d max_size=30g;

server {

listen 82;

server_name _;

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|html)$

{

proxy_cache cache_one; # keys_zone后的内容对应

proxy_cache_valid 200 304 301 302 10d; #哪些状态缓存多⻓时间

proxy_cache_valid any 1d; #其他的缓存多⻓时间

proxy_cache_key $host$uri$is_args$args; #通过key来HASH，定义key的值

proxy_pass http://10.168.247.180:81/;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

access_log /alidata/nginx/logs/default-cache.log;

}

可以看出Nginx主要通过proxy_cache来实现Web Cache，熟悉Nginx

的读者不难看出，以上配置在location这⾥，不仅可以实现静态⽂件的

缓存，还可以实现动态⽂件的缓存（相关内容在9.2节中进⾏详细介

绍）。下⾯编写个test.html测试⽂件，然后通过访问这个静态⽂件，来

看看磁盘缓存的实际效果。test.html源码如下：

<html>

<head>

<title>test cache</title>

<meta http-equiv="expires" content="-1">

</head>

<body>

<br>

<img src='eg_tulip.jpg'>

</body>

</html>

不难发现，服务器的cache⽬录⾥⾯，多了两个缓存⽂件：

/alidata/www/default/cache_dir/c/68/b0ad5d3e7f099bfff9e4fc6a159d868c

/alidata/www/default/cache_dir/f/fa/53edc39ed253e14415a29412cfc01faf 有意思的是，这两个⽂件⾥⾯的内容（通过less命令查看）分别如

图9-3和图9-4所⽰。

图9-3 缓存⽂件：b0ad5d3e7f099bfff9e4fc6a159d868c

图9-4 缓存⽂件：53edc39ed253e14415a29412cfc01faf

所以不难看出，Nginx把HTML内容和图⽚⼆进制全部缓存到本地

磁盘上了。下次⽤户再次来访问test.html的时候，Nginx会直接将缓存

在本地磁盘的⽂件返回给⽤户。特别是后端，如若部署的是Tomcat、

IIS等，Nginx强⼤的静态缓存能⼒将有效减少服务器压⼒。

9.1.3 ⽅法三：内存缓存

内存缓存，顾名思义，就是把静态⽂件缓存在服务器端的内存

中。在这种缓存⽅式下，如若命中缓存的话，取内存中的缓存数据返

回⽐取磁盘中的缓存数据返回性能要⾼很多。以Varnish为例，启动命

令为：

varnishd -f default.vcl -s malloc,2G -a 0.0.0.0:80 -w 1024,51200,10 -t 3600 -T

192.168.100.2:3500

Varnish的核⼼配置参数简介如下：

·-a address：port：监听端⼜；

·-f：指定配置⽂件；

·-s：指定缓存类型malloc为内存，file⽂件缓存；

·-t：默认TTL；

·-T address：port：管理端⼜；

·-w：最⼩线程，最⼤线程，超时时间。

default.vcl的核⼼配置如下：

sub vcl_fetch {

if (req.request == "GET" && req.url ~ "\.(gif|jpg|jpeg|png|bmp|swf|html)$") {

set obj.ttl = 3600s;

}

}

Varnish将以.gif、.jpg、.jpeg、.png等结尾的URL的缓存时间设置

为1⼩时。Varnish设置完毕后，可⽤命令⾏的⽅式通过查看⽹页头来

查看命中情况：

[root@test-varnish ~]# curl -I http://***.***.***.***/test.html HTTP/1.1 200 OK

Server: Apache/2.2.27 (Unix) PHP/5.3.18 mod_perl/2.0.4 Perl/v5.10.1

Last-Modified: Sat, 10 Jul 2016 11:25:15 GMT

ETag: "55dh9-233f-33d23c3758dg2"

Content-Type: text/html

Content-Length: 23423

Date: Fri, 18 May 2016 21:29:16 GMT

X-Varnish: 1364285597

Age: 0

Via: 1.1 varnish

Connection: keep-alive

X-Cache: MISS from ***.***.***.*** #这⾥的“MISS”表示此次访问没有从缓存读取

[root@test-varnish ~]# curl -I http://***.***.***.***/test.html HTTP/1.1 200 OK

Server: Apache/2.2.27 (Unix) PHP/5.3.18 mod_perl/2.0.4 Perl/v5.10.1

Last-Modified: Sat, 10 Jul 2010 11:25:15 GMT

ETag: "55dh9-233f-33d23c3758dg2"

Content-Type: text/html

Content-Length: 23423

Date: Fri, 18 May 2016 21:40:23 GMT

X-Varnish: 1364398612 1364285597

Age: 79

Via: 1.1 varnish

Connection: keep-alive

X-Cache: HIT from ***.***.***.*** #由“HIT”可知，第⼆次访问此⻚⾯时，从缓存中

?读取内容，也就是缓存命中

最后，我们可以通过varnishadm命令来清理缓存，也可以通过

varnishstat命令来查看Varnish系统的缓存状态。

9.1.4 ⽅法四：CDN（动静分离）

浏览器缓存、磁盘缓存、内存缓存分别是客户端缓存和服务器端

缓存的设置，⽽在云端，CDN已经包含了浏览器缓存、磁盘缓存、内

存缓存所代表的静态缓存（客户端静态缓存和服务器静态缓存），这

让我们节省了⼤量去部署配置的精⼒。但静态缓存的实施，⼀般不会

单独去使⽤浏览器缓存、磁盘缓存、内存缓存等技术点，⽽是会配合

动静分离的架构来应⽤，即将静态资源单独部署在静态服务器上，将

动态请求的业务请求单独部署在业务服务器上。事实上，CDN不仅是

云端静态缓存的最佳实践，更是动静分离的最佳实践。

如何通过CDN进⾏动静分离，在云端常规的做法有以下3种：

（1）⼩型应⽤

⼩型应⽤中，Nginx作为前端反向代理服务器，主业务域名解析绑

定在前端代理服务器上，且静态资源也存放⾄代理服务器上。在Nginx

七层通过Rewrite对请求做判断，如果是静态资源请求，直接请求本机

的静态资源，也可进⼀步设置对应的静态缓存。如果是动态请求，则

转发给后端服务器处理。这是常规动静分离最为成熟的解决⽅案。这

个场景下不需要CDN的接⼊，采⽤ECS带宽或者SLB带宽即可满⾜⽤

户⽇常访问需求，如图9-5所⽰。

（2）中型应⽤

中型应⽤中，有⼀定⽤户规模。在⽤户请求中，静态资源已经开

始占⽤较⼤⽹络带宽及消耗服务器的I/O性能。这时接⼊CDN来替代

Nginx动静分离Rewrite规则，通过CDN的静态资源缓存分发，节省我

们⾃⼰配置动态分离的成本及带宽成本，并进⼀步提升访问性能。在

这个时候，不必过早引⼊OSS，除⾮是出于业务上的规划需求等，否

则会增加应⽤的维护成本和复杂度，没太⼤必要。中型应⽤中，静态

资源⼀般会和应⽤代码⼀起部署。要实现静态加速，前端只需要加个

CDN，CDN会针对客户端请求，进⾏回源并主动缓存静态资源，如图

9-6所⽰。

图9-5 Nginx的动静分离

图9-6 CDN的动静分离

（3）⼤型应⽤

⼤型应⽤中，主业务的域名会直接绑定在业务服务器的负载均衡

IP上。静态资源会采⽤单独的Web服务器部署，并且会跟静态资源绑

定独⽴的⼆级域名来做请求分流。⽤户在请求对应的页⾯（包含静态

请求和动态请求）时，静态请求会被隐式重定向（不显⽰跳转后的

URL）引流到静态服务器上，所以对客户端⽽⾔是不可感知的。在京

东、淘宝等⼤型Web应⽤中，⽏庸置疑都是做了动静分离的，通过浏

览器的debug模式，我们能清楚地看到JS、CSS、图⽚等静态资源的数

据源都是单独的⼆级域名的URL地址。不过这种⽅式的动静分离有个

前提条件，就是需要进⾏⼀定的代码改造。

图9-7 CDN+OSS+单独静态资源域名的动静分离

在⼤型应⽤中，我们怎么使⽤CDN进⾏动静分离呢？如果想进⼀

步提升静态资源的访问速度，可以单独针对静态资源服务器加上

CDN，即将CDN的回源地址解析绑定到静态资源的域名上。在云端实

践中，我们可以把静态资源单独放在OSS中，以OSS作为静态资源服

务器，替代还需要单独部署Web服务器来管理静态资源的传统⽅式。

然后前端再接⼊CDN，CDN的回源请求去OSS中获取数据。CDN和

OSS的⽆缝结合，使其在云端架构及管理维护上⾮常⽅便。如果⽹站

业务是纯的静态内容，甚⾄可以将静态⽹站直接托管⾄OSS中运⾏，

如图9-7所⽰。

9.2 动态缓存的三种应⽤场景实践

静态缓存主要⽤于缓存客户端请求的静态数据，如图⽚、

HTML、JS、CSS等。⽽动态缓存，顾名思义，⽤于缓存业务中的动

态数据，如业务处理的临时数据、频繁对数据库访问查询的热点数

据、⽤户Session数据、动态页⾯数据等，甚⾄频繁访问的静态页⾯数

据也是通过动态缓存技术（Redis、Memcache）进⾏缓存的。

9.2.1 场景⼀：数据库缓存

在动态缓存应⽤中，最为常见的就是数据库缓存了。

我们知道，常见的数据库⽐如Oracle、MySQL等，数据都是存放

在磁盘中的。虽然在数据库层也做了对应的缓存，但这种数据库层⾯

的缓存⼀般针对的是查询内容，⽽且粒度也太⼩，只有表中数据没有

变更的时候，数据库对应的Cache才会发挥作⽤。但这并不能减少业务

系统对数据库产⽣的增、删、查、改的庞⼤I/O压⼒。所以数据库缓存

技术由此诞⽣，从⽽实现热点数据的⾼速缓存，提⾼应⽤的响应速

度，极⼤缓解后端数据库的压⼒。

下⾯以Memcache数据库缓存为例，说明⼀下什么是数据库缓存

（如图9-8所⽰）。

图9-8 Memcache对数据库的缓存

数据缓存有以下四⼤技术特点。

（1）性能优越

数据库缓存的第⼀个技术特点就是提⾼性能，所以数据库缓存的

数据基本上都是存储在内存中的，相⽐I/O读写的速度，数据访问能更

快速返回。⽽且从MySQL 5.6的版本开始，它已经把Memcache这种跟

数据库缓存直接挂钩的中间件直接集成进去了，已经不⽤我们去单独

部署对应数据库缓存的中间件了。

（2）应⽤场景

对于数据库的增、删、查、改，数据库缓存技术应⽤场景绝⼤部

分针对的是“查”的场景，如⼀篇经常访问的帖⼦/⽂章/新闻、热门商品

的描述信息、好友评论/留⾔等。因为在常见的应⽤中，数据库层次的

压⼒有80%是来⾃查询，剩下的20%才是来⾃数据的变更操作。所以

绝⼤部分的应⽤场景还是“查”缓存。当然，“增、删、改”的场景也是

有的。⽐如，⼀篇⽂章访问的次数，不可能每访问⼀次，我们就去数

据库⾥⾯加⼀次吧？这时，“增”场景的缓存就必不可少了。否则，⼀

篇⽂章被访问了⼗万次，代码层次还要去做⼗万次的数据库操作。

（3）数据⼀致性

在很多应⽤场景中，当⼀个数据发⽣变更的时候，很多⼈在考虑

怎样确保缓存的数据和数据库中的数据保持⼀致，确保从缓存中读取

的数据是最新的。甚⾄，有⼈在对应数据变更的时候，是先更新数据

库，然后再去更新缓存。这⼀⽅⾯会导致代码层次逻辑变得复杂，另

⼀⽅⾯缓存也失去了存在的意义。在绝⼤多数的应⽤中，缓存中的数

据和数据库中的数据是不⼀致的。即，我们牺牲了实时性换回了访问

速度。⽐如，⼀篇经常访问的帖⼦，可能这篇帖⼦已经在数据库层次

进⾏了变更。⽽我们每次访问的时候，读取的都是缓存中的数据（帖

⼦）。既然是缓存，那么必然是对实时性可以有⼀定容忍度的数据，

容忍度的时间可以是5分钟，也可以是5⼩时，这取决于业务场景的要

求。相反，⼀定要求是实时性的数据库，就不应该从缓存⾥读取，⽐

如库存，再如价格。

（4）⾼可⽤

为什么说数据缓存⾼可⽤呢，我们知道缓存为数据库分担了很多

压⼒，同时也为应⽤提供了较⾼的访问速度。但如果当数据库缓存“罢

⼯”了，这会出现什么后果？特别是在⼀些⾼并发的应⽤中，数据库层

肯定会“消化不良”，最终会导致应⽤全⾯瘫痪。所以缓存的⾼可⽤显

得⾮常重要。

9.2.2 场景⼆：集中Session管理的六种策略

⽽在分布式架构中，负载均衡的引⼊会导致⽂件存储需要集中管

理，并且会出现Session会话的问题。Session会话的技术问题，其实偏

向云端负载均衡的实践。但在Session会话保持的技术中，通过动态缓

存相应技术（Redis/Memcache）来集中存储及管理Session是⽐较成熟

的架构，所以主要在动态缓存这⾥来跟⼤家分享。

我们先来看看什么是Session，Session是程序中⽤于和客户端请求

进⾏会话保持的⼀种技术。PHP会默认将Session数据存在本机磁盘⽂

件上，⽽Tomcat会默认将Session数据存放⾄JVM分配的内存中。我还

记得曾在⽆锡⼀家公司⾯试Java开发的岗位时，最后⼀轮由技术总监⾯

试，他问过我⼀个相关的技术问题，这个问题是针对系统登录的代码

处理流程的。

技术总监问：“⽤户登录状态存在哪⾥？”

我回答：“存放在Session中。”

技术总监继续问：“Session是存在哪⾥的？”

我回答：“存放在Tomcat中。”

技术总监继续问：“Tomcat中能存放多少Session数据？”

我顿时有点懵，对这个问题没有⼀点概念。当时回答：“……好像

没有限制吧。”

图9-9 负载均衡中对Session的请求

这些年，我⼀直想着这问题，现在终于有了答案。⾸先，Session

存放的⽤户状态数据是有⼤⼩的，这⾥假设每个Session存放的⼤⼩为

1KB。其次，Tomcat使⽤的内存⼤⼩也有限制，这主要取决于Tomcat设

置的可使⽤最⼤JVM内存，假设设置的⼤⼩为1024MB（等于

1024×1024=1048576KB）。则Tomcat中存放的Session的个数极限值

是：1048576KB/1KB，即⼀百万个，这也从侧⾯说明能⽀持⼀百万⽤

户同时在线。不过这是极值，我们未考虑代码处理中，还有其他业务

计算的地⽅需要⼤量占⽤内存。

⽽什么又是Session共享问题呢？如图9-9所⽰。

当⽤户第⼀次发送登录请求时，负载均衡将请求转发⾄后端服务

器1，这时候程序会将⽤户登录的状态保存在服务器1。当⽤户第⼆次

发送查询请求时，负载均衡可能会将请求转发⾄后端服务器2。但是如

果到服务器2中没有发现登录的状态信息，这时候系统会跳转⾄登录页

⾯要求⽤户重新登录系统。所以在负载均衡的分布式应⽤中，当请求

转到服务器2上，也能获取到服务器1上的Session数据，我们需要在服

务器端采⽤Session共享的相应技术来集中管理，常见的做法有以下6

种。

策略⼀：基于源IP的会话保持

基于源IP的会话保持，是指负载均衡识别客户端请求的源IP地址，

将同⼀IP地址的请求转发到同⼀台后端服务器进⾏处理。若将客户端

的请求绑定在后端某⼀台服务器上，不让请求轮询到其他服务器上，

那么就不会出现Session会话的问题。

⽐如，在Nginx中配置ip_hash，通过识别客户端IP，将请求转给后

端同⼀个服务器（将请求绑定在某台服务器上处理），以达到会话保

持的效果。这是中⼩型企业做Session会话保持的最常⽤的做法。配置

案例如下：

upstream www.cloudcare,cn {

server 192.168.1.1:80;

server 192.168.1.2:80;

ip_hash;

}

云诀窍

HAProxy的balance source算法和Nginx的ip_hash，它们的算法原理

是⼀样的。

再如，四层的SLB会话保持，也是基于源IP地址的会话保持，如图

9-10所⽰。

图9-10 四层SLB的会话保持

虽然基于源IP的会话保持配置⾮常⽅便快捷，但是此⽅案有两个

很明显的缺点：

1）基于源IP的会话保持在实践中虽然解决了会话保持的问题，但

流量均衡做得并不是很理想，⽐如驻云上海办公⽹络（有200⼈办公）

去请求Nginx时，如果Nginx配置了ip_hash参数，那么这200⼈的请求都

会被Nginx转发到后端的某⼀台服务器上，并不能很好地进⾏流量负载

均衡。

2）基于源IP的会话保持的体验性可能并不好，假如后端服务器出

现异常宕机，那么问题就来了。绑定在这台服务器上存储的Session数

据会全部丢失，下次客户请求由负载均衡调度，负载均衡看到后端这

台服务器宕机，则将请求转发到新的后端服务器上，⽽新的后端服务

器没有该⽤户请求的Session数据。这时候会让客户端重新登录系统，

但⽤户端并不知道后端这台服务器宕机。所以会感觉莫名其妙，怎么

又让我登录？

策略⼆：基于浏览器Cookie的会话保持

为了解决基于源IP会话保持所带来的后端流量不均衡的问题，出

现了基于浏览器Cookie的会话保持，它很好地解决了该问题。哪怕再

多⼈共⽤⼀个IP也不⽤担⼼，因为客户端是根据客户端请求的Cookie进

⾏转发的。七层SLB的会话保持，就是基于Cookie的会话保持的，如图

9-11所⽰。

图9-11 七层基于浏览器Cookie的会话保持

七层SLB Cookie处理主要分为以下两种。

1）植⼊Cookie：指客户端第⼀次访问时，负载均衡会在返回请求

中植⼊Cookie，下次客户端携带此Cookie访问，负载均衡会将请求定向

转发给之前记录到的后端服务器上。

2）重写Cookie：根据需要指定HTTP/HTTPS响应中插⼊Cookie，

在后端服务器上维护该Cookie的过期时间和⽣存时间。

Nginx使⽤第三⽅模块nginx-sticky-module-ng为每个⽤户插⼊⼀个

Cookie，后续请求也都会带上这个Cookie。负载均衡会识别前端请求中

的Cookie，然后根据这个Cookie选择后端相应服务器。由于是第三⽅模

块，所以需要重新编译Nginx。然后在Nginx配置⽂件的upstream⽚段中

去掉ip_hash等策略，并加上sticky配置。其中sticky后⾯还可以跟参

数，⽐如“sticky expires=12h domain=cloudcare.cn path=/;”。

相⽐Nginx，HAProxy在Cookie⽅⾯的设置就要灵活得多。在云端

选型篇的负载均衡选型中曾跟⼤家对⽐过Nginx及HAProxy的优缺点。

HAProxy在Cookie设置中，⽀持Insert、Rewrite和Prefix这3种设置

Cookie的⽅式。

·Insert设置Cookie⽅式：HAProxy将在客户端没有Cookie（⽐如第

⼀次请求）时，在响应报⽂中插⼊⼀个Cookie。

·Rewrite设置Cookie⽅式：顾名思义，使⽤Rewrite模式时，

HAProxy将重写该Cookie的值。

·Rrefix设置Cookie⽅式：HAProxy将在已存在的Cookie（例如后端

应⽤服务器设置的）上添加前缀Cookie值。

此外，HAProxy还提供了⼀些额外的针对Cookie的功能设置。由于

篇幅有限，就不详细介绍，更多内容可以参考HAProxy官⽹。

策略三：数据库存放Session

图9-12 Session存放在数据库中

虽然基于浏览器Cookie的会话保持解决了基于源IP的会话保持中转

发给后端流量不均衡的问题，但是没有解决基于源IP的会话保持中，

后端某⼀台服务器宕机了，存储在这台服务器上的Session丢失的问

题。所以为了解决这个问题，我们就不能把Session存放在服务器本地

的内存或者⽂件中。在实际应⽤中有⼀种解决办法，就是把Session存

放在数据库中，如图9-12所⽰。

当⽤户第⼀次发送登录请求，在服务器1上直接将Session数据存放

⾄数据库中，⽽不是存放在本地内存或者本地磁盘⽂件上。这样在第

⼆次请求时，即使负载均衡将请求转发⾄后端服务器2上，仍会⾸先去

数据库中取出Session数据，这样在服务器2上就不会提⽰⽤户再登录

了。虽然这种⽅式解决了后端服务器宕机Session丢失的问题，但是带

来了更严重的性能问题，在实际应⽤中强烈建议不要这么使⽤。因为

数据库往往是业务性能瓶颈点，如果将Session存储到数据库表中，频

繁的数据库操作会影响业务正常访问，得不偿失。

在云端我们也曾遇到过对应的真实案例，某花卉电商系统，平时

业务正常访问没多⼤问题。但是⼀到活动的时候，访问就奇卡⽆⽐。

刚开始，我们还以为是前端Web或者CDN⽅⾯出了性能问题。后来才

发现，在RDS数据库中有⼤量的select进程被堵塞，导致数据库性能被

撑爆了。跟客户确认这些SQL语句的主要⽤途时，客户发现这是每次

⽤户请求时，到数据库查询该请求对应的Session数据从⽽产⽣的语

句。原来希望将Session存放在数据库中，解决Session会话保持的问

题。但是⼀到活动期间，⽤户访问量增加，导致数据库操作频繁，数

据库成为性能的瓶颈，从⽽导致业务性能严重跟不上。

PHP使⽤数据库存放Session的配置案例如下。

php.ini的配置如下：

session.save_handler = user

数据库表[sessions]的建表语句如下：

CREATE TABLE sessions (

sesskey char(32) not null,

expiry int(11) unsigned not null,

value text not null,

PRIMARY KEY (sesskey)

);

需要在PHP代码[session_inc.php]中实现Session⽂件持久化到数据

库中，⽰例如下：

<?php

$SESS_DBHOST = "yourhost"; /* database server hostname */

$SESS_DBNAME = "yourdb"; /* database name */

$SESS_DBUSER = "youruser"; /* database user */

$SESS_DBPASS = "yourpassword"; /* database password */

.. session set ...

.. session get ...

?>

Tomcat使⽤数据库存放Session的配置案例如下（context.xml）：

<Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart=

"true" maxActiveSession="-1" minIdleSwap="0" maxIdleSwap="30" maxIdleBackup="0">

<!-- db store -->

<Store className="org.apache.catalina.session.JDBCStore"

driverName="com.mysql.jdbc.Driver"

connectionURL="jdbc:mysql://localhost:3306/demo?user=root&amp;password=123456"

sessionTable="t_session"

sessionIdCol="session_id"

sessionDataCol="data"

sessionValidCol="session_valid"

sessionMaxInactiveCol="max_inactive"

sessionLastAccessedCol="last_access"

sessionAppCol="application_name"

checkInterval="60"

debug="99" />

</Manager>

⽤于存放Session的数据库表结构如下：

CREATE TABLÈt_session` (

`session_id` varchar(128) DEFAULT NULL,

`datà mediumblob,

`max_inactiveìnt(128) DEFAULT NULL,

`last_access` bigint(20) DEFAULT NULL,

àpplication_namè varchar(128) DEFAULT NULL,

`session_valid` char(1) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 策略四：动态缓存的集中Session管理

在实际应⽤中，通过使⽤数据库存储Session的⽅式来解决服务器

宕机致使Session丢失的问题，显然是不可取的。⽽采⽤Redis、

Memcache动态缓存技术来集中存储及管理Session，是中⼤型应⽤中最

为成熟且常见的⽅案。由于Memcache相⽐Redis，不⽀持内存数据的持

久化，所以在Session集中化存储管理中，默认优先选⽤Redis。

PHP中配置和Memcache的集成⾮常⽅便，php.ini只需要配置两

项：

session.save_handler=memcache

session.save_path="tcp://127.0.0.1:11211"

⽽配置Tomcat使⽤Redis来进⾏Session管理，相⽐PHP的配置要复

杂得多，配置案例如下：

1）在Tomcat/lib中增加以下jar包：

commons-pool2-2.4.2.jar jedis-2.8.0.jar

tomcat-redis-session-manager-2.0.0.jar

2）修改tomcat/conf/context.xml，增加下⾯两⾏内容：

<Valve

className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />

<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"

host="192.168.2.3"

port="6379"

database="0"

password="cloudcare"

maxInactiveInterval="600"/>

实现以上配置后，“session.setattribute()”向Session中存储的数

据、“session.getAttribute”向Session中获取数据时，都不是存储在JVM

的内存中了，⽽是直接存储在Redis中。

云诀窍

建议使⽤阿⾥云Memcache/Redis，⾃建的Memcache/Redis搭建、维

护、成本、效率等都不是最优⽅案。⽽且阿⾥云Memcache⽀持数据持

久化，不⽤担⼼Memcache内存中的数据丢失。

策略五：基于Tomcat集群Session共享

动态缓存的集中Session管理中，Tomcat+Redis通过配置Tomcat将

Session直接存放⾄Redis中。但是，在代码语法使⽤上是有所不同的。

除了这种⽅式外，还有其他⽅案吗？有，那就是Tomcat的Session集群

共享，不过这种⽅式的配置管理有些烦琐。只适合⼩集群使⽤，⼤集

群还是建议使⽤Redis或者Memcache进⾏共享。

相应的配置案例如下，在conf/server.xml⽂件中找到该⾏：

<Engine name="Catalina" defaultHost="localhost"> 在该⾏下⾯配置集群配置信息就可以了，如下：

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"

channelSendOptions="8">

<Manager className="org.apache.catalina.ha.session.DeltaManager"

expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/>

<Channel className="org.apache.catalina.tribes.group.GroupChannel">

<Membership className="org.apache.catalina.tribes.membership.McastService"

address="228.0.0.4"

port="45564"

frequency="500"

dropTime="3000"/>

<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"

address="auto"

port="4000"

autoBind="100"

selectorTimeout="5000"

maxThreads="6"/>

<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">

<Transport

className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>

</Sender>

<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailure Detector"/>

<Interceptor

className="org.apache.catalina.tribes.group.interceptors.MessageDispatch 15Interceptor"/>

</Channel>

<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>

<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"

tempDir="/alidata/tomcat/tmp/war-temp/"

deployDir="/alidata/tomcat/tmp/war-deploy/"

watchDir="/alidat/tomcat/tmp/war-listen/"

watchEnabled="false"/>

<ClusterListener

className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>

<ClusterListener

className="org.apache.catalina.ha.session.ClusterSessionListener"/>

</Cluster>

以上配置需要在多个Tomcat中进⾏配置，如果是同⼀个集群，⾥

⾯配置信息保持⼀致就可以了。如果是其他集群，修改⼀下address就

好了。

策略六：基于NAS⽂件共享

Session除了可以存放在本地内存中以外，当然也可以存放在本地

磁盘⽂件上。存放在本地内存中的数据，服务器宕机、内存数据丢

失，都会导致Session丢失，但可以通过Redis/Memcache等动态缓存技

术将Session进⾏集中管理并共享。同样，存放在本地磁盘⽂件中的数

据，若因为服务器宕机，磁盘⽂件中的Session没办法访问，都可以通

过NAS做磁盘⽂件共享。即使服务器宕机，存放在NAS中的Session⽂

件还存在，并不影响客户请求及对Session⽂件的读写。但是NAS中的

⽂件读写，涉及磁盘I/O。相⽐之下，Redis、Memcache读写是内存数

据的读写操作，内存中的读取性能是⾮常快的，所以基于动态缓存技

术的集中Session管理适合中⼤型项⽬应⽤。⽽磁盘I/O相⽐内存的速度

要慢许多，⼤规模读写会造成很严重的性能瓶颈。所以NAS⽂件共享

只适合中⼩规模项⽬应⽤。

PHP使⽤本地磁盘⽂件存放Session的配置案例如下（php.ini）：

session.save_handler = files

session.save_path = "N;MODE;/path"

注释 N表⽰多级⽬录，值为数字。MODE表⽰创建的Session

⽂件权限。/path表⽰Session存储路径，可以配置本地磁盘路径，也可

以配置NAS共享⽂件的路径。

Tomcat使⽤本地磁盘⽂件存放Session的配置案例如下

（context.xml）：

<Manager className="org.apache.catalina.session.PersistentManager"

saveOnRestart="true" maxActiveSession="-1" minIdleSwap="0" maxIdleSwap="30"

maxIdleBackup="0">

<Store className="org.apache.catalina.session.FileStore" checkInterval="60"

directory="../session/mySession.session"/>

</Manager>

9.2.3 场景三：四招搞定动态页⾯缓存

何为动态页⾯缓存？即对.do、.jsp、.asp/.aspx、.php、.js(nodejs)等

动态页⾯进⾏缓存。可以看出，动态页⾯⼀般都会涉及动态计算、数

据库缓存、数据库等操作，所以每⼀次访问同⼀个页⾯，所获得的数

据都可能有所不同。如若应⽤对数据及时性要求较⾼，则可能不太适

合动态缓存。⽐如，对⼀个动态页⾯缓存了半个⼩时，⽤户请求访问

该动态页⾯，返回缓存中的数据，很有可能，缓存中的页⾯数据即半

个⼩时前缓存的页⾯数据状态。所以，动态页⾯缓存是典型的牺牲数

据的及时性换取性能的技术，如图9-13所⽰。具体缓存设置要多长时

间，得根据业务情况⽽定。

图9-13 访问性能与时效性的天平秤

我在云端也曾遇到很多动态页⾯缓存⽅⾯的真实案例，接下来通

过⼀个真实客户案例来详细介绍动态页⾯缓存技术。在两会期间，我

们为新华社新闻推送业务提供了运维保驾护航服务。当时遇到了⼀个

很棘⼿的问题，热点类新闻推送是⾼并发应⽤场景，如同电商的秒杀

应⽤。瞬时的热点新闻访问，⾼并发的场景给数据库缓存及数据库带

来了极⼤的压⼒。针对这种场景（采⽤Nginx+PHP部署的后端应⽤，

前端为⼿机APP客户端），我们采⽤了动态缓存技术，单机处理能⼒从

50TPS提升到5000TPS，其性能得到了⾮常⼤的提升。

第⼀招：通过Nginx内置Proxy模块实现动态页⾯缓存

图9-14 Nginx的动静态缓存

Nginx的动态页⾯缓存，主要通过HTTP反向代理（负载均衡）内

置Proxy模块的proxy_cache实现。基本上可以实现所有动态页⾯的缓

存，当然，静态页⾯也能缓存（在9.1节中已分享过通过Nginx实现静态

缓存的⽅式），架构原理如图9-14所⽰。

在图9-14中，Nginx做负载均衡反向代理，将⽤户请求转发⾄后端

服务器。我们可以在Nginx这层根据规则设置动态/静态缓存，即每次客

户请求，直接由Nginx将缓存数据返回，⽽不⽤再到后端获取响应数

据。不过，Nginx内置Proxy模板proxy_cache实现动静态缓存，缓存⽂

件是存放在磁盘⽂件中的。在⾼并发访问的场景中，磁盘I/O可能是性

能的瓶颈点。

Nginx动态缓存的核⼼配置（以缓存JSP为例）如下：

#levels设置⽬录层次

#keys_zone设置缓存名字和共享内存⼤⼩

#inactive在指定时间内没⼈访问则被删除，在这⾥是1天

#max_size最⼤缓存空间

proxy_cache_path /alidata/www/default/cache_dir/ levels=1:2

keys_zone=cache_one:200m inactive=1d max_size=30g;

server {

listen 80;

server_name _;

location /{

proxy_pass http://10.117.39.67:8080;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

location ~ .*\.jsp$

{

proxy_cache cache_one; # keys_zone后的内容对应

proxy_cache_valid 200 304 301 302 10d; #哪些状态缓存多⻓时间

proxy_cache_valid any 1d; #其他的缓存多⻓时间

proxy_cache_key $host$uri$is_args$args; #通过key来HASH，定义key的值

proxy_pass http://10.117.39.67:8080;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

access_log /alidata/nginx/logs/default-cache.log;

}

在介绍静态缓存的时候，有实现过类似的配置。其实对于Nginx⽽

⾔，动态缓存和静态缓存的配置基本⼀致。唯⼀的区别就是，静态缓

存的location配置中，正则匹配的是静态访问请求。⽽动态缓存的

location配置中，正则匹配的是动态访问请求。

实践案例1：Nginx对JSP的动态缓存

在MyEclipse中，新建⼀个test的Web项⽬，然后在默认的index.jsp

中简单输出测试⽂字、当前⽇期及⼀张图⽚。index.jsp测试代码如下：

<%@ page language="java"

import="java.util.*,java.text.SimpleDateFormat,java.text.DateFormat"

pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<title>This is test page</title>

<meta http-equiv="pragma" content="no-cache">

<meta http-equiv="cache-control" content="no-cache">

<meta http-equiv="expires" content="0">

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

<meta http-equiv="description" content="This is my page">

</head>

<body>

This is my JSP page. <br>

<img src='eg_tulip.jpg'><br>

<%

Date date = new Date();

DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); out.print("Now the time is :" + df.format(date));

%>

</body>

</html>

然后将其部署到Tomcat中，且前端⽤Nginx做反向代理。为了测试

⽅便，在后端仅部署了⼀台test Tomcat。Nginx反向代理的配置如下：

server {

listen 80;

server_name _;

location /{

proxy_pass http://10.117.39.67:8080;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

access_log /alidata/nginx/logs/default-cache.log;

}

我们可以看到，每次刷新浏览器时显⽰的时间都是不⼀样的，如

图9-15所⽰。

图9-15 访问JSP的结果

然后我们对JSP进⾏动态缓存，核⼼配置如图9-16所⽰。

图9-16 Nginx动态缓存配置

这时通过浏览器访问对应JSP的页⾯，我们就可以看到每次访问

时，页⾯显⽰的时间是⼀模⼀样的了，由此可见，Nginx的动态缓存功

能已经实现。

我们在Nginx的服务器中缓存⽬录可以看到针对刚才访问JSP的缓

存⽂件，直到缓存时间到期，Nginx将会⼀直将存放在本地缓存中的磁

盘⽂件内容，作为Response返回给客户端请求，如图9-17所⽰。

Nginx对JSP的动态缓存和Nginx对PHP的动态缓存配置基本⼀致，

唯⼀不同的是JSP动态缓存的Nginx location中匹配JSP类型即可。由于

篇幅有限，Nginx对JSP的缓存就不再详细介绍。

图9-17 JSP动态缓存结果⽂件

图9-18 PHP⾃带的FastCGI缓存模块

图9-19 PHP测试代码

第⼆招：PHP的动态页⾯缓存：fastcgi_cache

除了Nginx内置Proxy模块实现动态页⾯缓存外，PHP也可通过⾃带

的FastCGI缓存模块来实现动态页⾯缓存。实现原理及架构如图9-18所

⽰。

值得注意的是，PHP的动态页⾯缓存是通过FastCGI⾃带的缓存实

现的，⽽不需要通过Nginx反向代理来设置对应的缓存配置。FastCGI

跟proxy_cache模块⼀样，也是将缓存⽂件存放在磁盘⽂件中的。同

样，在⾼并发访问的场景中，磁盘I/O也可能是性能的瓶颈点。

实践案例2：fastcgi_cache缓存实践

PHP的测试代码（输出⽂字、⽇期及⼀张图⽚）如图9-19所⽰。

Nginx的核⼼配置如图9-20所⽰。

通过浏览器多次访问我们的test.php页⾯，这时我们发现此页⾯的

内容是不变的，如图9-21所⽰。

同时，我们在服务器中可以看到存放在磁盘中的缓存⽂件，如图9-

22所⽰。

图9-20 Nginx配置FastCGI缓存

图9-21 访问PHP的结果效果图

图9-22 PHP动态缓存结果⽂件

直到缓存到期，或者我们⼿动清理缓存⽂件，客户端才会收到最

新的数据返回，否则将返回本地缓存的数据。

第三招：通过Nginx内置Memcache模块实现动态页⾯缓存

proxy_cache和FastCGI都是将缓存存放在磁盘⽂件中的，⾼并发场

景下，磁盘I/O会成为性能瓶颈。有没有⼀种缓存技术能⽤内存缓存动

态页⾯？答案是肯定的，那就是Nginx内置的Memcached模块。Nginx

内置的Memcached模块ngx_http_memcached_module，可以很轻松地实

现对Memcached的访问，如图9-23所⽰。

图9-23 Nginx内置的Memcached模块ngx_http_memcached_module的读

写原理图

值得注意的是，Nginx直接从Memcache get获取缓存页⾯。但是需

要特别注意的是，数据的set存储是在代码中向Memcache写⼊的。

实践案例3：Nginx+Memcache缓存实践

在之前⼀家电商公司做运维的时候，我发现每次在电商做活动期

间，Memcache缓存服务器的流量每秒⾼达三四百兆字节。按照我那时

候的理解，Memcache存储热点数据（⽐如数据库访问的热点数据、业

务临时业务数据等）怎么会有这么⾼的流量？然后我通过看Nginx的配

置⽂件，发现在Nginx中配置memcached_pass，好像能对Memcache直接

进⾏读取。由于没见过这种⽤法，我带着疑惑向研发总监请教了这个

问题。原来这是Nginx⾃带的Memcache，后端把业务订单的拍照图⽚

直接存放⾄Memcache中（数据库也存放⼀份），前端能直接通过

Nginx访问Memcache中存放的图⽚信息。

所以以上案例是通过Memcache缓存了业务重要的热点静态资源，

当然，缓存动态页⾯也是可以的，可采⽤如下设置：

server {

listen 80;

server_name www.cloudcare.cn;

location ~ .*\.php$ {

set $memcached_key $request_uri;

memcached_pass host:11211;

error_page 404 502 504 = @fallback;

}

location @fallback {

proxy_pass http://backend;

}

}

这个配置会把所有请求URI后缀为php的访问，⽤Memcached模块

来读取，同时使⽤请求URI作为Memcached的key。当缓存没有命中或

者出错时，可使⽤@fallback进⾏处理。

然后，⽤简单的代码把页⾯写进Memcached⾥：

$htmlContent = file_get_contents('http://www.cloudcare.cn'); $memcached = new Memcache();

$memcached->addServer('127.0.0.1', 11211);

$memcached->set('/cache/index.php', $htmlContent); 注意写缓存时的key，由于我们访问的URL是

http://www.cloudcare.cn/cache/index.php，所以写进Memcached的key就

是URI/cache/index.php，然后我们访问

http://www.cloudcare.cn/cache/index.php时，即访问Memcache中的缓存

数据。

第四招：通过Nginx第三⽅模块实现动态页⾯缓存

Nginx内置的Memcached模块ngx_http_memcached_module，虽然实

现了对Memcached的访问。但是数据的put存储，还要需要通过代码来

操作。有没有⼀种技术，连put操作也直接通过Nginx完成了？事实上，

可以通过第三⽅模块memc-nginx和srcache-nginx构建⾼效透明的缓存机

制，如图9-24所⽰。

图9-24 Nginx第三⽅模块memc-nginx/srcache-nginx的读写原理图

直接通过Nginx对Memcache或者Redis进⾏数据的写⼊和读取时，

具体配置如下，由于是第三⽅模块，因此需要重新编译Nginx，加⼊第

三⽅模块：

./configure --prefix=/usr/local/nginx \

--add-module=../memc-nginx-module \

--add-module=../srcache-nginx-module \

Nginx的主配置如下：

#Memcache服务upstream

upstream memcache {

server localhost:11211;

}

server {

listen 80;

server_name localhost;

#memc-nginx-module

location /memc {

internal;

memc_connect_timeout 100ms;

memc_send_timeout 100ms;

memc_read_timeout 100ms;

set $memc_key $query_string;

set $memc_exptime 300;

memc_pass memcache;

}

location / {

root /var/www;

ndex index.html index.htm index.php;

}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000

#

location ~ \.php$ {

charset utf-8;

default_type text/html;

#srcache-nginx-module

set $key $uri$args;

srcache_fetch GET /memc $key;

srcache_store PUT /memc $key;

root /var/www;

fastcgi_pass 127.0.0.1:9000;

fastcgi_index index.php;

include fastcgi_params;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

}

}

其中，memc-nginxs是标准的upstream模块，“location/memc”是相

关配置。$memc_exptime表⽰缓存失效时间（单位：秒），这⾥统⼀设

为300s（5分钟）。最后我们在“location～\.php$”中⽤srcache-nginx-

module模块配置了缓存。这表⽰所有以“.php”结尾的请求结果都会被缓

存。当然这仅仅是案例，实际⽣产应⽤中具体看业务需要，也不可能

把全部动态页⾯设置成缓存的。

以上配置相当于对Nginx增加了如下逻辑：当URL请求是

以“.php”结尾的时候，⾸先到Memcache中查询有没有以“$uri$args”为

key的数据，如果有，则直接返回。否则，执⾏location的逻辑。如果返

回的HTTP状态码为200，则在输出之前以“$uri$args”为key，将输⼊结

果存⼊Memcache。

云诀窍

Nginx内置的Proxy模块的proxy_cache和Memcache模块

ngx_http_memcached_module，以及Nginx的第三⽅模块memc-nginx和

srcache-nginx这3项技术都可以应⽤在动态页⾯缓存中，同样也能应⽤

在静态页⾯缓存上。其实动静缓存的配置，后端采⽤的技术都⼀样，

具体取决于在Nginx location中匹配动态还是静态来让其缓存。

第10章 云端数据库实践

云端数据库是个⼤类，常见的有关系型和⾮关系型（NoSQL）数

据库。就拿MySQL、MongoDB等数据库来说，从数据库底层原理、

业务代码场景使⽤实践、运维架构、调优等⽅⾯⼊⼿都能单独写⼏本

书了。我曾买了⼀本⾼性能MySQL的书籍，有五百多页，内容还仅仅

是MySQL技术层⾯的。

第⼀篇从运维架构层⾯针对云端数据库选型进⾏了讲解，⽅便⼤

家参考选型数据库。⽽在本章主要从云端运维架构层来介绍数据库实

践。要说到数据库运维架构的实践，主要分为垂直分区和⽔平分区两

类。我们常见的主从架构、Sharding分⽚架构，都属于垂直分区和⽔

平分区的实践。⽽在实际应⽤中，我们⼀般是先做垂直分区，再做⽔

平分区，接下来就主要针对这两种分区的应⽤场景介绍实践技巧。

10.1 垂直拆库三⼤应⽤场景实践

在数据库领域中，垂直分区和⽔平分区是⼀种纵向、横向的架构

扩展⼿段。纵向垂直分区，针对不同的维度，应⽤场景⼤有不同。纵

向的垂直拆分，可以针对数据库的库级别拆分，也就是说把数据分别

放在不同的数据库中，然后把不同的数据库放在不同的服务器中。我

们也可以针对数据库读写操作的纵向垂直拆分，这就演变成⼤家熟知

的经典主从（读写分离）架构。在主从（读写分离）基础上加上⾼可

⽤，就是数据库的集群技术应⽤，本质上也是数据库垂直拆分的应

⽤。⽽相⽐于垂直拆分，⽔平拆分就是典型的分布式数据库应⽤，即

把⼀个表的数据划分到不同的数据库，且两个数据库的表结构⼀样，

且两个数据库同时对外提供访问。

10.1.1 场景⼀：垂直拆库的应⽤实践

在互联⽹的应⽤中，数据库很可能成为性能瓶颈。单纯的SQL优

化、数据库性能优化可能已经满⾜不了业务的增长需求，所以数据库

层⾯的垂直拆分是我们⾸先想到的架构⼿段。因为相⽐于⽔平拆分，

垂直拆分的改造要少很多。在实际业务中，⽣产环境下可能会因为业

务系统的不同，⽽有多个数据库存放在⼀台数据库中。当业务压⼒增

⼤时，我们可以根据库级别进⾏拆分，如图10-1所⽰。

图10-1 不同库拆分到不同机器上的流程

库1、库2、库3、库4、库5刚开始时都在⼀台机器的数据库实例中

跑着，库1和库2的访问压⼒相对⾼些。随着业务发展，我们会考虑把

除库1和库2以外的其他库单独拆分出来放在⼀台机器上，从⽽减少对

库1和库2的资源争抢。当压⼒进⼀步增加的时候，可以进⼀步把库2拆

分出来再放在单独的机器上运⾏。垂直拆库是在数据库扩展中改造⼯

作量最⼩的，如果业务调⽤的库和库之间没有跨库查询等依赖关系，

我们可以直接把库放在不同机器上运⾏，然后改⼀下代码连接数据库

的地址。相反，如果业务查询有跨库查询等依赖关系，业务代码受到

限制没办法进⾏扩展，则需要进⾏⼀定的代码业务改造。

既然库1这时候已经单独在⼀台机器上运⾏了，当库1的压⼒进⼀

步增加时，又该怎么拆分呢？如图10-2所⽰。

图10-2 不同表拆分到不同机器上的流程

我们可以进⼀步针对库1中的表，把不同的表拆分到不同的数据库

中，然后将不同的库放在不同的机器中运⾏。在实际业务中，业务的

功能模块之间往往没有交集，⽐如⽇志模块、⽤户权限模块、商品信

息模块等。所以这些功能模块所⽤的表之间都没有关联性，即数据库

级别的表和表之间没有关联查询等操作。事实上，不仅可以把这些没

有关联的表分别拆分放在不同的数据库中，还可以进⼀步把这些数据

库放在不同的机器中。不过这种⽅式的拆分，⼀⽅⾯要求表和表之间

没有关联关系，另⼀⽅⾯需要进⾏代码改造。

来看个例⼦，某O2O门店管理系统的应⽤，在中午业务⾼峰期

时，ECS服务器的系统性能负载就很⾼。在前端ECS服务器中的流量平

时是⼩于10Mbps的，⽽在⾼峰期时的流量为50Mbps。ECS层⾯的压⼒

主要集中在CPU消耗上，因此导致服务器负载很⾼。经研究发现瓶颈

在数据库。在Server端，每个门店都是使⽤的单独的数据库，我们发现

在RDS中有两百个左右的库，且有⼏个库的Process读写进程很多，这

⼏个库的读写压⼒⼀看就知道是⼤的业务门店了。所以此时为了解决

客户的性能瓶颈问题，我们建议把这⼏个⼤的门店的库单独拆分到其

他数据库中。这时候可能就会有⼈问，为什么不直接升级RDS的配置

来解决问题？或者⽤主从的读写分离来解决性能问题？升级配置及读

写分离也是个解决办法，但是在这个场景下不是最优⽅案。主要原因

有如下两点：

·由于有两百个库，数据库层⾯应该⽤到8核32GB的中⾼配了。当

你的业务只能升级⽤顶配的RDS才能解决时，更多的是需要业务优

化、架构优化。⾼配的配置，⼀⽅⾯成本⾼昂，另⼀⽅⾯并不能发挥

云的分布式架构优势。所以在笔者看来这是⼀种治标不治本的做法，

当然如果RDS的配置是中低配，优先选⽤升级RDS配置。中低配的配

置，问题更偏向聚焦在底层性能⽅⾯。

·主动的读写分离架构，不太适合数据库太多的实例。库太多会导

致在数据库备份还原⽅⾯⽐较⿇烦。RDS逻辑备份和物理备份都是针

对整个实例，所以想单独还原单个库不容易操作。关键是不同的库表

⽰不同的门店业务，如果某些库的读写压⼒较⼤，可能会直接影响其

他门店业务的性能。所以拆分库，需要综合利弊，多⽅位权衡，找出

最合适的做法。

10.1.2 场景⼆：主从的四种实践⽅案

垂直拆库需要把库拆分到最⼩粒度放在单独服务器上，这个时候

如若单台服务器读写压⼒很⾼，接下来要怎么样进⾏架构扩展，以满

⾜对数据库性能的诉求呢？可通过主从的读写分离架构，即将读写请

求进⾏垂直拆分，引流到不同的数据库上来解决对数据库性能的诉

求。

⽅案⼀：经典主从架构的实践

Replication主从复制，又称之为AB复制。是数据库中最为经典、

应⽤最为⼴泛的架构。从库通过实时同步复制主库，保障从库中的数

据和主库中的数据⼀致，⽐如MySQL的Replication主要通过binlog来同

步主库数据。如图10-3所⽰。

图10-3 ⼀主⼀从架构

主从复制的架构，根据应⽤场景的不同，还可以称之为读写分离

或者双机热备。读写分离，主要是指在垂直拆分库中，单个库放在单

台机器上，没办法再通过升级配置解决数据库性能问题。所以针对数

据库增删查改，我们把对数据的查找放在从库上。把数据的增删改操

作即写数据放在主库上，可见读写分离是针对数据库连接操作的垂直

拆分。

在主从复制的架构中，相⽐读写分离的场景，双机热备的应⽤也

⽐较⼴泛。在数据⽐较敏感的应⽤中，除了每天定时的冷备外，从库

主要做主库的热备库，主库宕机，从库要随时顶上。从库除了做热备

外，包括冷备的备份，也是建议放在从库上做，这样可避免在主库上

做冷备对业务访问有性能上的影响。

云诀窍

常见数据库的主从架构中最为常见的实践为：

·Oracle的Data Guard

·MySQL的Replication主从复制

·Redis的Replication主从复制

·MongoDB的Replication主从复制

即我们可以直接在ECS中搭建对应数据库的主从复制。

云端数据库的主从架构最为常见的实践如下。

·云数据库RDS：MySQL版，可以添加只读实例，⽤于读写分离。

也可以添加灾备实例，⽤于数据容灾。

·云数据库Redis版的读写分离版，也是标准的主从应⽤。

·云数据库MongoDB版的主从应⽤，可以添加副本集实例来满⾜需

求。

⽅案⼆：主从架构的三种扩展应⽤

（1）⼀主多从架构应⽤

在实践中，主从有很多扩展架构的应⽤场景。为了进⼀步分担数

据库读写压⼒，我们可以继续增加多个从库，如图10-4所⽰。

图10-4 ⼀主多从架构

⼀主多从的应⽤也是⾮常⼴泛的，多个从库可以进⼀步分担查询

的压⼒。因为在业务中，80%的数据库压⼒都来源于查询压⼒。特别

是业务中后台的⼀些分析功能，数据库查询分析会消耗很多数据库的

性能。多个从库不仅能进⼀步分担数据库查询的压⼒，数据库的热

备、冷备等也都可以放在不同从库上，这样，数据的备份就可以⾼枕

⽆忧了。

云诀窍

读写分离，从架构上来看，核⼼点是增加⼀个或者多个从库，通

过增加的从库来分担数据库的查询压⼒。在⾼并发场景下，增加多个

从库能有效解决数据库⼤量查询的压⼒，但是没办法解决数据库的写

（增删改）压⼒，这是读写分离的瓶颈点。

另外，主从复制的机制，从库会造成短期的数据不⼀致。主要是

因为最新写⼊的数据只会存储在主库中，想要在备库中读取到新数据

就必须先从主库复制过来，这会带来⼀定的延迟，造成短期的数据不

⼀致。

（2）主主架构应⽤

为了解决读写分离写（增删改）的瓶颈点，主主架构是主从架构

的扩展应⽤，如图10-5所⽰。

在⽣成环境中，为了进⼀步减少写的压⼒，有时也会采⽤主主主

的环状读写分离，如图10-6所⽰。

图10-5 双主架构

图10-6 三主环状架构

值得注意的是，不管是在主主架构中还是在主主主架构中，都存

在着两个主库对某个表同时写⼊的场景，从⽽插⼊的数据在主从同步

的时候可能出现主键冲突。为了解决此问题，在两个主库中需要⾃定

义主键⾃增规则，避免主从同步ID重复的问题，如MySQL通过

auto_increment_increment参数⾃定义⾃增偏移。

云诀窍

在⽣成应⽤中，不推荐同时在主库中写⼊。即主主实现⽆缝迁

移，不是为了均衡写压⼒。它的⽬的是⾼可⽤，⽽不是负载均衡。特

别是主主主的架构，更是不推荐在⽣产环境中应⽤。两个同时写问题

很多，三个同时写则会有主从同步等更多问题，很不靠谱。⽐如阿⾥

云经典的RDS MySQL就是主主架构，⽤DNS暴露域名URL给到客户端

连接，DNS解析到某个主库上提供给客户端进⾏读写操作。还有个主

库对客户端隐藏且不可操作，当读写的主库发⽣异常，DNS完成IP地

址切换解析。

（3）副本集架构应⽤

传统的主从架构，⼀般需要在代码配置⽂件中⼿动指定集群中的

Master。如果Master发⽣故障，⼀般都是⼈⼯介⼊修改配置⽂件，指

定新的Master。这个过程对于应⽤⼀般不是透明的，往往主从异常伴

随着应⽤重新修改配置⽂件，重启应⽤服务器等。⽽相⽐传统主从架

构，MongoDB副本集（如图10-7所⽰），集群中的任何节点都可能成

为Master节点。⼀旦Master节点发⽣故障，副本集可以⾃动投票，则

会在其余节点中选举出⼀个新的Master节点。并引导剩余节点连接到

新的Master节点，这个过程对于应⽤是透明的。⽬前MongoDB官⽅已

不推荐使⽤主从模式，取⽽代之的是副本集模式。

图10-7 MongoDB副本集架构

何为应⽤透明？来看看Java连接副本集进⾏读写分离的实践：

1）Mongo主从之间通过执⾏oplog来保证数据的同步。主从之间

的同步关系由Mongo⾃⼰的机制决定，时间⼀般在ms级别。详细时间

取决于机器之间的⽹络状况，同时，oplog不能设计得太⼩，⼀般建议

在数据库⼤⼩的10%以上。

2）为了保证主节点和从节点之间的数据⼀致性，建议使⽤Mongo

内部机制，它可保证⼀个写操作同步到所有从节点之后再返回写成

功。具体实现⽅式可以参考Mongo的getlasterror机制来实现。

3）读写分离的代码调⽤⽅式有两个步骤，⼀是设置读写分离需要

先在副本节点SECONDARY设置setSlaveOk。⼆是在程序中设置副本

节点负责读操作。

代码案例如下：

public class TestMongoDBReplSetReadSplit {

public static void main(String[] args) {

try {

List<ServerAddress> addresses = new ArrayList<ServerAddress>(); ServerAddress address1 = new ServerAddress("192.168.1.1" , 27017);

ServerAddress address2 = new ServerAddress("192.168.1.2" , 27017);

ServerAddress address3 = new ServerAddress("192.168.1.3" , 27017);

addresses.add(address1);

addresses.add(address2);

addresses.add(address3);

MongoClient client = new MongoClient(addresses);

DB db = client.getDB( "test" );

DBCollection coll = db.getCollection( "testdb" ); BasicDBObject object = new BasicDBObject();

object.append( "test2" , "testval2" );

// 读操作从副本节点读取

ReadPreference preference = ReadPreference. secondary(); DBObject dbObject = coll.findOne(object, null , preference); System. out .println(dbObject);

} catch (Exception e) {

e.printStackTrace();

}

}

}

读参数除了secondary⼀共还有五个参数：primary、

primaryPreferred、secondary、secondary-Preferred、nearest。

·primary：默认参数，只在从主节点上进⾏读取操作。

·primaryPreferred：⼤部分在从主节点上读取数据，只有主节点不

可⽤时从secondary节点读取数据。

·secondary：只在从secondary节点上进⾏读取操作，当存在问题时

secondary节点的数据会⽐primary节点的数据“旧”。

·secondaryPreferred：优先从secondary节点进⾏读取操作，

secondary节点不可⽤时从主节点读取数据。

·nearest：不管是主节点还是secondary节点，从⽹络延迟最低的节

点上读取数据。

在Java连接驱动中，Server的连接地址是⼀个集合，集中包含副本

集所有的IP地址。⽽客户端连接到副本集，不关⼼具体哪⼀台机器是

否挂掉。主服务器负责整个副本集的读写，副本集会通过oplog定期同

步数据备份。⼀旦主节点挂掉，副本节点就会选举⼀个新的主服务

器。这⼀切对于应⽤代码服务器不需要关⼼，我们也不需要因为主从

节点挂掉，⽽去修改应⽤代码的连接配置⽂件，以及重启应⽤代码服

务器。只需要通过连接副本集的参数指明是在主节点读，还是在从节

点读，其他⼀切底层会帮忙搞定。

⽅案三：主从连接的三种⽅式

主从读写分离的架构，由于可能有多主库多从库的情况，因此主

库从库可能有多个IP地址。在实际应⽤中，代码要怎么连接？主要有

以下三种⽅式。

图10-8 配置⽂件的主从调⽤

图10-9 配置管理服务的主从调⽤

（1）代码配置⽂件

⾸先来看最为常⽤的⽅式，即代码层+配置多个数据源的⽅式，

如图10-8所⽰。

在代码中，针对写的操作，配置单独数据源。⽽针对查询的操

作，也可以把不同查询的语句及类型配置到不同的数据源中。但这种

⽅式有个缺点，这也是MongoDB官⽅不推荐使⽤主从，⽽推荐使⽤副

本集的原因。即如若主从架构中有节点异常，我们需要⼿动更改代码

配置，并且⼀般情况下还需要重启应⽤服务器。

（2）集中配置管理

为了解决这种⼈⼯⼲预配置⽂件的低效率做法，可以采⽤

Zookeeper、Consul、Etcd来做配置集中管理。这便是第⼆种⽅式，即

配置集中化管理，如图10-9所⽰。

业务代码连接数据源的配置放在Zoo-keeper（或Consul/Etcd）中

来管理，通过简单⼼跳代码，⾃动Check主从的节点是否可⽤。如果

对应的节点异常，更新Zookeeper（或Consul/Etcd）中的数据源地址，

这样业务代码获取的连接地址便会是最新⽆异常的地址。

云诀窍

也可以将配置⽂件存放⾄Redis中，我们之前的电商业务系统就是

这么做的。即业务要连接哪个数据库，先去Redis中获取要连接的数据

库地址。只不过相⽐Redis，Zookeeper、Consul、Etcd是专门应⽤于服

务发现的框架。

（3）读写分离中间件

代码配置管理、集中配置管理，都是通过代码层的控制来选择对

应的主从读写分离库的。我们也可以采⽤读写分离的中间件来实现，

应⽤业务代码连接不⽤关⼼后端有哪些主库及从库，真正意义上对应

⽤是透明的，如图10-10所⽰。

图10-10 Proxy代理的主从调⽤

业务代码连接读写分离的中间件Proxy⽤来分辨是写请求还是读请

求，然后再将请求转发到后端对应的主从库来处理。相⽐于Proxy的⽅

式，在程序代码端实现读写分离会带来⼀个问题，即数据库和程序的

耦合度太⾼。如果数据库不⼩⼼宕机了，则同时意味着程序的不可

⽤。如果数据库地址发⽣改变了，那么程序代码端也要进⾏相应的修

改。引⼊读写分离中间件能很好地对程序端和数据库进⾏解耦，这样

程序端只需关注数据库中间件的地址，⽽⽆须知晓底层实际上有⼏个

数据库及如何提供服务。

云诀窍

常见的⽤于读写分离的中间件如下。

·MySQL Proxy：MySQL-Proxy是MySQL官⽅提供的中间件服务，

是⼀个处于Client端和MySQL server端之间类似代理的程序，它可以监

测、分析或改变它们的通信。它使⽤灵活，没有限制，常见的⽤途包

括：读写分离、负载平衡、故障、查询分析，查询过滤和修改等。

·MyCAT：MyCAT是MySQL中间件，能够实现读写分离，前⾝是

阿⾥⼤名⿍⿍的Cobar。由于Cobar在开源了⼀段时间后不了了之，于

是MyCAT扛起了这⾯⼤旗。

·Amoeba：Amoeba算中间件中的早期产品，后端还在使⽤JDBC

Driver，也能实现读写分离功能。

·RDS读写分离服务：阿⾥云RDS⾃带读写分离的功能服务，通过

RDS的读写分离地址，可以使写请求⾃动转发到主实例，读请求按照

设置的权重⾃动转发到各个只读实例。

⽅案四：主从的⾼可⽤架构

介绍到这⾥，相信⼤家已经对主从架构及应⽤场景⽐较熟悉了。

在前⾯的实践中，已介绍了主从架构的作⽤主要是解决查询的压⼒，

但没办法解决写的压⼒。并且从库由于要同步主库的数据，从库存在

短暂的数据不⼀致。除了这两个缺点外，主从还有第三个缺点，就是

⾼可⽤的问题。即客户端连接的主库宕机，怎么切换到从库中。其实

在主从连接的三种⽅式中，也已经给出了相应的解决办法，但是并不

推荐。⽐如，通过Zookeeper、Consul、Etcd服务发现框架，在应⽤代

码层实现故障切换，连接可⽤的主从库，从⽽满⾜⾼可⽤的需求。但

是这种⽅式需要编码，成本较⾼，并不是⾸先⽅案。另外读写分离的

中间件，主要功能偏向读写分离转发⽅⾯，在故障转移⽅⾯偏弱，也

并不是⾸选。

在云端实践中，主从的⾼可⽤架构和RDS的DNS+双主架构类似，

如图10-11所⽰。

图10-11 DNS+Consul的主从⾼可⽤架构

·主从数据库的IP地址，通过DNS暴露给客户端连接。

·DNS采⽤Dnsmasq⾃建，是⼀款轻巧的DNS⼯具，只需要通过

yum install dnsmasq这条命令即可简单搞定安装。

·Consul⽤于⼼跳检测，当主库正常，让DNS解析主库的IP地址。

当主库异常，让DNS解析从库的IP地址。

·后端不仅可以采⽤主从架构，也可以采⽤主主架构。如若采⽤主

主架构，⽐如A库异常，切换解析到另外⼀个B库。当A库恢复，B库

的数据会反向同步给A库，我们不⽤再将解析切换回A库上了。也正如

前⾯所说，主主架构主要应⽤在这种⽆缝迁移的⾼可⽤场景，并不是

为了均衡写压⼒。

传统的IDC除了采⽤DNS+Consul⽅案外，也可以采⽤主主/主从

+Keeplived的⽅式来解决主从⾼可⽤的问题。还可以采⽤部署单

MySQL，结合DRBD（Distributed Relicated Block Device分布式复制块

设备）和Keeplived的⽅式来解决数据库的⾼可⽤问题。但由于云端不

⽀持Keeplived等三层的虚拟VIP技术，所以DNS+Consul是最佳实践推

荐了。

云诀窍

传统MySQL主从的⾼可⽤架构，MHA（Master High

Availability）⽬前在MySQL⾼可⽤⽅⾯是⼀个相对成熟的解决⽅案，

是⼀套优秀的作为MySQL⾼可⽤性环境下故障切换和主从提升的⾼可

⽤软件。但由于在云端，基本上RDS云数据库默认就已经解决了数据

库⾼可⽤的问题，所以在云端实践中，很难再看到类似MHA这种传统

经典的⾼可⽤架构的应⽤了。

10.1.3 场景三：集群技术的应⽤实践

最为常见的数据库集群技术，当属于Oracle RAC和MySQL Cluster

了。Oracle RAC是成熟的商业数据库集群技术，淘宝曾基于Oracle

RAC组建了全亚洲最⼤的Oracle RAC集群。后来阿⾥去IOE架构，改⽤

MySQL了。相⽐Oracle RAC，MySQL Cluster的应⽤⾯没那么⼴泛，由

于搭建配置较复杂，成熟案例也不多，所以在⽣成环境及云端中，⼏

乎未曾看到MySQL Cluster这⽅⾯的实践案例。

数据库的集群技术，主要是解决主从架构的⾼可⽤问题，也不存

在主从延时导致从库短暂数据不⼀致的问题。⽽且需要特别强调的

是，数据库集群仅解决了主从架构的⾼可⽤问题，并没有解决主库⾯

对⾼并发写、⼤数据存储的问题。所以数据库集群技术并不是数据库

分⽚Sharding技术。Oralce RAC和MySQL Cluster的原理架构如图10-12

所⽰。

图10-12 Oracle RAC集群架构

Oracle RAC通过多个实例共享存储上的数据⽂件，客户端通过连

接多个实例地址来对集群数据库进⾏访问，所以实例的连接地址前⾯

可以放四层SLB做负载转发，保障数据库⾼可⽤。RAC降低了在实例

级别的冗余过程，但RAC不能够解决数据的安全问题。尽管有多个实

例，但是只有⼀份数据⽂件。如果数据⽂件损坏了，那么整个数据库

就损坏了。

云诀窍

Oracle RAC依赖于虚拟的IP技术，在云端由于不⽀持虚拟IP⽽导致

Oracle RAC并不能正常部署在ECS上。但在云端基于N2N VPN，我们

为客户实践了Oracle RAC。虽然底层基于VPN⽹络，稳定性和性能都

得不到保障，但这也是在云端⾸个实现Oracle RAC的成熟案例。

MySQL Cluster的数据主要保存在数据节点集群中（NDB

Cluster），每个节点的数据都是相同的，所以相⽐于Oracle RAC，它不

存在某个数据⽂件损坏，整个数据库就损坏的问题。但同时这也是

MySQL Cluster在写⽅⾯的弊端，数据要在多个NDB节点中进⾏写⼊，

导致写⼊效率和性能特别低下（曾⽤了8核16GB的五台硬件服务器搭

建MySQL Cluster集群，在写⼊性能和压⼒测试⽅⾯还不如单台

MySQL）。客户端通过连接多个SQL节点来对集群数据库进⾏访问，

同样在SQL节点连接地址前⾯可以放⼀个四层SLB做负载转发，保障数

据库⾼可⽤，如图10-13所⽰。

图10-13 MySQL Cluster集群架构

云诀窍

数据库集群技术只是能解决主从架构中⾼可⽤的问题，但是没有

解决主从架构⾯对海量数据存储的问题。⽐如TB、PB数量级数据的存

储，这时候需要采⽤分布式技术的数据库。

10.2 ⽔平拆表三⼤应⽤场景实践

⾯对TB、PB⼤数据存储及读写场景，垂直拆库、甚⾄主从读写分

离已经明显显得⼒不从⼼。⽔平拆表意味着我们可以将同⼀数据表中

的记录通过特定的算法进⾏分离，分别保存在不同的数据表中，从⽽

可以部署在不同的数据库服务器上，来应对⼤数据存储及读写的场

景。但同时⽔平拆分会带来另外⼀个问题，就是如果有join关联查

询，将会导致拆分后的表关联统计变得⾮常⿇烦。另外拆分后的分布

式架构，不可避免导致了整个架构的复杂性。虽然有像阿⾥这样技术

实⼒强⼤的公司开发了透明的中间件层（如DRDS）来屏蔽开发者的

复杂性，但还是避免不了整个架构的复杂性。常见⽔平拆表主要有三

种应⽤场景，接下来跟⼤家逐⼀介绍。

10.2.1 场景⼀：业务层⽔平分区拆表的三种⽅式

在分布式Sharding中间件及数据库Sharing技术不成熟的早期，想要

在关系型数据库的单张表中存储TB、PB级别的含量数据，⽤单台服务

器显然是不可能做到的。最为常⽤的⽅式就是在业务层⾯把存储在单

个表中的数据分区拆分存放在不同的服务器的数据表中，不过这种⽅

式对业务代码改造较⼤，⽽且分区拆分后，join等操作⾮常困难。拆分

原理架构图如图10-14所⽰。

图10-14 数据⽔平拆分原理

与垂直拆分最⼤的不同是，⽔平拆分能把⼀份数据拆分成N份放在

不同机器上，这个N份原则上是任意份。⽐如在图10-14中，1TB的数据

能拆分成为四份256GB。也可以拆分成为⼋份128GB，还可以拆分成为

⼗六份64GB，等等。⽽垂直分库分表拆分到某台机器上，某个库或者

某个表会达到拆分的最⼩粒度，此时就没办法再继续拆分下去了。⽐

如A库B库C库部署在⼀起，经过拆分将A库独⽴部署在A机器上，这时

候已经达到拆分的最⼩粒度。

现如今，随着分布式Sharding中间件及数据库Sharing技术的成熟

（拆分的原理跟上图架构图原理⼀致，在本章其他中间件、数据库的

Sharding技术的原理就不再重复介绍了），业务层⾯的⽔平分区拆表已

不推荐。常见的业务层⽔平拆表⼿段如下。

⽅式⼀：哈希算法

原理：通过<主键>%<节点数>取余（如：id%10），根据取余的不

同结果，将数据存放⾄不同分区中。架构图如图10-15所⽰。

图10-15 哈希算法进⾏数据⽔平拆分

优势：⾮常容易实现，应⽤程序找到分区，只需要进⾏简单的取

余计算即可。哈希算法在分布式缓存Memcache、Redis中也应⽤⽐较⼴

泛。当有⼤量缓存数据需要存放在多个Memcache或者Redis中时，采⽤

哈希算法是⾮常⽅便快捷的。哈希算法可以为多个分区⽐较均衡地分

配⼯作量，特别是当记录数量级较多时，各个分区更加趋近于均衡。

缺陷：不利于扩展。⽐如从10个分区扩展到20个分区，这便涉及

所有数据的重新分区等问题。这样⼀来就不得不暂停站点，重新规划

及计算了。

⽅式⼆：范围

原理：按照特定字段的范围来将数据存放⾄不同的分区中。⽐如

按照时间字段的范围进⾏分区，我们可以将Time为2019年1⽉、2019年

2⽉的数据存储在⼀个分区中，⽽将Time为2019年3⽉、2019年4⽉的数

据存储在另⼀个分区中，以此类推。这使得应⽤程序需要维护⼀个简

单的范围映射表，⽐如根据Time来计算所属分区。再⽐如也可以按照

索引字段id的范围进⾏划分，将相应id范围的数据存放在不同的分区

中。架构图如图10-16所⽰。

图10-16 范围进⾏数据⽔平拆分

优势：带来很好的扩展性，随着时间推移数据在不断增长，我们

可以创建更多的分区。

缺陷：各个分区的⼯作量会存在较⼤的差异，⽐如可能⽼数据所

在的分区压⼒相对较⼩，或者⼀些特定年⽉的热点事件及业务活动导

致所在分区的压⼒过⼤。

⽅式三：映射关系

原理：通过⼀个映射关系（如同索引的原理）来说明对应的数据

存放在哪个分区中，⽐如映射关系中，我们可以指定id为1的数据存放

⾄⼀分区中，id为2的数据存放⾄三分区中，id为3的数据存放⾄⼆分区

中等。架构图如图10-17所⽰。

优势：详细记录了每⼀个数据与存放分区的对应关系，相⽐哈希

算法的分区与范围分区，我们可以灵活地控制分区的规模，并且可以

轻松地将数据从⼀个分区迁移到另外⼀个分区。

缺陷：维护的这个映射关系就是瓶颈。不建议将映射关系存放⾄

数据库中，数据库的查询可能成为性能瓶颈。⼀般建议将映射关系存

放⾄Redis缓存中，⽅便快速查询。

实践：曾经在⽤Java开发的千万级房屋出租系统中，⽤到了映射关

系的分⽚。将房屋出租的信息拆分存储到⼗台MySQL物理数据库中。

·映射关系表存储在MySQL数据库中。

图10-17 映射关系进⾏数据⽔平拆分

·数据的增加，先确定这条数据的id对应在哪个物理数据库中，将

这个映射关系写⼊到数据库中。然后再到对应物理数据库中，存储这

条数据。

·数据的删除，先去映射关系表中查找这个id的数据在哪个物理数

据库中，然后再到对应物理数据库中删除掉这条数据。

·数据的查询，数据的查询是分⽚中最为⿇烦的，⽐如模糊查询，

查询在地铁⼆号线张家⾼科站附近的房屋出租信息。这时候我们需要

去⼗台物理数据库中查找满⾜条件的数据，最终再把⼗台物理数据库

查到的结果汇总成最终结果。如若这⾥有join等操作，查询操作将变得

更加⿇烦。

·数据的更改，先去映射关系表中查找这个id的数据在哪个物理数

据库中，然后再到对应物理数据库中更改这条数据。

由于映射关系存储在MySQL数据库中，因此是存在性能瓶颈的。

我在⾯试的时候曾被问到这⽅⾯的问题，虽然添加Memcache/Redis缓

存能很⼤改善读取压⼒，但是⾯对⾼并发场景，写⼊压⼒是个很⼤的

性能瓶颈。建议直接采⽤Redis缓存数据库来实现分布式存储映射关

系。

10.2.2 场景⼆：数据库层次⽔平分区拆表的⽅法

Oracle、MySQL等关系型数据库的⾼级特性中，都⾃带分区表的

功能，即将数据按照⼀个较粗的粒度分在不同的表中。与业务层⽔平

分区拆表不同的是，数据库⾃带的⾼级特性分区表只能把表拆分到同

台机器的同个数据库中，并不能拆分到不同机器的不同数据库中。

例如MySQL⽀持多种分区表，最常见的就是根据范围进⾏分区，

下⾯的例⼦是通过PARTITION语法将每⼀年的销售额存放在不同的分

区表⾥：

CREATE TABLE sales (

order_date DATETIME NOT NULL,

-- Other columns omitted

) ENGINE=InnoDB PARTITION BY RANGE(YEAR(order_date)) (

PARTITION p_2017 VALUES LESS THAN (2017),

PARTITION p_2018 VALUES LESS THAN (2018),

PARTITION p_2019 VALUES LESS THAN (2019),

PARTITION p_catchall VALUES LESS THAN MAXVALUE );

PARTITION分区⼦句可以使⽤各种函数。但有⼀个前提，表达式

返回的值要是⼀个确定的整数，且不能是⼀个常数。由于篇幅有限，

关于数据库⾃带的⾼级特性分区表使⽤场景及相应语法，这⾥就不过

多介绍。请参考官⽅⽂档，相信⽐本⽂介绍得更为详细全⾯。

10.2.3 场景三：四⼤成熟分布式Sharding技术⽅案

数据库分布式Sharing技术是⽔平分区拆表应⽤中最为经典最为成

熟的应⽤实践，当前主流的Sharing主要分为两⼤类。⼀类是通过分布

式Sharding中间件实现⽔平分区拆表，另⼀类即通过⾮关系型数据库

NoSQL实现⽔平分区拆表。在以下实践中介绍的四种成熟的分布式

Sharding技术，便是围绕着这两⼤分类⽽展开的。

1.DRDS Sharding技术

图10-18 DRDS原理架构

分布式关系型数据库服务（Distributed Relational Database

Service，DRDS）是阿⾥巴巴致⼒于解决单机数据库服务瓶颈问题⽽⾃

主研发推出的分布式数据库产品。DRDS的前⾝为TDDL（Taobao

Distribute Data Layer），总的来说DRDS是⼀款分布式数据库中间件，

只不过在云端将TDDL封装产品化便成为DRDS了。DRDS相⽐TDDL⽽

⾔，功能更加全⾯，是⼀款商业化产品，并且便于管理维护。

DRDS⾼度兼容MySQL协议和语法，⽀持⾃动化⽔平拆分、在线

平滑扩缩容、弹性扩展、透明读写分离，具备数据库全⽣命周期运维

管控能⼒。⽽DRDS最核⼼的功能便是分⽚Sharding技术，⽀持

RDS/MySQL的分库分表，在创建分布式数据库后，只需选择拆分键，

DRDS就可以按照拆分键⽣成拆分规则，实现将数据⽔平拆分存放⾄

RDS中，如图10-18所⽰。

客户端通过SLB直接连接DRDS，⽽不是RDS。通过DRDS将数据

拆分存放⾄后端RDS中，也通过DRDS将后端存储的数据查询汇总。虽

然DRDS⾼度兼容MySQL协议和语法，但由于分布式数据库和单机数

据库存在较⼤的架构差异，且存在SQL使⽤限制，因此使⽤DRDS将会

有⼀些功能限制。相关兼容性和SQL限制的描述如下：

·暂不⽀持⽤户⾃定义数据类型、⾃定义函数。

·暂不⽀持视图、存储过程、触发器、游标。

·暂不⽀持临时表。

·暂不⽀持BEGIN…END、LOOP…END LOOP、REPEAT…

UNTIL…END REPEAT、WHILE…DO…END WHILE等复合语句。

·暂不⽀持类似IF、WHILE等流程控制类语句。

除了SQL限制外，使⽤DRDS还有⼀个关键点，就是DRDS的拆分

键即分库/分表字段。DRDS会根据拆分键的值将数据表⽔平拆分到每

个RDS实例上的物理分库中。关于拆分键即分库/分表字段的设置规则

及实践，在本⽂中就不再增加篇幅介绍，详情请参考阿⾥云官⽹DRDS

的产品帮助⽂档。

云诀窍

正如前⾯所说，虽然有像阿⾥这样技术实⼒强⼤的公司开发了透

明的中间件层（如DRDS）来屏蔽开发者的复杂性，但是还是避免不了

整个架构的复杂性。总体来说，使⽤DRDS的门槛很⾼。我们通过总结

使⽤DRDS失败的客户案例，得出两点经验教训：

1）前期没有调研清楚业务需求究竟是什么，⽆法准确地跟进业务

诉求，从⽽进⾏分库分表。例如，很多客户需求只是单表的数据可能

会⼤点，有⼀些数据需要分析，其实这时候采⽤RDS+读写分离基本上

能满⾜绝⼤多数企业级应⽤对数据库的需求，使⽤DRDS反⽽将简单事

情复杂化了。

2）DRDS虽然⾼度兼容MySQL协议和语法，但还是存在SQL使⽤

限制。并且通过DRDS进⾏数据存储，需要进⾏拆分键即分库/分表字

段规划，这块对SQL的门槛及要求较⾼。

另外，在运维管理⽅⾯使⽤DRDS时，有⼀点是值得重点注意的，

那就是数据的备份。使⽤DRDS后，数据被拆分存放⾄后端不同的RDS

中。所以DRDS的备份仅⽀持逻辑备份，不⽀持物理备份。并且在不同

的RDS中单独备份RDS的数据是没有意义的，虽然RDS上⾯可以设置相

同的备份策略，但是RDS当前的数据和事务都不相同。不管是逻辑备

份，还是物理备份⽅式，都不能保证后端三台RDS备份数据的时间点

是⼀致的。最终如若还原RDS中的数据，可能导致DRDS对外的数据不

⼀致。这就如同8.1节中不建议在云盘中使⽤LVM的原理⼀样，LVM虚

拟化多块云磁盘，⽽底层云磁盘的快照又不是在同⼀时刻进⾏。最终

如若通过快照恢复了云盘，可能造成LVM中的数据不⼀致。

2.三种Redis Sharding技术

Redis、MongoDB、列数据库都属于⾮关系型数据库（NoSQL），

分⽚Sharding技术都是它们⾃带的经典成熟特性，这是CAP定理中

Partition Tolerance（分区容错性）的特性。在第⼀篇的数据库选型中也

详细介绍了这块明细：

“⾮关系型（NoSQL）数据库，除了实现CAP定理的AP外（也可以

称为BASE模型），也实现了CAP定理中的CP，即Consistency（⼀致

性）和Partition Tolerance（分区容错性），但对Availability（可⽤性）

⽀持不⾜。我们可以看到，不管AP还是CP，都有个P。这是因为对于

分布式存储系统⽽⾔，分区容错性（P）是基本需求。即在NoSQL数据

库中，集群分⽚（Sharding）的功能是常态。⾮关系型数据库的⽔平横

向分⽚功能（能够单纯通过增加机器解决存储扩容、⾼并发读写的性

能问题），解决了关系型数据库中的垂直纵向扩展（⽐如主从、

Cluster集群都是垂直扩展，没办法通过⼀直加机器解决性能问题）带

来的性能问题。”Redis在Sharding技术实践中，有以下三种⽅式，都曾

是云端中Redis热门的Sharding技术实践。

（1）分布式中间件Codis

Redis 3.0版本之前是不⽀持Sharding的，到3.0版本才开始⽀持分⽚

Sharding。并且早期阿⾥云官⽅的云数据库Redis并没有集群版本。所

以在早期云端，要想实现对Redis Sharding的功能，⼀般有两种⽅法：

·在业务代码层，通过类似哈希的算法，将数据存储在不同的Redis

中。

·采⽤Redis的分布式中间件Codis。

由于业务层实现分⽚，研发成本较⼤，因此并不推荐。在早期云

端Redis分⽚Sharding实践中，我们在云端ECS中跟客户搭建Codis集群

来满⾜这⽅⾯需求。那具体什么是Codis呢？Codis是豌⾖荚（刚开始⽼

是把豌⾖荚误认为是⾖瓣⽹）使⽤Go和C语⾔开发、以代理的⽅式实

现的⼀个Redis分布式Sharding集群解决⽅案，且完全兼容Twemproxy。

Twemproxy由Twitter开源，Twemproxy是⼀种代理分⽚机制。

Twemproxy和Codis都是成熟的中间件，可以⼤规模应⽤在⽣成环境

中。不过Twemproxy的应⽤有以下三点不⾜之处：

·Twemproxy本⾝存在单点，需要⽤Keeplived保障⾼可⽤。

·Twemproxy最⼤的痛点在于，没办法平滑的扩容/缩容。如果需要

增加Redis服务器，或者减少Redis服务器，对Twemproxy⽽⾔基本上都

很难操作，除⾮再新建⼀个基于Twemproxy的Redis集群。

·Twemproxy运维不友好，没有Dashboard控制⾯板来⽅便维护。

⽽Codis很好地解决了Twemproxy这⽅⾯的不⾜。Codis的体系架构

如图10-19所⽰。Codis-proxy是客户端连接的Redis代理服务，也是

Codis集群请求的⼊⼜。我们可以通过HAProxy（也可以⽤四层SLB）

为多个Codis-Proxy做负载均衡，保障连接Codis集群是⾼可⽤的状态。

图10-19 Codis体系架构

顾名思义，Codis-Config，是Codis的管理⼯具，主要⽤于管理

Redis及Proxy节点。启动Codis-Config顺便会启动Dashboard服务，我们

可以通过Web页⾯查看Codis集群的运⾏状态。

Codis-Server即Redis数据节点，Codis采⽤预先分⽚（Pre-

Sharding）机制，事先规定好了，分成1024个slot。也就是说，最多能

⽀持后端1024个Codis Server。并且Codis引⼊了Group的概念，每个

Group包括1个Redis Master及⾄少1个Redis Slave。即⼀个Codis Server对

应⼀个Codis Group。

Zookeeper的⽤途相信⼤家也都知道，主要⽤于存储Redis节点信

息、Proxy节点信息、路由（记录存在哪个slot中）等配置信息，也可以

换成Etcd来做配置管理。

下⾯来看⼀下云端Codis实践，在云端某⾦融股票分析APP的应

⽤，我们曾⽤16台ECS部署了Codis集群，架构如图10-20所⽰。

图10-20 云端Codis实践架构

配置清单如表10-1所⽰。

表10-1 Codis实践配置清单

Codis实践1：Codis-Server在主库中未开启持久化，在从库上开启

RDB备份，这样可以减少及避免主库由于备份⽽影响业务的访问。

Codis实践2：当Codis-Redis的Master异常，Codis-ha切换Slave为

Master的时候，由于Redis程序代码屏蔽了HUP信号，不⽀持在线重载

配置⽂件，再加上是线上环境，不能通过重启来加载新的配置⽂件，

所以这块通过redis-cli连接redis，然后采⽤config命令来在线修改Redis 状态，重新配置主从关系。

Codis实践3：Codis-ha不稳定，经常误报警Codis-Server服务宕机，

被迫将其Slave提升为Master。经过考量和评估，最终将Codis-ha⾼可⽤

脚本停⽌。后续主从切换维护，采⽤⼿动维护。不过在最新的Codis版

本中，Codis-ha的功能好像已经被优化改善。

Codis实践4：可以通过Codis API获取Codis集群状态，来结合监控

系统做到对Codis的7*24的监控。常见的API接⼜如下所⽰：

codis_api_proxy="http://127.0.0.1:18087/api/proxy/list"

codis_api_overview=" http://127.0.0.1:18087/api/overview"

codis_api_servergroups=" http://127.0.0.1:18087/api/server_groups"

云诀窍

在Codis集群实践中，Codis Server采⽤了8核16GB配置的ECS，在

配置选项中也向⼤家详细介绍了，由于Redis是单进程单线程模式，对

多核利⽤不太好。因此Redis适合⽤于CPU与内存资源配⽐为1∶4或1∶8

这种偏向内存型的配置，⽽8核16GB偏向计算型的在资源配置上使⽤

不合理。

（2）Redis Cluster

Redis Cluster相⽐Codis集群要简单许多，部署也更简单，架构如图

10-21所⽰。

Redis Cluster是去中⼼化的结构，它会将所有的Key映射到16384个

slot中。集群元数据信息分布在每个Redis实例节点上，业务程序通过集

成的Redis Cluster客户端进⾏操作。客户端可以向任⼀实例发出请求，

如果所需数据不在该实例中，则该实例引导客户端⾃动去对应实例读

写数据。Redis Cluster的成员管理（节点名称、IP、端⼜、状态、⾓

⾊）等，都通过节点两两之间进⾏通信，定期交换并更新。

（3）阿⾥云Redis

阿⾥云的Redis集群版体系架构如图10-22所⽰，阿⾥云的Redis集

群版由以下四⼤组件构成。

·Redis-Config：顾名思义，集群管理⼯具，双节点容灾模式。

·Redis-Server：优化过源码的Redis，即图10-22中的Master与Slave

部署的Redis，⽀持slot、扩容迁移等。

·Redis-Proxy：如同Codis-Proxy，⽤于暴露给客户端访问。阿⾥云

采⽤DNS+VIP提供给客户端访问，到对应Proxy异常，DNS⾃动切换到

可⽤的Proxy IP上。

·Rds db：⽤于存储集群的元数据（meta data），类似Zookeeper的

配置管理⾓⾊。

阿⾥云Redis在云端已产品化（云数据库Redis集群版），所以在云

端缓存实践中。如果是在⼤数据存储、读写的场景下，则要考虑到分

⽚Sharding技术。云数据库Redis集群版，⽆疑已成为最佳选择。我们

不⽤关⼼底层的架构原理，也不⽤像Codis还要进⾏复制的安装配置。

我们只需要开箱即⽤，开通Redis集群版，选择对应的规则配置即可。

图10-21 Redis Cluster原理架构

图10-22 阿⾥云Redis体系架构

3.MongoDB Sharding技术

MongoDB是⾮关系型数据库（NoSQL）中最为热门的数据库，

MongoDB的分⽚Sharding技术在云端应⽤⾮常⼴泛及常见，同时也是

在云端四⼤成熟分部署Sharding技术中最为⼴泛及常见的。本⽂将详细

介绍MongoDB Sharding技术实践。

（1）MongoDB Sharding的体系架构

MongoDB Sharding原理架构如图10-23所⽰。

图10-23 MongoDB体系架构

这图是从官⽹借鉴的，可以说是很形象和经典了，让⼈⼀眼就能

理解MongoDB的Sharding体系架构。MongoDB的Sharding体系架构主要

包括以下三个核⼼组件。

·Mongo（路由节点）：集群的请求⼊⼜，类似Codis-Proxy、Redis-

Proxy⾓⾊。主要把所有对MongoDB的数据读写请求，根据Config

Server的配置信息分配到不同的分⽚服务器上去。流量请求的⼊⼜，建

议⽤4核8GB、8核16GB的中⾼配。

·Config Server（配置节点）：存放分⽚信息、分⽚的数据与⽚的关

系，以及集群配置信息。配置节点的性能⼀般不⾼，建议使⽤2核

4GB、4核8GB的中低配。

·Shard（分⽚节点）：⼀个分⽚可以是⼀台服务器，也可以是多台

服务器组成的⼀个副本集。在实际应⽤中，很少⽤单台服务器部署⼀

个分⽚。如若这台服务器宕机，就会导致该分⽚不可⽤，甚⾄数据丢

失。所以在实际应⽤中，我们⼀般⽤副本集的模式来部署分⽚，保障

分⽚中的数据⾼可⽤。分⽚节点就是MongoDB的数据节点了，建议采

⽤8核32GB的内存型配置来部署。由于MongoDB存储引擎基于内存映

射，因此⾼内存的配置能有效提升MongoDB的性能。

（2）游戏类应⽤MongoDB分⽚性能测试

●业务概要

本实践为2014年8⽉，某知名公司在阿⾥云上进⾏游戏类业务运维

部署的案例。底层数据库采⽤MongoDB，并且⽤到了MongoDB的分⽚

Sharding技术。游戏业务初步的⽤户量为四⼗万玩家，并且同时有五六

万玩家在玩游戏，数据库吞吐量（ops/sec）初步预估需要达到五万左

右。由于当初还未推出云数据库的MongoDB版本，所以我们分别基于

普通云盘和SSD云盘，对MongoDB集群进⾏了压测，并得出最终的部

署⽅案。

●测试⼯具及环境

采⽤YCSB⼯具对MongoDB集群进⾏压测，测试环境的配置清单

如表10-2所⽰。

表10-2 MongoDB性能压测配置清单

●测试环境架构

分别部署三个Mongo节点，并且采⽤SLB负载均衡，避免Mongo的

单点故障，及提升Mongo连接效率。部署三个Config节点及三个

Shard，且每个Shard为⼀个副本集，部署架构明细如图10-24所⽰。

图10-24 MongoDB性能压测架构

●测试结果

性能测试结果如表10-3所⽰。

表10-3 MongoDB性能压测结果

●说明

·95thPercentileLatency（insert ms）表⽰95%的insert操作延时在多

少毫秒以内；

·99thPercentileLatency（insert ms）表⽰99%的insert操作延时在多

少毫秒以内。

从以上结果可以看出，MongoDB集群部署云磁盘上的性能明显不

如部署在SSD上的性能。

服务器的状态如表10-4所⽰。

表10-4 MongoDB性能压测服务器性能状态

从上⾯的内容可以看出，MongoDB为NoSQL型数据库，⾼内存、

⾼CPU虽然能够提升MongoDB的性能及效率。但作为持久化型数据

库，磁盘I/O的性能将直接影响MongoDB的性能效率。结合测试结果来

看，由于云磁盘的I/O性能低，对于性能要求较⾼的⼤规模应⽤，特别

是⽤于部署DB类型的应⽤，不推荐采⽤云磁盘部署，否则会对业务带

来严重的性能问题。

（3）游戏类应⽤MongoDB Sharding部署⽅案（SSD）

先来看⼀下部署注意点。

根据业务估算同时有四⼗万玩家在线，并且同时有五六万玩家在

玩游戏。初步估算，数据库的吞吐量（ops/sec）需要达到五万左右。

MongoDB集群的部署注意点：不要在负载饱和时才想到提⾼性能

与承接能⼒，对于MongoDB集群部署要有前瞻性。

在MongoDB集群应⽤中，请保证拥有⾜够的分⽚节点/机器来应对

未来业务增加带来的压⼒，不要到了集群负载饱和的时候才想到新增

节点来提⾼承载能⼒。MongoDB集群部署要有前瞻性，前期架构部署

需要做好。如果在业务压⼒来临的时候，我们才想到去加机器，这个

时候很可能已经来不及了。⼀⽅⾯，这个时候系统有⼀定的压⼒。另

⼀⽅⾯，新加⼊的节点机器，Mongo内部会进⾏相应的均衡迁移（此

步会导致进⼀步消耗Mongo性能），这样会进⼀步加剧系统的压⼒，

会给Mongo的稳定性及性能带来严重的后果。

下⾯再来看⼀下部署架构。

为了提⾼Mongo的⾼可⽤性及⾼性能，我们采⽤分布式的部署⽅

案，并且会避免单点故障。

·采⽤SLB来负载均衡Mongo节点，⼀⽅⾯避免Mongo单点故障，另

⼀⽅⾯也可以提升Mongo的连接并发能⼒。

·Config节点需要⾄少部署三份。

·每个Shard节点需要有⼀个副本集保障Shard数据的安全，在实际

⽣产环境中，推荐采⽤⼀主节点（Primary）、⼆从节点（Secondary）

来部署单个Shard节点，保障每个Shard节点有三份数据冗余。同时，为

了保障充分利⽤每台机器的系统资源，我们采⽤每台机器部署三个

Shard节点。

注意 此种⽅式只适合⾼性能的SSD部署⽅式，由于云磁盘的

I/O性能低，更多只适⽤于⼀主、⼀从、⼀仲裁的副本集部署Shard的⽅

式，单台机器也只能部署单个Shard节点（因为在单台ECS上没有更多

的I/O性能来部署更多的从节点及更多的Shard节点）。

依据业务场景估算，数据库的吞吐量（ops/sec）需要达到五万左

右。根据对应的测试结果来看，按照⾄少三台组成⼀个副本集，这三

台为⼀套环境，前期我们需要⾄少部署三套。明细如图10-25所⽰。

图10-25 MongoDB Sharding⽣成环境部署架构

部署配置的清单如表10-5所⽰。

表10-5 MongoDB Sharding⽣成环境部署资源清单

（4）MongoDB Sharding的实践经验

第⼀条，Mongo分布式环境不⽀持全局唯⼀性索引。

问题点：在实践中，_id的值由客户端⽣成，再向Mongo Sharding

集群中插⼊数据，能插⼊重复的_id值。为什么会这样？不管_id是客户

端⽣成的，还是Mongo⾃⼰⽣成的。Mongo应该都会对_id做唯⼀性校

验，即不允许_id重复。所以现在问题来了，那为什么客户端重复的_id

还能插⼊Mongo Sharding集群中。这可以通过以下两种⽅式来确认。

⼀是在Mongo单台实例中插⼊重复的_id：

use test

db.t1.insert({"_id":1})

db.t1.insert({"_id":1})

通过插⼊重复的_id，我们发现唯⼀性报错，如图10-26所⽰。

图10-26 单机MongoDB数据插⼊唯⼀性报错

⼆是在分布式Mongo Sharding实例中测试。

我们先对test库做分⽚，再对集合t1上的key字段做hashed分⽚。

db.runCommand({enablesharding:"test"})

db.runCommand({shardcollection:"test.t1",key:{"key":"hashed"}}) key的值作为分⽚键，是全局唯⼀的，这个是没问题的。要不然

Mongo的分布式环境就没法运转了。我们接下来做以下操作：

db.t1.insert({_id:1,key:1})

db.t1.insert({_id:1,key:2})

db.t1.insert({_id:1,key:3})

这时发现插⼊成功了，如图10-27所⽰。

图10-27 MongoDB Sharding_id重复性数据插⼊

但我们在插⼊第三条的时候，发现唯⼀性报错，如图10-28所⽰。

图10-28 MongoDB Sharding数据插⼊唯⼀性报错

结论：_id在分布式环境中不做全局唯⼀性校验，分布式环境只对

分⽚键做全局唯⼀性校验，且在分布式环境中不⽀持唯⼀性索引的建

⽴。上⾯刚插⼊两条数据时能够成功加⼊，是因为两条数据被分别插

⼊到了不同的分⽚，即不同的Mongo实例中。但第三条数据，又被重

新分配到之前两条数据的分⽚实例中，所以在单个Mongo实例中出现

_id唯⼀性校验异常。

第⼆条，数据不同步的异常。

在插⼊数据后，我们发现db.accoun.count()的值⼀直在波动，且持

续很久。在Mongo分布式环境中，当插⼊数据后，Mongo会内部均衡

（内部数据迁移）使得每个分⽚的数据量⼀致。但这个均衡时间不会

持续很久，所以这⾥均衡出现异常。

经过我们排查，发现均衡的异常是因为_id出现了重复。即Shard1

分⽚中有个_id的值跟Shard2中的某个_id值重复，导致Shard1的数据迁

移到Shard2的时候，出现唯⼀性校验错误，进⽽导致内部均衡重复性的

持续。

所以在分布式环境中为了避免_id重复，通常两种解决办法：

·_id让Mongo⾃⽣成。

·_id设置成为分⽚键。

（5）短视频类应⽤分⽚实践案例

●业务架构说明

该业务主要为短视频的PAAS平台、第三⽅短视频类业务提供接⼜

服务。平台架构如图10-29所⽰。

·业务量：当前16台左右ECS，⼆三⼗个服务左右。

·访问量：⽇PV两千万，压⼒主要集中在SDK移动终端访问。服务

器SDK的访问量不⼤，当前有两三千家企业客户，实际使⽤⼏百家左

右。

·服务端SDK：只有成⼈视频检测这块的服务⽤到了Mongo、HBase

数据库，其他转码、OpenAPI（Nginx做了访问限制）、直播历史等未

进⾏持久化。

图10-29 云端某短视频PAAS平台架构

·语⾔环境：PAAS平台⽤到了Java、Python、Go语⾔。

·Java：主要⽤于核⼼业务模块等，Web容器为Tomcat，⾮Web容器

未守护进程。

·Python：⽤到转码，底层⽤到了C模块等。

·Go：适应新接⼜，授权接⼜，主要考虑到Go的并发能⼒不错。

·数据库：主要采⽤MongoDB进⾏数据存储，由于考虑到后期业务

数据量的关系，MongoDB采⽤分⽚Sharding部署。另外HBase主要跟

Spark结合进⾏数据分析。

·离线分析：⽤到了Spark，主要分析⽇活、作息时间等。

·MQ：RabbitMQ⽤于内部通信（⾮核⼼），然后也⽤到了阿⾥的

消息队列，后期打算统⼀⽤阿⾥的消息队列。

·ELK：由于⽇志量⽐较⼤，主要存储程序的Error⽇志。

·Docker：在1/5/13编号的服务器上⾯部署了Cocker，主要为了部署

发布、扩展⽅便。Docker采⽤⼿动部署，未采⽤阿⾥云Cocker。

·缓存3-LB：上⾯部署了四个Redis实例，并做了主从，采⽤SLB做

负载均衡。此Redis版本为3.0+，⽽Codis的版本为2.0+。由于3.0+的

Redis性能更优，所以并没有统⼀都采⽤Codis，Redis⾥⾯主要存放应

⽤配置、应⽤付费信息等。数据量在800MB左右。

·缓存2-Codis：数据量⼏个G，和tag为“缓存”的服务器组成集群。

·Zookeeper：仅⽤于Spark和Codis。

·程序发布：代码库在本地，⾃⼰写的Python脚本，每次发布使⽤

Python脚本进⾏发布。

●业务配置清单

由于业务还处于前期，所以其整体配置清单都是偏向中低配，配

置清单如表10-6所⽰。

表10-6 云端某短视频PAAS平台配置清单

通过以上配置清单，我们都能侧⾯看出该系统IT架构是否合理。

结合第5章的实践，我们可以看到以上配置有三点不合理之处：

·采⽤的经典⽹络，未采⽤VPC⽹络。

·每台服务器都有公⽹IP，安全⽅⾯使⽤不合理。另外我们看到带

宽有1Mbps、2Mbps的，通过这些1Mbps、2Mbps带宽值也⼤体都能猜

到⼀般是⽤于远程SSH连接使⽤。由此配置清单，能推算出这⽅⾯云端

运维采⽤SSH直连，未采⽤堡垒机。我们也可以看到这⽅⾯的运维还⽐

较薄弱，且存在不⾜。

·未采⽤弹性IP，直接绑定的公⽹IP，公⽹使⽤的灵活性及弹性不

⾼。

●MongoDB配置清单

MongoDB的资源配置清单如表10-7所⽰。

表10-7 云端某短视频PAAS平台MongoDB配置清单

由于业务处于前期，我们采⽤中低配进⾏部署。考虑到云盘的I/O

性能实在太低，因此将普通云盘下部署的MongoDB Sharding迁移⾄⽤

SSD磁盘部署。并且考虑到MongoDB是内存型应⽤，CPU和内存资源

配⽐采⽤1∶4的2核8GB的配置。

云诀窍

由于MongoDB前期采⽤中低配，后期需要升级服务器配置。为了

保障数据的安全，我们采⽤Replset的⽅式部署单个Sharding，即⼀台

ECS上的数据⾄少冗余在两台ECS上。在升级Mongo重启单台ECS的时

候，相应Sharding会⾃动切换主备模式，并不影响整个Mongo服务的可

⽤性。值得注意的是，为了保障Mongo服务的⾼可⽤性，升级Mongo的

时候，我们需要采⽤⼀台⼀台的⽅式单独操作ECS，如若批量操作

ECS，会影响Mongo服务的可⽤性。

●MongoDB Sharding部署

部署架构如图10-30所⽰。

如上⽂的MongoDB Sharding实践中，每个Shard副本集是⼀主⼆

从。⽽本案例实践，考虑到客户服务器配置为低配，每个Shard的副本

集⽤⼀主⼀从⼀仲裁的标准副本集，减少从节点，提升性能。

●MongoDB Sharding实践经验

MongoDB Sharding集群⽅式想要应⽤好，有两个⽅⾯需要注意：

·研发层次：MongoDB是⼀个⾮关系型数据库，要想获得MongoDB

的最⼤效率及性能，需要在研发思维模式上从传统关系型数据库的设

计思维，转变到⾮关系型数据库的设计思维上。特别是在MongoDB的

Collection设计、分⽚键的设置等⽅⾯，都会直接影响着MongoDB的效

率及性能。

图10-30 云端某短视频PAAS平台MongoDB Sharding部署架构

·运维层次：MongoDB配置的选型、集群分⽚的设置、监控、优化

等，也会直接决定后期MongoDB是否以最⼤效率、性能稳定地运⾏。

（6）电商类应⽤分⽚实践案例

某电商类应⽤以MongoDB Sharding来分布式存储业务数据，与上

⽂中另外两个实践案例不同的是，该客户案例采⽤的是阿⾥云云数据

库MongoDB版。由于当前阿⾥云云数据库MongoDB版已⽀持分⽚集群

版，所以相⽐上⽂两个案例，⽆须⼿动搭建MongoDB Sharding集群

了。在MongoDB控制台，我们可以⽅便创建/减少/升降配Mongo、

Shard节点。值得注意的是，Config节点随着Mongo、Shard节点创建⽽

⾃动创建，Config节点被隐藏。部署架构及配置如图10-31所⽰。

图10-31 云端某电商云MongoDB Sharding部署架构

前端⽤了四台8核32GB的Mongo节点，两个Shard采⽤8核

16GB/500G磁盘空间。Config节点随着Mongo、Shard节点创建⽽默认创

建，配置默认为1核2GB且不可变配更改。此架构上线后，客户业务在

MongoDB端连接超时严重，MongoDB的不可⽤直接导致业务⼤⾯积宕

机。我们对此案例进⾏的复盘总结，也为云端使⽤云数据库MongoDB

版经典的失败案例。总结如下。

●容量规划严重不合理

我们看了⼀下⽣产环境，其数据量仅8GB，所以当前云上

MongoDB的架构没有必要做分⽚。⽤中低配的单机MongoDB，或者副

本集架构，性能也是绰绰有余的。⽽采⽤了四台8核32GB、2台8核

16GB，导致资源使⽤严重过剩。

●架构规划严重不合理

Mongo是路由节点，流量的⼊⼜，也可以⽤来做负载均衡。两个

Shard，前⾯居然⽤了四台Mongo。这就如同两台ECS，前⾯⽤了四台

SLB。这架构使⽤很不合理，仅有两个Shard情况下，前⾯⽤⼀个

Mongo即可。

●对Mongo的使⽤存在严重问题

Config Server为管理节点，阿⾥云Mongo集群版中此节点不对外开

放，默认配置为1核2GB。客户默认把⽣产数据全部存放在了Admin库

中，我们知道Admin库是Config节点中⽤于存放集群的配置信息的。所

以最终导致业务数据的读写全部落在了Config Server节点上，压⼒根本

没有流转后端Shard节点。⽽Config Server节点近1核2GB，导致Config

Server节点⼀下⼦就爆掉了，从⽽使得MongoDB集群不可⽤，⽽

Mongo、Shard节点⼀点压⼒都没有。

另外，数据都是存放在配置节点的Admin库中。没有设置分⽚库，

没有设置分⽚键，导致虽然开通了两台Shard，但数据会全部落到⼀台

Shard上，即实际上仅⽤上了⼀台，另外⼀台没有⽤到。

云诀窍

在如今，虽然云端对MongoDB Sharing的需求，都是⾸选云

MongoDB集群版，也很少再看见⾃建MongoDB Sharding集群。但如何

⾃建MongoDB Sharding集群及MongoDB Sharing底层的原理是什么，这

底层的技术依据是我们使⽤好云MongoDB这款产品的关键核⼼。

4.列数据库Sharding技术

HBase、Cassandra是典型的列数据库，⼀般列数据库都会跟⼤数据

存储、分析等关联。在云端已推出云数据库HBase版，当然也有阿⾥云

⾃主研发的列数据库相关产品：表格存储。⽽不管是HBase，还是

Cassandra，还是表格存储，在云端很少遇到⼤规模的应⽤。因为常规

的应⽤都是互联⽹的中⼩型应⽤，采⽤RDS基本上就已经满⾜需求

了。本节的主要内容及配图摘⾃阿⾥云官⽹产品帮助⽂档，关于基于

列存储的分⽚Sharding技术及应⽤，更多详情建议参考阿⾥云官⽹⽂

档，本⽂就不过多介绍，官⽅⽂档更为详细。

（1）HBase

HBase相信⼤家多多少少听说过，HBase是列数据库中典型的代

表，列数据也是分⽚Sharding技术的典型实践。同时，HBase也是

Google Bigtable的开源实现（Google著名的三篇⼤数据的论⽂：分别讲

述GFS、MapReduce、BigTable）。所以，HBase基本上是⼤数据领域

的典型代表，Hadoop（分布式⽂件系统）+HBase（数据库）

+Hive（数据仓库）+Spark（分布式计算框架）更是成为⼤数据的标

配。HBase的特点如图10-32所⽰。

图10-32 HBase特性

当前阿⾥云官⽅已推出云数据库HBase版，产品介绍如下：

HBase X-Pack是基于HBase及HBase⽣态构建的低成本⼀站式数据

处理平台。

HBase X-Pack⽀持HBase API（包括RestServer\ThriftServer）、关

系Phoenix SQL、时序OpenTSDB、全⽂Solr、时空GeoMesa、图

JanusGraph、分析Spark on HBase，是阿⾥云⾸个⽀持多模式的分布式

数据库，且协议100%兼容开源协议。

HBase X-Pack实现数据从处理、存储到分析全流程闭环，让客户

⽤最低成本实现⼀站式数据处理。

云数据库HBase主要的应⽤场景为⼤数据场景，HBase在整个数据

处理⼤图之间的位置如图10-33所⽰。

云HBase处于数据存储的位置，⾃带分析的功能。

数据来源的途径有：

·通过业务ECS直接写⼊到云HBase之中。

·有⼀些消息中间件⾃带push功能，可以直接写⼊到HBase之中；有

⼀些不⾏，需要拉取消息再转化处理后写⼊到HBase之中。

·通过流式系统，⽐如：SparkStreaming、Flink、Storm等流式引擎

计算写⼊到云HBase之中。

·从离线同步数据到云HBase之中，⼀般为T+1同步。

·从关系型数据库同步数据到云HBase之中，可以做到实时同步。

图10-33 云数据库HBase在⼤数据场景中的应⽤

·在机器学习场景中，直接把云HBase作为存储。

云HBase的数据的去向：

·云HBase⾃带Phoenix模块分析，⽀持百亿的毫秒级别分析。

·通过Spark等离线分析引擎。

·ECS业务端查询，如Scan⼀些数据，在客户端展⽰。

（2）列数据库和⾏数据库区别

基于列存储的列数据库和基于⾏存储的⾏数据库，有什么区别

呢？如图10-34所⽰。

图10-34 ⾏数据库和列数据库对⽐

对应列存储及⾏存储的优缺点如表10-8所⽰。

表10-8 ⾏存储和列存储对⽐

（3）表格存储

在云端，表格存储（TableStore）也是典型列存储数据库，前⾝是

OTS（Open Table Service）。表格存储（Table Store）是阿⾥云⾃研的

NoSQL多模型数据库（你可以将它类⽐为HBase），提供海量结构化数

据存储以及快速的查询和分析服务。表格存储的分布式存储和强⼤的

索引引擎能够提供PB级存储、千万TPS以及毫秒级延迟的服务能⼒。

表格存储在云端就推出了，⽽云数据库HBase版是最近⼀两年才推出的

产品服务。

与HBase不同的是，HBase和⼤数据存储、分析关联性很⾼，⽽表

格存储的场景主要偏向海量业务数据存储。⽽不管是HBase，还是表格

存储，或者是Cassandra，在云端很少遇到⼤规模的应⽤。因为常规的

应⽤都是互联⽹中⼩型应⽤，采⽤RDS基本上就已经满⾜需求了。表

格存储基于列存储的数据库的特点如下：

·⼤规模且可扩展：单表万亿条记录、PB级别数据量。

·⾼吞吐且低延时：百万级TPS、毫秒级延时。

·⾃由表结构和宽⾏：单⾏包含上千列。

·⾼可⽤服务器容灾：同城和跨区域。

·⾼度集成计算服务：ODPS、Stream SQL、EMR、Hadoop、

Hive、Spark。

·数据访问安全：RAM、VPC、https。

·全托管服务：RESTFul API和多语⾔SDK。

表格存储典型应⽤场景

·移动社交的应⽤场景：使⽤表格来存储⼈与⼈之间产⽣的⼤量社

交信息，包括聊天、评论、跟帖和点赞，表格存储的弹性资源按量付

费能够以较低的成本满⾜访问波动明显、⼤并发、低延时的需求。

·⾦融风控的应⽤场景：低延时、⾼并发，弹性资源可以让风控系

统永远⼯作在最佳状态，牢牢控制交易风险，灵活的数据结构能够让

业务模式跟随市场需求快速迭代。

·电商物流的应⽤场景：⼤量的交易订单及物流跟踪信息，使⽤表

格存储能够让使⽤者⽆须担⼼数据规模，它的弹性资源，可以从容应

对节⽇促销活动。

·云存储解决⽅案的应⽤场景：⼤量的联系⼈、短信、通话记录、

便笺等结构化信息与图⽚、视频、⽂件的元数据正好与表格存储数据

模型相对应，并且表格存储的备份机制可以保障这些数据的安全性。

·⽇志监控的应⽤场景：我们可以将应⽤程序的监控和⽇志信息写

⼊表格存储，提供在线的⽇志检索，并利⽤离线数据处理服务ODPS进

⾏监控与⽇志分析，挖掘其中的数据价值。

第11章 云端运维实践

在学习过云端选型篇、云端实践篇的技术实践内容后，相信⼤家

对云端热门技术都有了⼀定的了解。本章主要结合上云迁移、云端混

合云、云端运维架构优化这三类云端最常见的运维热门需求，并通过

真实的客户案例，向⼤家进⼀步分享云端运维架构的实践⼲货。

11.1 上云迁移的实践

上云迁移是在云端中⽐较常见的运维场景，伴随云计算的普及，

越来越多的客户都将部署在物理硬件中的运⾏的业务运维迁移到云

端。本⽂内容主要摘⾃本⼈在2017年2⽉发布在阿⾥云官⽅⽹站上的⼀

篇最佳上云实践的技术⽂章，希望相关的实践经验对⼤家在云端运维

实际迁移部署有所启发及帮助。

11.1.1 上云的诉求

客户背景：杭州某知名⽹上私⼈订制礼品购物平台2006年成⽴。

2014年12⽉的某⽇，该客户联系到我们。因为它的机房机柜于

2015年2⽉到期，所以想把资源迁移上云。客户的需求很明确，希望我

们根据平台已有的数据及特性，兼顾成本与性能，给予他们最佳的云

架构/资源⽅案。

11.1.2 前期技术调研

经过我们前期的调研，初步了解到了客户的⼀些基本情况，如下

所⽰。

·运维团队规模（4⼈）：运维1⼈、运维架构师1⼈、⽹络⼯程师1

⼈

·客户研发/测试团队规模：30⼈

·客户电信机房资源：

■3个机柜

■40台左右硬件服务器（DELL-R410为主，其中两台16核/96GB的

内存⽤于XEN虚拟化）

■200Mbps（独享）

客户IDC机房架构如图11-1所⽰。

图11-1 IDC机房架构

由图11-1可以看出传统电商的架构环境：

·由于电商环境存在⼤量商品图⽚，所以CDN是必不可少的。

·服务器端、前端采⽤Nginx+Varnish作为⼆级缓存，主要减少CDN

回源访问的压⼒。

·后端业务系统名称包括designe/kderp/search/res/seo/oc/img等⼗余

项，采⽤的开发语⾔主要为Java、PHP、Python。操作系统主要为

CentOs为主，少量Windows环境为辅。

·图⽚源⽂件等，主要通过NFS进⾏磁盘挂载共享，图⽚数据量

2T+。

·数据库缓存端主要采⽤Redis作为数据库缓存，减少数据库压⼒。

·数据库端主要为MySQL，采⽤硬件服务器上⾯部署MySQL主从。

11.1.3 三⼤运维痛点

从客户⾓度来讲，传统运维有三⼤痛点：

·虽然云的确在成本、扩展、灵活性、快捷等⽅⾯有很⼤优势。但

是，对云产品、云架构的灵活运⽤，是有⼀定技术门槛的。关于如何

利⽤云资源设计出低成本⾼性能的架构，是个经验性的技术活。

·由于客户没有7*24监控响应中⼼，往往导致出现报警情况时不能

及时联系上运维，并⽴即响应解决，运维的7*24⽆法得到保障。

·客户有4个运维⼈员，成本⾼昂也是最实质性的痛点。

通过洽谈，双⽅最终在12⽉底确定了合作意向。我们为客户提供

上云架构⽅案+上云迁移+7*24监控+7*24运维服务（我⽅运维为主，

客户运维为辅）来解决客户痛点。

11.1.4 上云迁移的挑战性

关于此客户上云迁移，我们主要遇到以下三⼤挑战：

挑战⼀：时间短。客户机房2⽉到期，⽽每年的2⽉14⽇（情⼈

节）是⼀年中的业务⾼峰期。由于商务合作的时间点确定下来时已经

到12⽉底了，所以项⽬排期⽐较紧，我们需要在1⽉中旬（仅两周）完

成项⽬的上云迁移、测试及正式上线，并预留两周作为观察过渡期。

挑战⼆：业务系统及技术环境较多。通过梳理得知，客户有⼗余

个业务系统，Nginx、Varnish、Tomcat、PHP、Python、Redis、

MySQL等技术环境较多，这些⼤⼤增加了迁移难度。

挑战三：零配置⽂档、零规范。由这个挑战点可知，客户在某些

⽅⾯是很不规范的。例如，⼀个经历了8年运维的系统，居然在运维配

置⽂档、运维⼿册⽅⾯没有建⽴⼀份⽂档，仅仅有⼏张零碎的架构

图。另外，在主机名、防⽕墙、配置⽂件规范等⽅⾯更是杂乱⽆章。

在迁移期间还遇到过⼀件不可思议的事情——客户忘记了机房交换机

密码，这给我们的迁移⼯作带来了极⼤的难度和挑战。

11.1.5 七步搞定上云迁移

2015年1⽉4⽇，作为运维负责⼈的我，和2名架构师、1名DBA、1

名⾼级运维及2名中级运维，在当天下午开车前往杭州，进⾏项⽬周期

为两周的上云迁移⼯作。

第⼀步：项⽬启动

2015年1⽉5⽇，这是来到客户公司正式开展⼯作的第⼀天。这⼀

天我们的⼯作内容主要是确定双⽅参与项⽬⼈员的职责，制订项⽬通

讯录，确定项⽬实施计划及项⽬周期（项⽬周期为12天）。

第⼆步：系统架构梳理及评估

接下来，进⼊项⽬迁移实施期间（时间节点：2016年1⽉6⽇—

2016年1⽉7⽇），⾸先我们需要对原系统进⾏评估，并且制订云上架

构。原系统评估的内容涉及系统架构、软件模块架构、业务架构、接

⼜以及调⽤依赖关系、性能评估、上云迁移⽬标等。云上架构内容涉

及上云后的系统架构、软件架构、业务架构、性能⽬标、上云难点

等。其中云上架构如图11-2所⽰。

图11-2 云上架构

云上架构与IDC架构的区别如下。

（1）加⼊SLB保障架构灵活扩展性

在前端我们加⼊了SLB负载均衡。在原IDC架构中，域名解析到不

同的Nginx+Varnish上，然后经过前端静态缓存，再转发到后端对应的

业务服务器上。加⼊SLB后，此架构变得更加灵活。即将所有域名先绑

定到SLB上，然后转到后端Nginx，通过Nginx做虚拟主机等七层更灵活

的控制。

（2）采⽤TCP层SLB保障性能

在实践中，⾯对⾼并发性能要求的场景时，我们发现HTTP层的负

载均衡，相⽐TCP层的负载均衡，在性能上⾯有很⼤差距。HTTP层负

载均衡只能达到万级别并发，⽽TCP层的负载均衡能达到⼏⼗万级，甚

⾄上百万级的并发量。所以在电商等⽹站应⽤中，对于SLB，我们优先

选择TCP层。

（3）采⽤低成本⾼效率的按量带宽

在IDC机房，200Mbps的独享电信带宽，⼀年的成本⼤概是

1Mpbs/100元/⽉×12个⽉×200=24万。⽽在云端，采⽤1Gpbs峰值的BGP

多线SLB带宽，在带宽质量上⾯提升了⼏个量级。另外，带宽费⽤采⽤

按量付费，⼤⼤降低了成本。

（4）数据库优先采⽤RDS，低成本⾼效率

在IDC硬件上采⽤MySQL主从⼿动部署并维护的模式，使得后期

的维护管理成本很⼤。即我们要监控及维护主从状态，并且在出现问

题时需要及时处理，保障业务对数据库读写的连续性。在采⽤RDS

后，这些问题都可以⾃动化解决。即对数据库主从的监控、备份、后

期维护、故障切换等，都是全⾃动。

第三步：迁移⽅案

在进⾏系统架构梳理及评估的同时，我们还对迁移⽅案进⾏了确

认（时间节点：2016年1⽉6⽇—2016年1⽉7⽇），即如何将应⽤、数

据迁移⾄云端。同时我们还确认了系统割接上线的流程及对应的时间

节点。最后，在迁移⽅案中，我们确认了客户云上资源清单（23台

ECS、2台RDS、1台SLB）及具体的服务器配置。

关于迁移⽅案，具体的实践要点内容如下。

●上云实践1：云计算的优势在于分布式

在实践中很多⽤户喜欢把单台云主机跟同等配置的传统物理服务

器相⽐较，其结果往往是⽤户抱怨云主机的性能如何的糟糕。但是传

统物理服务器，在多核⾼频CPU等⽅⾯的性能，真的可以把云主机⽐

下去吗？不⼀定。何为“云计算”，关键字在于“云”，即“分布式”是“云

计算”最⼤的优势。所以在实践中，我们不要只追求单台机器的性能，

⽽是要通过分布式的设计思想来保障业务的⾼性能。在此项⽬中，服

务器的标准配置都是4核8GB，也有⼤多数服务器采⽤2核4GB的配置。

我们通过分布式充分压榨了单台服务器的资源，从⽽最⼤限度地保障

了最终的低成本（后⾯会详细给出相关费⽤）。

在迁移⽅案中，图⽚⽂件迁移的⽅案具有⼀定的难度。⼀⽅⾯，

线下图⽚数据⽬录的数据量有2T多，⽽线上单块磁盘最多只能⽀持1T

的容量（当前官⽹单块磁盘⽀持32T）。另⼀⽅⾯，2T的图⽚主要是⼩

⽂件，数量特别多。那么，如何把这些⽂件迁移到云端呢？在上云实

践2和上云实践3中，将介绍LVM+Rsync在云端中的应⽤。

●上云实践2：LVM在磁盘管理⽅⾯的应⽤

在云端迁移⽅案中，我们购买了四块1T数据盘（每台ECS最多只

能挂四块数据盘），通过LVM逻辑卷将其虚拟成⼀块4T磁盘，这样就

在云端保障了⼤于2T存储数据量的冗余空间。

其实，官⽅是不推荐使⽤LVM的。因为阿⾥云的快照主要是针对

单块磁盘，并不能针对⼏块磁盘进⾏同时快照。⽽LVM主要是在多块

磁盘（物理卷）的基础上，抽象成为逻辑卷的。LVM的读写针对的是

逻辑卷，⽽数据则被分散存储在最底层的物理卷（磁盘）上。如果某

块磁盘数据损坏，但是想通过快照恢复这块磁盘的数据，我们是⽆法

保障LVM逻辑卷整体数据的完整性的。⽽LVM主要是能够提升磁盘

I/O，⽐如我们需要购买100GB的数据盘，若按常规配置，买⼀块

100GB的数据盘即可；⽽我们也可以购买4块25GB的数据盘，然后通过

LVM虚拟化成为⼀块100GB的磁盘。在功能性上⾯都能满⾜其需求，

但在磁盘I/O性能上⾯，LVM⾄少能将I/O性能提升20%～40%。

这⾥采⽤LVM⽅案也是特殊情况，⼀⽅⾯碍于当时磁盘空间的限

制，需要通过相应的技术⼿段，获得更⼤的磁盘空间。另⼀⽅⾯，这

时候的磁盘类型只有普通云盘，我们需要想办法提升I/O性能。最终考

量下来，我们决定优先采⽤LVM⽅案。即图⽚服务器采⽤LVM管理云

盘，同时图⽚服务器也是NFS Server，通过NFS挂载以供客户端使⽤。

但在这种情况下，图⽚服务器需要每天⾯对三百万PV的业务量，普通

云盘的I/O性能是不能达到要求的。所以前端我们采⽤CDN（电商的标

配）来减少后端静态资源请求的压⼒，并且在后端我们还部署了

Varnish做⼆次缓存，再进⼀步减少对后端静态资源的访问压⼒。所以

最终凭借普通云盘的I/O性能，满⾜⼀个三百万PV量的电商业务也算是

⼀个⾮常好的实践了。

●上云实践3：Rsync在云端的应⽤

怎样将线下数据在不停机的情况下实时地迁移到云端？Rsync是⽂

件增量同步迁移最优⽅案。只不过在此项⽬中，⼀⽅⾯数据传输要⾛

公⽹，另⼀⽅⾯数据量也较⼤。初步统计下来，完成数据增量迁移⾄

少需要⼀周多的时间。由于这⽅⾯的数据迁移时间周期较长，为了避

免影响整体迁移进度，我们需要提前开展这部分⼯作。

第四步：迁移实施

20多台云主机牵扯到Nginx、PHP、Tomcat、Redis、Varnish等环境

的部署，⽽我们需要通过⾃动化的部署⼿段来保障部署的最⼤效率。

线上23台服务器环境的部署，在半个⼩时内就可以完成（时间节点：

2016年1⽉6⽇—2016年1⽉7⽇）。

●上云实践4：域名备案要先⾏

上云的最后⼀步，是需要将域名的IP解析到SLB公⽹IP（或ECS公

⽹IP）上。但需要提前在阿⾥云上对域名进⾏备案，如果到最后域名

解析到阿⾥云上后才发现域名被拉⿊，业务访问被拒绝，这将会变得

⾮常⿇烦。因此我们需要提前通过阿⾥云进⾏域名备案，或者已经在

其他供应商进⾏备案，那么只需要将域名备案转接⼊阿⾥云即可。

●上云实践5：通过镜像提升云端部署效率

刚开始我们开通了⼀台ECS，并对这台ECS做了运维规范⽅⾯的系

统调优、安全加固等措施。然后我们又把这台ECS做成了⼀个基础镜

像，批量开通了22台同样环境的服务器，⼤⼤提升了部署效率。

●上云实践6：⾃动化运维⼯具的应⽤

关于对应软件的安装脚本，我们内部团队都统⼀存在在内部的

GitLab中。我们通过Ansible⼯具，定制对应的PlayBook，推送对应的

安装脚本到⽬标机器上。5分钟内完成了对应Java、PHP、Python等环

境的安装。

随后，我们也迎来了迁移⼯作中最难熬的时期。因为运维配置⼿

册、运维⽂档的缺失，所以在我们将应⽤代码部署到已经搭建好的环

境中后，需要对每⼀项参数、每⼀个配置仔细进⾏调试。3名运维⼈员

和客户运维⼈员及研发团队⼀起经过了⼀天⼀夜的努⼒⼯作，才完成

所有代码以及对应配置⽂件的调试。⾄此，我们完成了⼤部分的迁移

⼯作。后续的核⼼⼯作主要集中在功能测试、性能测试及上线割接

上。

第五步：迁移测试

此阶段的⼯作内容主要为功能测试、性能测试，其主要集中在客

户的测试团队（时间节点：2016年1⽉9⽇—2016年1⽉11⽇）。

第六步：上线割接

在上线割接前，我们需要做好客户及公司内部的维护通告。⽽在

正式迁移的时候，由于客户数据库较多，⽆法做到实时迁移，所以我

们采取了保守的做法，即停机迁移。迁移的最后⼀步是将域名解析⾄

阿⾥云，这点在前⾯提到过，域名是需要提前备案的（时间节点：

2016年1⽉13⽇—2016年1⽉15⽇）。

⾄此，我们是不是完成了最终的迁移呢？答案是否定的。虽然域

名已经解析到最新的IP上，⽽且当前万⽹刷新最新的解析记录的最短

时间周期为10分钟。但是由于我们⽆法把控客户端本地的DNS缓存，

即还是会有部分客户访问到⽼的站点。所以要完成最后的迁移，我们

还差⼀步上云实践7。

●上云实践7：Nginx反向代理将⽼⽤户请求引流⾄阿⾥云

由于DNS解析切换，部分⽤户由于本地DNS缓存的原因，导致请

求访问的仍旧是⽼的IDC环境，⽽出现异常错误提⽰等。所以我们需要

在IDC机房前端Nginx上做302重定向跳转，将依旧访问IDC的客户引流

到阿⾥云，这将⼤⼤提⾼⽤户的访问体验性。值得注意的是，由于

Nginx是七层负载均衡，因此需要匹配域名。这⾥Nginx的server_name

和跳转的链接配置的域名是同⼀个，所以为了确保跳转的域名解析到

阿⾥云，我们可以在Nginx所在服务器的Hosts配置中强制地将域名的解

析IP设置为阿⾥云对应的IP。

第七步：项⽬交付及后期监控运维

后续便是项⽬交付了，主要内容为⽂档的编写总结。此项⽬我们

总共汇总了30余个⽂档，主要包含系统软件架构、系统架构、迁移⽅

案、运维实施配置⽂档、运维维护⼿册、故障处理⽂档、资源清单

等。在⽂档交付后，将进⼊后续7*24⽇常监控及运维阶段，这⾥不再

过多概述。

11.1.6 上云前后的对⽐

在我⾯对的成百上千的实践中，这个客户的上云实践项⽬是“最

佳”的，是我体会最深刻的，具体对⽐如表11-1所⽰。

表11-1 IDC与云端资源配置费⽤清单

随着云计算的到来，传统IT已经向⼤数据（DT）时代变⾰。云计

算的低成本、⾼效率、灵活扩展等诸多优点，已经逐渐代替传统IDC的

IT模式。以迁云的对⽐表格中的“成本”来说，迁云前，客户有四名运维

⼈员；迁云后，客户是没有运维⼈员的。在上云的第⼀年，客户仅保

留了⼀名运维来处理⽇常琐事。到了第⼆年，客户公司将剩下的⼀名

运维⼈员也裁掉了。从某⽅⾯来讲，云时代给运维⾏业带来不⼩的冲

击，很多运维⼈员将⾯临失业。因为传统中⼩型互联⽹公司不再需要

运维⼈员来做⼀些琐事，这些问题在云平台中都能得以解决。从另⼀

⽅⾯来讲，云时代也将给我们带来新的机遇及挑战，这就要求技术⼈

员的知识要更加全⾯。这也是很多⼈说DevOps是未来之路的根本原

因！

11.2 混合云⼋⼤运维架构实践

下⾯这个案例的客户，2010年在上海成⽴，是⼀家长期专注于母

婴新零售转型，以⼤数据分析驱动销售提升（关注会员经营、导购⼈

效、商品经营）为主的⾼新技术企业，主要业务是提供咨询规划、软

件产品、实施和运营的⼀站式服务。⽬前与之合作的70多家母婴连锁

零售商遍布中国的11个省30个城市，服务近1500家门店。随着云计算

的发展及普及，它所带来的成本、管理、效率及质量上的优势，让企

业选择使⽤“云”进⾏业务部署已经成为⼀种标配。2018年3⽉，该客户

找到我们，向我们提出基于混合云迁云+云上Kuberneters的诉求。⼀⽅

⾯，客户希望借助云平台的优势提升开发效率、降低运维维护成本；

另⼀⽅⾯，由于客户的核⼼业务是基于数据分析的，所以对数据的安

全性要求很⾼，希望借助混合云结构提升数据的异地冗余灾备。最后

客户还希望在云上借助Kuberneters容器资源编排技术（在第13章中会

详细介绍），来进⼀步提升整体效率，统⼀管理线上IDC中的测试预发

环境及线上部署的业务。客户要求部署的每个服务都需要保障⾼可⽤

及业务的连续性，并且重点强调除了部署的应⽤服务通过Kuberneters

保障⾼可⽤外，其他部署的数据库类重要服务也都需要保障⾼可⽤。

在客户线下的IDC机房中，客户的主要业务部署在上海，即上海全

华机房。它主要⽤于数据库的热备，即应⽤备库、数据备库、数据备

库2（主要为MySQL的从库）、业务Mongo集群（主要存放了

MongoDB的⼀个副本）等。IDC的架构如图11-3所⽰。

图11-3 IDC架构

11.2.1 混合云实践1：基于VPC+专线构建混合云架构

⾸先，云端环境需要基于VPC，以⽅便⽹络隔离及⾼速通道打通

线下IDC的内⽹。其次，将云端资源放在上海地域，也是为了给上海地

域的IDC做专线。关于专线的接⼊，这⾥不过多的介绍，更多明细请参

考阿⾥云官⽹帮助⽂档。以下是迁移上云后的架构，如图11-4所⽰。

图11-4 混合云架构

云上上海地域的资源通过百兆专线（⾼速通道）和全华机房打

通，存放云上MySQL数据库的从库热备数据，以及云上MongoDB的副

本热备数据。迁移完成后，云上的环境为线上业务环境，IDC机房的环

境改为测试环境。这样基于VPC+专线，便将云端和线下IDC数据中⼼

内⽹打通，即构建了混合云架构。

11.2.2 混合云实践2：RDS⾃建主从同步在混合云中的实践

刚进⾏此项⼯作时，我们优先选择了DTS来实时同步线上RDS数据

库到IDC机房的从库中，但由于⽬前RDS仅⽀持InnoDB引擎和TokuDB

引擎（对MyISAM引擎和Memory引擎不⽀持），导致我们在⽤DTS做

全量迁移和增量迁移时出现⼤量报错。最终，我们只能放弃DTS，⽽

选择⾃⼰来搭建主从同步。线上RDS和IDC机房MySQL相关配置，如

表11-2所⽰。

表11-2 ⾃建MySQL主从配置清单

11.2.3 混合云实践3：MongoDB副本集在混合云中的实践

由于云上MongoDB的副本集不能和IDC机房⾃建的MongoDB组成

⼀个副本集，所以我们选择⾃建云上的MongoDB，主要是为了满⾜混

合云中数据库跨平台冗余的架构。MongoDB副本集，两个节点在云

上，还有⼀个Secondary节点在IDC机房，配置清单如表11-3所⽰。

表11-3 ⾃建MongoDB副本集配置清单

11.2.4 混合云实践4：RabbitMQ+SLB⾼可⽤实践

RabbitMQ集群主要有两种模式，⼀种是普通模式，另⼀种是镜像

模式。对于普通模式来说，集群中各节点都有相同的队列结构，但消

息只会存在于集群中的⼀个节点。⽽对于消费者来说，若消息进⼊A节

点的Queue中，当从B节点拉取时，RabbitMQ会将消息从A中取出，并

且会经过B发送给消费者；镜像模式与普通模式的不同之处是，消息实

体会主动在镜像节点间同步，⽽不是在读取数据时临时拉取。

RabbitMQ采⽤镜像模式，即两个节点数据⼀致（类似双主架构），然

后前端采⽤四层SLB作为请求⼊⼜，以保障RabbitMQ⾼可⽤。

RabbitMQ节点配置如表11-4所⽰。

表11-4 RabbitMQ⾼可⽤配置清单

11.2.5 混合云实践5：云端⾃建DNS实践

RDS⽬前仅⽀持InnoDB引擎和TokuDB引擎，但客户很多业务的

数据库表都是MyISAM的，再加上客户业务⽤的是Ruby框架，⽤云数

据库Redis版必须要求输⼊⽤户名和密码进⾏权限验证（云数据库

Memcache版本可以去除密码验证），⽽代码框架不⽀持密码验证。基

于以上两点，⽆法再采⽤阿⾥云官⽅的RDS及Redis，所以我们选择了

⾃建MySQL主从和Redis主从。但⾃建主从并没有达到⾼可⽤的要

求。由于在云端不⽀持Keeplived等虚拟VIP技术，因此我们要寻求⼀

种能替代Keeplived的⽅案。相⽐ZooKeeper，Consul作为轻量级服务注

册、服务发现，它可以通过⾃⾝的DNS Interface来为上层应⽤提供

Redis（Master）的IP，从⽽实现⾃动故障转移，并且它对客户端应⽤

代码的连接是完全透明的。

对于DNS，我们没有采⽤Bind，⽽是采⽤了DNSmasq，⼀款⼩巧

且⽅便地⽤于配置DNS和DHCP的⼯具。在云端⾃建DNS时，曾遇到

两⼤困难，排查解决了很久，总结如下。

1.更改/etc/resolv.conf，重启服务器后会被还原

我们发现/etc/resolv.conf其实是软连接到/run/resolvconf/resolv.conf 的⽂件，进⽽才确认Ubuntu下本地DNS的管理是采⽤resolvconf命令

的。这与Red Hat相⽐有很⼤区别，在Red Hat下直接编

辑/etc/resolv.conf，便可进⾏DNS Server的设置。在Ubuntu系统中，我

们可以看到/etc/resolvconf/resolv.conf.d⽬录下有base、head、tail三个配

置⽂件，最终⽤来⽣成resolv.conf配置⽂件。我们将⾃定义的DNS服务

器配置到其中：nameserver 172.16.1.1，但是发现重启服务器

后，/etc/resolv.conf还是会被还原，并在/run/resolvconf/interface/⽬录中

会多出⼀个以“eth0”命名的dns配置⽂件，即这个配置⽂件导致我们每

次重启服务器后，会重置⾃定义在/etc/resolv.conf中的配置。那么这个

run实时运⾏⽬录中的配置信息具体是怎么被⽣成的？最终我们在⽹卡

配置/etc/network/interfaces中找到如下配置：

auto eth0

iface eth0 inet dhcp

将其更改为如下内容：

auto eth0

iface eth0 inet static

address 172.16.1.3

netmask 255.255.255.0

up route add -net 0.0.0.0 netmask 0.0.0.0 gw 172.16.1.253 dev eth0

即把IP获取由DHCP改成⼿动静态配置，然后重启服务

器，/run/resolvconf/interface/中⽣成的DNS不再由DHCP获取。我们配

置在/run/resolvconf/interface/⽬录中的⾃定义DNS⽣效。

2.线下机房⽆法云上搭建DNS

通过专线，我们将线下机房和云上VPC的内⽹打通，即现在内⽹

的⽹络都是互通的。但是在云上，内⽹的ECS配置⾃建的DNS Server

可以完成解析，⽽线下配置的这个⾃建的内⽹DNS Server，⽆法解

析。DNS的配置如下：

listen-address=127.0.0.1,172.16.1.1

刚开始，我们调试了很多次，以为是混合云⽹络的问题，导致⽆

法解析。但最终我们把DNS的配置改为以下内容，即DNS添加了

0.0.0.0解析，使问题得到了解决：

listen-address=127.0.0.1,172.16.1.1,0.0.0.0

11.2.6 混合云实践6：Redis主从+Sentinel+Consul+DNSmasq⾼

可⽤实践

前⾯章节提到，由于在云端不⽀持Keeplived等虚拟VIP技术，我们

要寻求⼀种能替代Keeplived的⽅案。Redis主从

+Sentinel+Consul+DNSmasq是⼀个⾮常成熟的实践⽅案，不管是搭建

维护、还是稳定性等⽅⾯都⽐较突出，其架构如图11-5所⽰。

图11-5 Redis主从+Sentinel+Consul+DNSmasq⾼可⽤架构

以上架构中服务对应的功能明细，如表11-5所⽰，以供读者参考。

表11-5 Redis主从+Sentinel+Consul+DNSmasq架构明细

前端通过连接DNS的域名地址（如redis.service.consul）来连接

Redis，⽽Consul把Redis的主库地址暴露给DNS。⽽数据层采⽤原⽣态

Redis主从实现数据的⾼可⽤冗余，那么Redis Sentinel在这⾥的作⽤是

什么呢？Redis Sentinel有个神奇的功能，就是能⾃动将从库提升为主

库。如果⽼的主库恢复的话，Redis Sentinel会⾃动将⽼的主库变更为新

主库的从库。以前主从的管理都是⼿动切换维护，现在，Redis Sentinel

能帮我们⾃动管理Redis的主从关系，这让Redis主从维护管理变得⾮常

⾼效且便捷。其配置清单如表11-6所⽰。

表11-6 Redis⾼可⽤架构配置清单

11.2.7 混合云实践7：MySQL主从+Consul+DNSmasq⾼可⽤

实践

相⽐Redis主从+Sentinel+Consul+DNSmasq⾼可⽤，MySQL⾼可⽤

架构如图11-6所⽰。

图11-6 MySQL主从+Consul+DNSmasq⾼可⽤架构

与Redis主从不同的是，MySQL的主从关系没有类似于Redis

Sentinel的⼯具来⽀持主从切换。主要原因是MySQL主从维护复杂，

⼀般主从关系断掉，发⽣主从切换，如果只是简单切换主从关系的

话，会由于底层事务或者内存数据还未持久化磁盘，将产⽣新的主从

不同步等异常。所以⼀般新的主从关系，都需要⼿动把新的主库数据

全量到从库上，重新做主从关系。

11.2.8 混合云实践8：关于DNS的⾼可⽤

虽然通过DNS+Consul解决了Redis及MySQL的⾼可⽤问题，但我

们发现搭建的DNS本⾝就是⼀个单点。如果DNS宕机了，就意味着它

⽆法解析IP地址了，也意味着连接的Redis、MySQL将全部宕机，这就

使得DNS的⾼可⽤保障尤为重要。如果采⽤Bind搭建DNS的话，Bind

有⾃带的主从保障DNS⾼可⽤。但是若以DNSmasq做DNS，它并没有

主从对应的⽅案。不过，由于客户端/etc/resolv.conf能配置多个

nameserver的DNS Server。客户端可以根据配置的多个nameserver⾃上

⽽下的选择⼀个可⽤的DNS Server来完成本地的域名解析，这样我们

就可以配置多个⾃建的DNS Server，也就解决了⾃建DNS的⾼可⽤问

题。由于DNS+Consul的配置⽂件在前期基本上已经配置好了，因此后

期不需要再变更，所以我们可以直接在两台ECS（172.16.1.1和

172.16.1.2）上搭建配置⼀样的DNS+Consul，然后在客户

端/etc/resolv.conf中配置两条nameserver就到了，具体内容如下：

nameserver 172.16.1.1

nameserver 172.16.1.2

如若172.16.1.1宕机，客户端会⾃上⽽下发现172.16.1.1请求不通，

然后⾃动去172.16.1.2的DNS Server进⾏解析查询。

11.3 云端运维架构五⼤优化

在云端，我们有⼀家客户是做护肤品电商平台的。其⽆论在业务

规模、云端服务器台数还是云端的资源消费额都很⼤。下⾯我们来具

体看看这个客户在云端⼀年的消费额，具体如图11-7所⽰。

图11-7 阿⾥云资源⽉消费案例

该数据取⾃2017年8⽉，消费总计：￥181625.21，⼀年云上资源成

本粗略估算，总计在两百万左右。其中⼀个⽉在ECS上有将近⼗万的资

源费⽤开销，我很好奇其⽤的ECS的配置。结果我发现，客户在云端⽤

的⼤多是16核128GB的⾼配服务器。我问客户为什么要⽤这么⾼配的

服务器，是业务的需要、还是其他原因？客户的回答让我记忆犹新，

其实这也是客户的⼼声。客户说公司经常会搞⼀些活动，⾃⼰也不专

业，所以只能开⾼配的服务器来寻求保障。但这种盲⽬的开⾼配的做

法，可能会掩盖本质的问题。最终不仅会造成资源的过度浪费，还⽆

法解决痛点问题。

客户在上线新业务且做活动期间，线上业务长达两三个⼩时宕

机，这就将上述问题进⼀步升级并推上⾼潮。当时，客户将此问题同

步到我们，由我们进⾏协助定位及解决。后来我们发现底层核⼼数据

库采⽤的是阿⾥云的MongoDB分⽚集群，但是⽣产的业务数据却存放

在ConfigServer节点的默认admin库中，⽽阿⾥云的MongoDB分配集群

的ConfigServer默认配置只有1核2GB（此案例在MongoDB分⽚Sharding

技术实践中有详细介绍）。⾯对活动压⼒，MongoDB瞬间瘫痪了。定

位到问题后，我们紧急将业务数据从admin库中迁到另外⼀个业务库

上，问题得到了解决。但在当天的业务活动期间，已直接导致五千多

万经济损失。同时我们也可以看到在云端实践中存在两个引⼈深思的

问题：

·在云端有80%的企业存在计算资源和存储资源闲置及浪费的普遍

现象。云你真的会⽤吗？真的⽤好了吗？

·随着业务发展，对应的资源越来越多，如何⾼效地对云端资源进

⾏监控运维？

下⾯主要是针对此客户在云端上的业务需求，进⾏的运维架构的

改造及优化的实践总结。希望通过相应的实践案例，能让⼤家对这两

个问题有更深刻的理解。

11.3.1 优化⼀：云端配置选型

⾸先我们要考虑的是根据实际的业务请求数、存储的业务数据的

⼤⼩，来合理评估对应的配置。对于上⾯的案例，通过最近活动的峰

值及三个星期运维监控性能数据发现，线上ECS资源（44台）、

MongoDB资源（三个集群）、Redis资源（三个集群）使⽤严重不饱

和。

1.ECS配置建议

16核128GB/32核128GB的⾼配，⽇常负载仅为1～2左右。这说明

资源使⽤过剩，建议统⼀采⽤8核16GB的标配。

线上未放⼊驻云监控平台的资源清单，如测试服务器（4核

16GB）、官⽹（8核64GB），同时，资源使⽤也过剩，建议降配⾄4

核8GB。

线上⼤量8核16GB的服务器，CPU负载在1以下，⾄少可以将服务

器台数减半。

线上90%的服务器的硬盘空间使⽤率在1%～3%之间，磁盘空间使

⽤严重不饱和。建议统⼀从500GB降配⾄100GB。

2.MongoDB配置建议

除了ECS的费⽤占⽐⾼之外，MongoDB的资源使⽤费⽤也很⾼，

同样⾯临资源使⽤过剩的问题。我算了⼀下，线上3个MongoDB集

群，按量的费⽤，⼀个⼩时需要59.5元。

核⼼业务MongoDB分⽚集群，Mongos采⽤8核32GB 4台（16000

连接数），Shard采⽤8核16GB/500GB 2台。分⽚集群使⽤的性能状态

汇总如下。

·MongoDB中存储的数据量⼤⼩：8GB

·Mongos的CPU使⽤率（max）：4.84%

·Mongos Connects（max）：1000

·Shard CPU使⽤率（max）：16.71%

·Shard内存使⽤率（max）：56%

·Shard IOPS（max）：400

·Shard IOPS使⽤率（max）：5%

另外其他两个MongoDB分⽚集群，资源使⽤率低到可以忽略不

计。因此可以看出，此时没有必要使⽤MongoDB分⽚集群，⼀台8核

16GB的单机版MongoDB⾜够满⾜需求。

3.Redis配置建议

线上采⽤三个16G的集群版Redis，⽽线上Redis实际使⽤量如下。

·UserdMemory：380MB

·InFlow（max）：43.52Kbps

·OutFlow（max）：149.12

·Conncount：977

·Totalqps（max）：756

根据以上业务数据量可知，单机低配版的1G～2G⼤⼩就能满⾜

Redis的需求，其费⽤⾄少可以减少50%。

4.总结

由以上案例，我们可以看到年消费两百万的资源费⽤，⼤部分都

是浪费。通过合理优化，每年的成本预算可以控制在三⼗万到五⼗万

之间。并且通过很多类似案例我们也可以总结出以下经验，即根据业

务的实际需求，结合系统实际的性能压⼒及峰值，在云端做出合理的

配置规划。

11.3.2 优化⼆：云端⽹络架构

在业务上，客户在云端⽹络主要有三⼤需求：

·每台服务器都需要具备访问公⽹的能⼒，主要是要去请求第三⽅

的服务接⼜。

·有些服务器上的端⼜需要对外提供访问，因为原本的端⼜只对内

开放，且只允许⽐如公司的IP去访问等。

·由于机器资源较多，要实现⽣产环境和测试环境的划分及隔离。

⼀开始，客户的云端⽹络选择情况如下：

·在杭州地域，采⽤经典⽹络。测试环境、⽣产环境采⽤安全组隔

离，不同的业务放在不同的安全组。

·每台机器都开通公⽹，主要是让外部请求能访问单台机器上部署

的服务。同时也是为了让该机器上部署的业务代码，能请求访问外部

第三⽅服务接⼜。

·通过安全组规则限制，让对应的服务端⼜只暴露给公司的IP地

址，从⽽起到安全限制的作⽤。

在云端采⽤上述的⽹络结构，基本需求虽然满⾜了，但同时也带

来了更为严峻的⽹络安全问题：

·经典⽹络内⽹IP随机，没有⽹段的概念。在业务上不⽅便划分，

只能笼统地⽤安全组统⼀“⼀⼑切”。

·每台机器都开通公⽹，安全性风险⾮常⾼。

·服务器太多，在安全组上控制有些机器的端⼜服务只允许指定的

公⽹IP访问，安全配置管理烦琐。

为了解决云端⽹络带来的问题，我们不得不对⽹络规划进⾏重新

设计，具体架构如图11-8所⽰。

图11-8 云端⽹络架构

在图11-8中，我们可以看出：

·云端⽹络采⽤VPC，不同的业务放在不同的⽹段中，不同的⽹段

⽤不同的安全组隔离。架构层次清晰，⾮常⽅便管理。

·基于VPC，在⼀台绑定公⽹的ECS上通过IPTABLES设置SNAT。

后端ECS不绑定公⽹EIP（只绑定内⽹），访问公⽹第三⽅服务的接

⼜，通过这台有公⽹的ECS SNAT去实现对出公⽹请求的访问。

·同样基于VPC，通过VPN⽹关服务的IPSec链路把云端VPC内⽹和

公司内⽹VPC打通，我们不⽤再去设置繁杂的公⽹安全组规则，在公

司直接访问云端内⽹端⼜服务。如果想要访问公司以外的⽹络，可以

在公司内部，或者云端放个拨号VPN，在⾮公司办公⽹络，直接拨号

到内部⽹络。这种⽹络架构，不管是IDC还是云端，都是成熟企业的混

合云架构模式。

通过以上云端⽹络，可以基本解决在云端的⽹络及安全需求。但

是我们又遇到⼀个新的问题，即刚开始在通过VPC环境使⽤SNAT功能

的时候，是在ECS上通过IPTABLES⽅式⾃建的，因为那时候阿⾥云官

⽅还没推出NAT⽹关服务，所以这种⾃建的⽅式给我们带来了两次⽣

产事故：

·在部署SNAT的ECS上，我们同时部署了监控代理、⾃动化⼯具、

CSOS云安全运维系统。在部署⼀些运维⼯具服务的时候，我们曾重启

过这台服务器。但重启后IPTABLES的规则没有加载，导致SNAT功能

不可⽤，从⽽导致线上业务连接公⽹第三⽅服务接⼜不通，对应出现

线上业务异常。后来添加了这条IPTABLES的SNAT规则，才恢复对应

服务。

·ECS上绑定的EIP的带宽峰值仅有200Mbps，在该客户电商活动期

间，由于请求压⼒较⼤，对出⼜带宽的压⼒也变⼤，导致200Mbps的带

宽被跑满，从⽽线上业务出现访问超时、⽩屏的问题。当时我们临时

的解决⽅案是在出⼜带宽压⼒较⼤的ECS上紧急绑定EIP，让数据的返

回直接通过EIP，⽽不从SNAT出去，以减少那台ECS的SNAT压⼒，这

样故障才得到解决。

为了解决⾃建SNAT带来的两个问题，我们最终将⾃建SNAT迁移

到官⽅的NAT⽹关服务上。NAT⽹关产品，本⾝就解决了⾼可⽤的问

题。⽽NAT⽹关的带宽包（对公⽹IP资源的封装，⼀个NAT带宽包由⼀

个或多个公⽹IP组成），又解决了我们对更⾼峰值带宽的诉求。

云诀窍

将⾃建SNAT迁移到NAT⽹关服务上，其核⼼注意点就是在控制台

中删除VPC中添加的路由条⽬，使路由器不再把公⽹访问请求转发给

⾃建SNAT，⽽是转发给NAT⽹关。这个操作⽐较敏感，有可能因为配

置失误导致SNAT的功能异常，从⽽使线上服务器出⽹访问时出现异

常。所以此步操作需要提前确认测试好，最好放在业务低峰期时进⾏

操作。

11.3.3 优化三：云端负载均衡的选择

⾸先看⼀下本客户案例，负载均衡优化前的⽼架构，具体如图11-

9所⽰。

由图11-9可知，⽼的架构设计有以下⼏个问题：

·采⽤七层的SLB（⾼规格的QPS仅五万的峰值），并不适合电商

领域对SLB性能的诉求。特别是对有⼀定业务体量的电商及⾯对活动

期间，这个问题将变得更为严峻。所以从业务层次上来说，使⽤七层

是不合理的。

·当时在使⽤七层SLB的时候，SLB还不⽀持虚拟主机的功能。七

层SLB仅做流量转发到后端Node应⽤中，且只⽤于请求转发的功能，

⽽采⽤七层负载均衡，从运维架构上也是不合理的。

·请求直接转发给到后端Node应⽤，并没有在Node前⾯加个Nginx

做反向代理。在七层上没有虚拟主机、Rewrite等灵活功能，从运维灵

活性及功能性上来说也是不合理的。

·业务仅采⽤HTTP给⽤户提供服务，在业务安全⽅⾯存在很⼤的

隐患。在Web类互联⽹应⽤服务中，HTTPS是默认的选项。

结合第7章的相关经验，改造后的运维架构如图11-10所⽰。

图11-9 优化前的SLB架构

图11-10 优化后的SLB架构

针对⽼架构存在的问题，我们对新架构进⾏了调整：

·前端⽤四层SLB进⾏流量转发，不⽤担⼼⾯对活动等⾼并发的业

务场景，SLB表现出性能不⾜的问题。基本上四层SLB能抗10w～50w

的并发，常规互联⽹⾼并发场景也基本上都能应付得来。

·流量转发到ECS上，在Node前⾯加上Nginx做反向代理。这样我

们就可以控制七层的明细，七层请求的⽇志明细，以及做七层的虚拟

主机或者Rewrite等功能。

·给域名申请对应证书，我们把证书放在后端Nginx中配置管理。

不采⽤七层SLB在前端做证书集中管理，其实主要也是从性能⽅⾯考

虑，虽然采⽤四层SLB，后端每台ECS上都需要配置证书。但是Nginx

管理证书的配置也只有两⾏，然后结合Ansible⾃动化⼯具，这对运维

侧来说也是⾮常⽅便的。

·业务侧访问，我们保留HTTP的80端⼜访问。在Nginx上80端⼜上

配置Rewrite跳转规则，⾃动跳转⾄HTTPS的443端⼜上。值得注意的

是，在SLB的TCP上80和443的端⼜监听都要开启，请求转发⾄后端

Nginx的80、443端⼜上。

11.3.4 优化四：云端静态资源访问

下⾯我们来看⼀段Nginx反向代理配置：

server {

listen 80;

server_name test.qiaobangzhu.cn;

location /wx-share {

proxy_pass https://qiaobangzhu.oss-cn-hangzhou-internal.aliyuncs.com/wx-share;

}

location /tw/cvs {

proxy_pass https://qiaobangzhu.oss-cn-hangzhou-internal.aliyuncs.com/tw/cvs;

}

location / {

add_header Cache-Control max-age=300;

proxy_pass https://qiaobangzhu.oss-cn-hangzhou-internal.aliyuncs.com;

}

error_page 404 /404.html;

location = /404.html {

root /usr/share/nginx/html;

}

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root /usr/share/nginx/html;

}

}

在这个客户应⽤场景中，我们把静态资源放在OSS中，前端对静

态资源的请求通过Nginx反向代理转发给OSS。在Nginx上控制对后端

ECS的访问，也可以在Nginx上做静态缓存，以减少对后端OSS的静态

请求次数。但这种做法，在架构应⽤上是不推荐的，因为它会带来如

下⼏个问题：

·访问静态资源的流量⾛ECS的带宽流量，特别是在中⼤型的Web

应⽤中。流量⾛ECS的带宽，很可能会出现性能瓶颈。⽐如在上述

SNAT的案例中，部署SNAT的那台机器流量跑满了EIP的200Mbps带

宽。这台机器⼤部分流量，就是Nginx的反向代理请求OSS，然后数据

通过Nginx再返回给客户端。所以静态资源占⽤了⼤量的ECS带宽，后

来在活动期间，瞬间使SNAT的那台机器瘫痪了。

·Nginx是通过公⽹将请求反向代理转发给OSS的，所以在⽹络传

输上会影响速度性能。

·通过Nginx反向代理封装，不仅增加了运维管理成本，还要维护

Nginx配置⽂件等。

所以此时添加Nginx做反向代理多此⼀举。在云端实践中是不推荐

使⽤此部署⽅案的。该客户之所以选择使⽤Nginx做反向代理，主要原

因在于业务代码侧。静态资源的请求，都是通过⽬录来划分的。如若

将静态资源单独放在⼆级域名，会由于跨域等Cookie问题在代码侧没

有得到很好地解决，⽽使这个运维架构对业务访问产⽣问题。最终我

们选择在业务代码侧进⾏了优化及调整，对OSS静态资源的使⽤规范

如下（这也是使⽤OSS进⾏静态资源管理的标准使⽤⽅法）：

·业务侧使⽤单独的⼆级域名来管理静态资源，静态资源统⼀存放

⾄OSS中。

·静态资源的⼆级域名直接将CNAME绑定在OSS的URL地址上，

这样就直接跳过“使⽤Nginx做反向代理”这个冗余的步骤了。

·如果想要进⼀步提升OSS中存放的静态资源的访问速度，我们可

以⽆缝接⼊CDN。CDN的回源请求，会直接通过内⽹回源请求OSS中

的源数据。相⽐Nginx反向代理⾛公⽹请求OSS，速度和效率会提升得

更⾼。

11.3.5 优化五：云端运维管理

为了保障系统在云端更加安全、规范、⾼效的运⾏，运维侧梳理

是基础，也必不可少。

1.云端运维安全管理系统

其实云端⽹络⽅⾯的优化，已经在很⼤程度上保障了业务访问及

系统访问的安全性。但这在运维管理中还不够，我们还缺少针对SSH连

接的安全管理、审计系统，即堡垒机的安全功能。驻云的CSOS就能很

好地解决服务器在SSH连接管理这⽅⾯的安全功能问题。它可以更有针

对性地进⾏账号管理、权限管理，也可以针对数据库⽅⾯的连接管

理，对数据库的SQL访问做安全管控等。CSOS架构如图11-1所⽰。

2.运维安全加固

绑定在公⽹的ECS上，如果没有⽤安全组或者本机ECS的

IPTABLES防⽕墙做安全规则，就会存在较⼤的安全风险。所以我们需

要开启安全组规则或者防⽕墙规则来保障安全性，默认采⽤安全组来

设置端⼜服务访问安全性。

有些服务器直接采⽤ROOT⽤户连接，远程端⼜为默认的22端⼜。

有关这⽅⾯的使⽤也存在较⼤的安全隐患，在服务器连接中，都是建

议使⽤⼀个普通⽤户连接，然后需要管理员权限，再通过sudo切换⾄

ROOT。ROOT直接暴露，会存在较⾼的安全风险。并且默认的22端

⼜，也增加了被扫描及暴露漏洞的风险。

另外我们还发现⼀些进程服务也都是运⾏在ROOT⽤户下的，存在

较⾼的安全风险。⼀般默认情况下，安装的程序最好默认运⾏在普通

⽤户下。

3.运维规范

因为云端服务器资源较多，从2019年2⽉份的数据来看，在杭州地

域下的ECS资源清单就有283台，所以保证基本的运维规范，是我们做

运维⾃动化集中管理的基础，也是必要条件。下⾯⼀起看看具体有哪

些规范。

·主机名规范：统⼀采⽤《业务名》-《⽤途》-《编号》来进⾏，

⽐如prod-web-01。

·开机⾃启动规范：梳理Nginx/Node/Java服务的启动命令

⾄/etc/rc.local中，统⼀采⽤rc.local是为了⽅便了解每台服务器上运⾏的

服务进程清单。

·运维⾃动化：采⽤Ansible+Rundeck实现服务器⽇常集中化管理，

Ansible+Rundeck都是基础的⾃动化运维⼯具。运维⼈员可以直接登录

服务器通过⾃动化⼯具集中管理服务器，也可以登录DevOps平台管理

服务器。

图11-11 CSOS体系架构

第12章 云端监控实践

监控是运维的第⼀道防线，业务系统可以不做运维⾃动化，甚⾄

可以不做DevOps，但⼀定不能不做监控。监控是业务的“眼睛”，能让

对应的异常问题在第⼀时间被发现，只有这样我们才能第⼀时间去解

决问题。运维⼯作做的好不好，更多的是看监控有没有加好。本章主

要从物理机体系、云计算体系、容器体系这三⼤IT体系所对应的系统

架构演变过程，来介绍每个IT体系下对应的监控解决⽅案。本章包含

⼗⼀种监控解决⽅案，其中也包含驻云⾯对云端⼤量客户的监控需

求，它所累积的驻云监控1.0、驻云监控2.0、驻云监控3.0等最佳云端

监控实践⽅案，可以说⼏乎覆盖了当今互联⽹下最热门的监控解决⽅

案及最佳实践。

12.1 物理机体系：三⼤监控⽅案实践

物理机体系下的架构，其典型特点就是传统的IOE单机架构及以

虚拟VIP技术为主的集群⾼可⽤架构。⽽这类原始单机版的架构，相

对应的监控⽅案也⽐较简单。

12.1.1 监控⽅案⼀：Shell/Python

应⽤场景：通过Shell或者Python脚本，甚⾄Java、PHP来完成监控

需求。这个监控解决⽅案⼀般⽤于不懂运维的研发⼈员，他们⼀般没

听说过监控系统，也不知道⽤什么监控系统，所以就⽤⾃⼰擅长的开

发语⾔，来完成⽇常的监控需求。⽐如我以前做Java开发的时候，就

兼职公司的运维和服务器的监控⼯作，就是⾃⼰写了⼏个Shell脚本来

完成监控⼯作。

功能特点：主要通过脚本编码做些系统基础监控指标（CPU/内存/

⽹卡/磁盘）报警。

缺点：缺乏中间件、应⽤层监控。缺乏监控数据存储、数据查看

等监控集中化管理平台（Dashboard）。

12.1.2 监控⽅案⼆：Nagios

业务系统的监控是⼀个系统型专业的⼯程，简单的⾃定义监控脚

本，适⽤的场景⽐较少，并不能满⾜业务监控需求。在物理机体系

下，⽤得⽐较多的监控软件当属Nagios。

应⽤场景：IT基础架构监控的⾏业标准（出⾃官⽹），主要应⽤

在主机系统、交换机路由器等⽹络设备的监控上。

功能特点：Nagios主要偏向做主机系统、交换机路由器等⽹络设

备的监控。

缺点：

·Dashboard监控数据的图形展⽰效果很差。

·很多功能通过插件化来实现，对技术能⼒要求很⾼，特别对初学

者门槛较⾼。

·偏向主机层⾯监控，⽐如在Nginx、Tomcat等应⽤中间件性能⽅

⾯监控偏弱。

12.1.3 监控⽅案三：Nagios+Cacti

Cacti是⼀套基于PHP、MySQL、SNMP及RRDTool开发的⽹络流

量监测图形分析⼯具。Cacti可以单独部署使⽤⽤以监控⽹络流量，监

控数据图形界⾯展⽰效果⽐较好；也可以跟Nagios结合起来使⽤，整

合Cacti和Nagios是利⽤了Cacti的⼀个插件Nagios for Cacti（NPC），

它的原理是将Nagios的数据通过ndo2db导⼊到MySQL数据库（Cacti的

库）中，然后Cacti读取数据库信息将Nagios的结果展⽰出来。

应⽤场景：Cacti+Nagios是物理机体系阶段的最佳监控解决⽅案。

功能特点：Cacti的良好数据展⽰，弥补了Nagios监控软件的不

⾜。

缺点：

·同样对技术能⼒要求⾼，对初学者来说门槛较⾼。

·同样偏向主机层⾯监控，⽐如在Nginx、Tomcat等应⽤中间件性

能⽅⾯监控偏弱。

12.2 云计算体系：四⼤监控⽅案实践

云计算的出现及普及，也使分布式架构得到了发展。以负载均衡

为核⼼的分布式架构，不仅解决了集群架构的⾼可⽤问题，还使业务

可采⽤⽔平的⽅式得以扩展，即后端动态添加或减少服务器，满⾜业

务弹性的需求。随着互联⽹Web2.0⽹站的兴起、⼤数据和云时代的到

来以及分布式架构的普及，使分布式架构同时也⾯临着“三⾼”的问题

及挑战：

·⾼并发读写的需求。

·对海量数据的⾼效率存储和访问需求。

·⾼可扩展性和⾼可⽤性的需求。

分布式架构下的监控解决⽅案，最合适的当属Zabbix了。Zabbix

被誉为企业级开源监控解决⽅案，曾经被⼤部分企业作为开源解决⽅

案的⾸选。

12.2.1 监控⽅案四：Zabbix

应⽤场景：企业级IT监控解决⽅案（出⾃官⽹），相⽐Nagios官

⽹的介绍及特点（IT基础架构监控的⾏业标准），Zabbix被称作企业

级解决⽅案，从这⼀点就能看出来Zabbix不仅仅能做Nagios主机、⽹

络设备层⾯的监控，还能满⾜企业级其他⽅⾯的监控需求，⽐如中间

件、⽇志等。

功能特点：

·主机、⽹络、中间件、⽇志等性能监控（⾮常成熟完善）。

·详细的报表图标绘制，如Dashboard、Graphs、Screen、Map等功

能。

·⽀持⾃动发现⽹络设备和服务器，⽀持分布式集中管理、管理监

控点。

·完善详细的API，⽀持企业级定制化开发。这个功能⾮常重要，

企业可以通过API把Zabbix集成在其他运维⾃动化平台中，或者基于

Zabbix⼆次定制化开发适合公司业务的监控系统。

缺点：

·Zabbix的分布式体现在监控节点上，即客户端（Agent）监控数据

的收集，Zabbix有Proxy模式，能满⾜⼤多数企业跨地域、跨内外⽹等

⽹络结构下的监控需求。但是Server端的数据存储⽤的是以MySQL为

主的关系型数据库，Server端存在很严重的性能问题。

·需要在监控的⽬标主机中安装Agent，这样将会存在安全隐患。

·对容器监控⽀持不太好。

12.2.2 监控⽅案五：云监控

云监控（CloudMonitor）是⼀项针对阿⾥云资源和互联⽹应⽤进⾏

监控的服务。随着云平台功能的逐步完善及成熟，云平台中⾃带的云

监控也逐渐⽇益完善及成熟。当前云监控不仅能完成针对云平台层⾯

的云产品服务监控，也能完成主机层⾯、中间件层⾯等的定制化监

控。产品架构图如图12-1所⽰。

在未来，云监控会成为监控的主要趋势。因为云平台会把常见的

开源环境，⽐如Web、缓存、数据库等都进⾏封装并产品化。运维⼈员

不需要再去安装部署这些开源类中间件，只需要开通对应产品服务，

如⼀键式配置、管理、维护等，所以我们不需要再⾃建Zabbix等监控需

求。⼀般情况下，云监控⼀键式的监控设置，能满⾜80%互联⽹企业的

监控需求。常见热门云产品的报警规则设置实践如表12-1所⽰。

图12-1 阿⾥云云监控产品架构图

表12-1 常见热门云产品的报警规则设置实践

应⽤场景：针对云平台层⾯的云产品服务监控，也是未来的监控

趋势。

功能特点：

·Dashboard：提供⾃定义查看监控数据的功能，可以在⼀张监控⼤

盘中跨产品、跨实例查看监控数据，将相同业务的不同产品实例进⾏

集中展现。

·应⽤分组：提供跨云产品、跨地域的云产品资源分组管理功能，

⽀持从业务⾓度集中管理业务线涉及的服务器、数据库、负载均衡、

存储等资源。

·主机监控：在服务器上安装插件（Agent），提供CPU、内存、磁

盘、⽹络等三⼗余种监控项。

·⾃定义监控：可以针对⾃⼰关⼼的业务指标进⾏⾃定义监控，将

采集到的监控数据通过API上报⾄云监控来完成⾃定义监控报警。

·站点监控：通过遍布全国的互联⽹终端节点，发送模拟真实⽤户

访问的探测请求，监控全国各省市运营商⽹络终端⽤户到服务站点的

访问情况。

·云服务监控：提供查询⽤户购买的云服务实例各项性能指标情

况。

·⽇志监控：提供对⽇志数据的实时分析，⽐如对⽇志关键字统

计，进⾏监控及报警等。

·事件监控：提供云产品服务各类异常事件的报警功能，也⽀持⾃

定义事件类型数据的上报、查询、报警功能。

缺点：

·主机⽅⾯的监控项仅有三⼗余种，这些监控项虽然能覆盖常见需

求，但监控项粒度和⼴度的可选择空间还⽆法满⾜需求。

·开源中间件之类的监控，需要通过⾃定义监控调⽤云API来完成，

有⼀定的研发要求，监控门槛较⾼。

·云监控作为⼀个产品化服务，做了很多功能封装，所以我们才能

⼀键式⽅便快捷地使⽤。但同时也由于产品功能的封装，导致整体在

监控细粒度、深⼊度、灵活度等⽅⾯不⾜。⽐如在监控数据采集时间

周期、监控数据存储时间、监控数据可查看历史数据等⽅⾯都有限

制，相关明细会在后⽂与Zabbix及Prometheus的对⽐中详细介绍。

12.2.3 监控⽅案六：驻云监控1.0（集群监控）

在云端的监控实践中，我们会⾯对各种各样的云端客户的业务需

求。对于云端的监控技术体系的选择，应主要考虑其灵活性及可定制

化，这⾥我们选择了主要以Zabbix为核⼼的监控技术体系。

驻云监控1.0技术体系架构图如图12-2所⽰。

针对图12-2的说明如下：

·7*24秒级预警：监控数据收集可以设置秒级别。

·1个监控室：7*24值班⼈员来进⾏报警通知、问题升级及调度。

图12-2 驻云监控1.0技术体系架构图

·2个监控中⼼：在杭州地域、北京地域分别部署Zabbix Server，⽤

来运维监控不同的云端客户。

·4种通知⽅式：通过⼈⼯钉钉、⾃动短信、⾃动邮件、⼈⼯电话等

来进⾏报警信息通知。

·100余项监控节点：站点的HTTP URL监控，由于Zabbix在站点监

控⽅⾯功能较弱，所以我们采⽤监控宝监控产品来协助完成。

·200余项监控模板：千家云端客户实践案例、万台云端主机试验经

验，累积⼤量针对系统OS、中间件、数据库等监控模板。

我们之所以把1.0监控称之为集群监控，主要也是考虑到Zabbix的

扩展性问题。虽然Zabbix Agent及Proxy能做到客户端的分布式监控，

但是在Zabbix Server中，Zabbix Server的服务及监控数据都存储在关系

数据库（如MySQL、PostgreSQL）中，⽆法做到分布式的⽔平扩展。

⼀个Zabbix Server⾯对上万的主机、TB及PB含量的数据，将会变得⾮

常⼒不从⼼。所以很多⼈把Zabbix看成分布式监控，其实严格意义上来

说是不准确的，Zabbix Server端的性能瓶颈才是Zabbix真正的瓶颈。所

以我们才把驻云监控1.0称为集群监控，在“绪⾔”中也跟⼤家介绍过，

集群架构技术和分布式架构技术的区别，即集群的核⼼是保障⾼可

⽤，⽽分布式不仅能保障⾼可⽤，还能进⾏⽔平式性能扩展。

那么，基于Zabbix的1.0监控体系，和传统互联⽹公司⾃⼰搭建的

Zabbix具体有哪些区别？其汇总如图12-3所⽰。

图12-3 客户⾃建监控与驻云监控1.0对⽐

针对传统Zabbix监控，驻云监控1.0做了以下三⼤实践。

实践1：监控模板优化

Zabbix常规模板中有很多监控项，但对应模板的Item监控项是不是

每个都需要，以及对应Item监控项的报警阈值要设置为多少才合适？这

都影响着监控报警的覆盖⾯及报警的准确性。如果设置不准确会导致

出现很多问题，如报警不能及时被发现，以及误报警信息过多，出现

的“报警洪⽔”等问题。

⼀般Zabbix常规模板的报警项设置为：

·CPU load>5。

·磁盘空间>80%。

·数据库连接数>80%。

以上默认的模板设置，会导致存在如下报警问题：

·CPU利⽤率100%，但CPU load未上去，导致报警最后未发出来。

·当CPU只有1核或CPU有16核的时候，针对服务器配置偏低或偏⾼

的这种情况，单纯设置CPU load>5的阈值，可能导致存在阈值设置偏

⾼或偏低等问题。

·当磁盘空间为500GB的时候，如若设置磁盘空间>80%为报警阈

值，但这时磁盘空间还有100GB，那么此时这个报警意义并不⼤。

·如Mongo集群8核32GB，最⼤连接数是16000。若设置数据库连接

数>80%为报警阈值，我们会发现，数据库连接数要达到12800才报

警，⽽实际情况往往是很难达到这个阈值的，所以报警⼏乎根本不会

被触发。

·阿⾥云短信信息太多，可能会因为粗⼼，导致漏掉“资源到期续

费”等重要短信信息？

Zabbix优化如下：

·CPU load>‘cpu核数’&& CPU利⽤率>90%。

·磁盘空间>90%&&磁盘空间≤5GB。

·Zabbix针对阿⾥云的资源过期监控（通过调⽤API Python

SDK）。

我们通过“and”联合多个监控报警项，很⼤程度地提⾼了报警的准

确性。在设置具体的阈值时，我们还需要采集：

·服务器配置。

·中间件配置。

·⽇常性能情况。

·⾼峰性能情况。

·业务类型及特性。

另外我们需要根据不同的业务特点以及不同业务下服务器配置的

不同，采取不同的报警阈值策略。我们在Zabbix上把这些不同的策略规

则汇聚成为对应的监控模板：

·<⾦融类>Zabbix监控⽅案。

·<电商类>Zabbix监控⽅案。

·<游戏类>Zabbix监控⽅案。

·<⾳视频类>Zabbix监控⽅案。

·<传统类>Zabbix监控⽅案。

·<跨国际应⽤类>Zabbix监控⽅案。

实践2：监控集中化Screen图

Zabbix中的Graphs图是针对某个主机中某个监控项的单个图，如果

想同时查看不同主机上的监控数据，可以通过Zabbix Screen图来集中展

现，如图12-4所⽰。

实践3：可视化系统监控架构图（Maps）

Zabbix的Maps可以通过架构图的形式来展现监控数据，图中连线

数据都是实时动态数据。如若连线数据对应的监控项设置了报警，那

么在出现报警信息的时候，对应图中的状态就会变成红⾊异常状态。

通过架构图的形式来展现系统监控状态，受到客户的⼀致好评，很多

客户都表⽰这种直观的表⽰⽅式的体验性⾮常好，具体如图12-5所⽰。

图12-4 Zabbix Screen图

图12-5 Zabbix Maps监控架构图

12.2.4 监控⽅案七：驻云监控2.0（⾃动化监控）

驻云监控1.0体系的特点，就是围绕监控室的⼀套7*24监控报警流

程。但在这个流程中，监控室和值班⼈员同时存在，会出现管理成本

和⼈员成本叠加的问题，可见，这套监控体系并不够智能⾼效。⽽结

合Zabbix的API，驻云监控2.0的⾃动化监控，主要是基于驻云监控1.0

的集群监控，它对监控报警通知做了很⼤改良。在以前的报警通知

⾥，通知信息泛滥、误报率较⾼，⽽且还要有个7*24的值班室，由监

控⼈员进⾏7*24电话通知，⼈员成本⾼，通知效率⾮常低。⽽在驻云

监控2.0的版本中，我们通过⾃主研发阿尔法智能告警机器⼈，把报警

信息汇聚⾄报警平台，然后做智能分析，并对报警信息进⾏合并、优

化、分析，从⽽将最终的结果通过⾃动电话/钉钉/邮件/短信等⽅式通知

到运维。在这个阶段，我们实现了监控的⾃动化，7*24监控⼈员值班

的制度可以直接废除。这样，不仅降低了⼈⼒成本，效率质量也得到

了很⼤提升。整体报警⾃动化的分析流程如图12-6所⽰。

图12-6 驻云监控2.0⾃动化分析流程

驻云阿尔法智能告警机器⼈的效果展⽰如图12-7所⽰。

图12-7 智能告警机器⼈钉钉群中的告警信息

整体的驻云监控2.0技术体系架构如图12-8所⽰。

图12-8 驻云监控2.0技术体系架构

驻云监控2.0体系与1.0体系的主要不同之处在于：

·监控报警通过智能机器⼈来⾃动电话调度（如果问题未解决，⾃

动升级发给第⼆/第三/第四联系⼈）。

·新增的深圳监控中⼼，采⽤最新Zabbix 4.0，并且完全实现监控⾃

动化，即Agent添加、端⼜监控，都是通过Zabbix的⾃动发现及⾃动注

册功能，⾃动化添加到Zabbix Server上进⾏监控的，⽆须⼈为地去

Dashboard页⾯进⾏配置。

·站点监控从监控宝迁移⾄阿⾥云（云平台成本费⽤更低，管理维

护更加⽅便），传统的类似监控宝的这种第三⽅监控系统，云平台都

⽆缝集成了对应的监控功能，我们在云平台上⼀键开通使⽤即可。

·结合Zabbix API进⾏定制化开发，将监控系统⾃动集成⾄运维平

台、⽉报平台中做集中管理运维，及数据分析和运维巡检。

·在监控数据展⽰上进⼀步优化，接⼊Grafana、DataV进⾏监控数

据集中展⽰，展现效果更加专业。

Grafana+Zabbix监控数据的展⽰效果如图12-9所⽰。

图12-9 Grafana+Zabbix监控数据的展⽰案例

定制化监控⼤屏DataV+Zabbix监控数据的展⽰效果如图12-10所

⽰。

图12-10 DataV+Zabbix监控数据的展⽰案例

12.3 容器体系：四⼤监控⽅案实践

容器技术的出现，可以让我们的业务部署不再依赖底层环境。不

管是物理机，还是各⼤云⼚商，容器技术都能对其进⾏⽆缝部署。容

器体系的微服务架构，是建⽴在分布式架构基础之上的，在业务功能

层⾯的解耦。微服务，特别适合⽤容器技术进⾏部署。⽽容器技术的

出现，也对传统监控⽅案提出了新的要求。物理机体系、云计算体系

下的开源解决⽅案，如Nagios、Zabbix都是针对服务器系统OS层⾯或

者系统OS中的应⽤设计的，它们有个共同特点，即都是静态的。⼀个

环境安装配置好后可能⼏年都不会变动，对监控系统来说，既然监控

对象是静态的，那么对监控对象做的监控配置也应该是静态的，系统

上线部署好监控后基本也就不再需要管理了。

⽽容器的动态⾏为与传统的静态⾏为完全不同：

·可以短期存活和动态调度。

·是⼀种进程，但是具有⾃⼰的环境、虚拟⽹络和不同的存储管

理。

·容器的个数，IP地址随时可能发⽣变化。

Nagios、Zabbix监控软件诞⽣的时候（即1998年和1999年），容

器技术还没有出现，⽽Nagios、Zabbix的出现也并不是为了解决容器

监控问题的。所以⽤Nagios、Zabbix等传统监控⽅案来监控容器，明

显是不合适的。这时，我们就需要有⼀套新的解决⽅案，来解决容器

时代下容器的监控需求。⽽Prometheus的出现，便成为容器监控开源

类的最佳解决⽅案。

12.3.1 监控⽅案⼋：Prometheus+Alertmanager+Grafana

Prometheus是⼀个开源的系统监控及告警⼯具，Prometheus就是为

容器监控⽽诞⽣的。在2016年Prometheus加⼊CNCF基⾦会成为继

Kubernetes之后的第⼆个托管项⽬后，就成为受欢迎度仅次于

Kubernetes的项⽬。Prometheus的体系架构图如图12-11所⽰。

图12-11 Prometheus体系架构

应⽤场景：监控系统&时序数据库（出⾃官⽹），与Nagios、

Zabbix明显不同的是，Prometheus是⼀个监控系统，并没有和关键字IT

有所关联，这⼀点⾮常重要。这是因为任何监控⽬标，只要暴露出标

准的HTTP协议的Metric数据，Prometheus就都能监控到。这也就意味

着Prometheus的监控对象，不仅仅局限于IT系统。类似于容器监控需

求，通过Prometheus很⽅便地就能实现，因此Prometheus被誉为容器开

源解决⽅案的最佳实践。

功能特点：

1）基于时序数据库（TSDB）的多维数据模型。

·时序数据库是典型NoSQL分布式数据库，使⽤它不⽤担⼼数据库

的性能问题。它完美地解决了Zabbix⽤关系型数据库带来的“三⾼”性能

问题。Prometheus数据存储可解决每秒10000000个样本，这个是Zabbix

可望⽽不可即的，所以Prometheus也适⽤于未来物联⽹（IOT）领域的

海量数据存储及监控。

·灵活的数据模型，特别适⽤于对动态灵活性⾼的容器的监控。

·对监控⽬标的监控，不管是系统OS的监控，还是中间件、⽇志及

⾃定义的监控，都需要在系统OS中安装Zabbix Agent，只有这样才能完

成对监控⽬标的监控。⽽Prometheus没有Agent的概念，只需要监控⽬

标能按照标准的HTTP协议暴露出Metric数据，即可完成监控。

2）采⽤HTTP协议，使⽤pull模式拉取数据，简单易懂。在Zabbix

监控体系中，如若Zabbix Server出现异常，可能会导致由于⼤⾯积

Agent连不上⽽出现报警洪⽔。这种情况我们经常在云端遇到，有⼀次

就曾因⽹络抖动，导致我们部署在某个地域的Zabbix Server⼤⾯积报

警。⽽在Prometheus监控体系中，由于Prometheus是主动通过HTTP协

议去获取监控⽬标的监控数据的，即使Prometheus Server出现问题，也

不会导致类似Zabbix Agent连不上的⼤量报警的情况的出现。

3）Prometheus+Alertmanager真正阐释了什么叫“监控”，什么叫“报

警”，⽽Zabbix则将“监控”+“报警”合⼆为⼀，Zabbix带来的报警洪⽔⼀

直是Zabbix的⼀⼤弊端。⽽当Alertmanager出现时，我们激动地把

Alertmanager称为“报警神器”。Alertmanager是Prometheus下的⼀个独⽴

的报警模块（需要单独部署、独⽴运⾏），主要⽤于接收Prometheus发

送的告警信息，它⽀持丰富的告警通知渠道，⽽且很容易做到对告警

信息进⾏去重、降噪、分组等操作，是⼀款前卫的告警通知系统。

⽐如10台主机宕机了，在Zabbix是10条报警且需要通知10次。⽽

Prometheus，我们则可以把这10台机器需要合并报警的监控项打上标

签，并通过分组合并，把对应报警信息合并成⼀条进⾏通知，报警通

知的效率得到了很⼤程度的提升。再⽐如Alertmanager的报警抑制功

能，在Zabbix中，如若运⾏MySQL的主机宕机，则会收到两条报警信

息，⼀条信息是主机宕机，还有⼀条是MySQL宕机。多余的报警信

息，会导致报警不精准，导致运维⼈员排查反向出现偏差。在

Alertmanager中设置报警抑制功能，将⾼级别报警抑制低级别报警，即

只发送⾼级别告警信息，不发送低级别告警信息。这样在Prometheus

中，如若运⾏MySQL的主机宕机，我们只会收到⼀条主机宕机的告

警，告警精准度提⾼了很多。Alertmanager的原理架构图如图12-12所

⽰。

缺点：

·需要每个中间件或者监控⽬标都要单独安装Export，如果有多个

监控⽬标的话，多个监控⽬标对应暴露HTTP服务端⼜，在维护管理等

⽅⾯⾮常不便。

·Prometheus的监控项值只能为浮点数据类型，不能为字符串数据

类型，这个就具有局限性了。为什么不能存储字符串数据类型呢？因

为官⽅觉得涉及不到字符串类型数据采集，应该属于⽇志采集的范

畴，不属于监控的范畴。所以使⽤Prometheus，并不能做字符串类型数

据采集，以及字符串类型数据的规则报警。

12.3.2 监控⽅案九：TICK技术栈

为了解决Prometheus的两⼤缺点，我们对TICK技术栈进⾏了实

践。TICK同样也能解决容器的监控问题，并且也解决了Prometheus需

要安装多个Export及只能存储浮点数据类型，不能存储字符串数据类型

的问题。下⾯我们先来看看TICK技术栈的架构图，如图12-13所⽰。

图12-12 Alertmanager原理架构

图12-13 TICK技术栈体系架构

以下是针对图12-13的说明：

·Telegraf-数据采集：是收集和报告指标及数据的代理，Telegraf是

插件化的，Telegraf通过输⼊插件，能整合多个监控⽬标进⾏数据采

集。Telegraf通过输出插件对监控数据的存储，除了⽀持InfluxDB存储

外，输出插件还可以将指标发送⾄各类数据仓库、服务、消息队列，

⽐如InfluxDB、Graphite、OpenTSDB、Datadog、Librato、Kafka、

MQTT、NSQ等。

·InfluxDB-数据接收：作为时序数据库的“领头⼈”，相⽐

Prometheus⾃带的TSDB存储功能更加完善，⽐如它能存储字符串数据

类型等。

·Chronograf-数据汇总展⽰：监控数据展⽰是TICK技术栈中的弱

项，相⽐于Grafana，其功能及图形展⽰效果等⽅⾯要弱⼀些。

·Kapacitor-监控报警：报警通知也算TICK技术栈中的弱项，相⽐

Alertmanager，并没有报警去重、降噪、分组等功能。

12.3.3 监控⽅案⼗：驻云监控3.0（容器体系监控）

不管是⽤Prometheus还是⽤TICK技术栈，都有其对应的缺点，为

了构建容器体系下的最佳监控解决⽅案。驻云监控3.0将

Prometheus+TICK技术栈进⾏了合并，以完成驻云监控2.0的升级，解决

2.0中对容器监控⽀持的问题，以及海量监控数据读写的问题。驻云3.0

监控技术体系如图12-14所⽰。

图12-14 驻云3.0监控技术体系架构

Telegraf可以配置Prometheus的输出格式（Export），数据输出给

Prometheus，通过Prometheus的Rule+Alertmanager实现监控报警。这样

就解决了TICK技术栈中，使⽤Kapacitor报警通知的缺陷，把

Alertmanager充分利⽤起来。

Telegraf可以同时配置InfluxDB输出，这样InfluxDB就可以存储字符

串数据类型的监控项了，从⽽解决了Prometheus监控数据只能存储浮点

数据类型的问题。

Telegraf⽀持⾃定义监控（通过“exec”的输⼊插件实现），能⽅便

地调⽤Shell、Python等脚本来完成⾃定义监控数据的收集，从⽽满⾜

更多⾃定义监控项的监控。

由于Alertmanager的报警通知，仅存储最新⼀条报警通知信息，

Alertmanager⽆法实现报警信息的历史查看、历史报警分析统计等功

能。所以Alertmanager统⼀将报警信息通过Webhook传送给智能告警机

器⼈（阿尔法⼆代），智能告警机器⼈识别报警属于哪个项⽬，再通

过对应电话逐级升级的⽅式通知到第⼀/第⼆/第三/第四联系⼈。

在智能告警机器⼈这⾥，我们能实现报警信息查看、历史告警统

计分析等功能。在驻云监控2.0中，智能告警机器⼈（阿尔法⼀代）具

有了⼀个很重要的功能，就是报警的合并，这个合并是将⼀定时间内

的所有报警“暴⼒”合并成为⼀个报警。其实报警合并功能，已经属于

Alertmanager的功能范畴了。

在阿尔法⼆代中，报警合并功能直接⽤Alertmanager来实现，相⽐

阿尔法⼀代，Alertmanager能够通过标签分组来进⾏更精准的合并。这

样阿尔法⼆代就仅做报警逐级升级通知、报警信息查看及分析等监控

报警数据的展现功能。

Telegraf+InfluxDB+Prometheus+Alertmanager不仅解决了原⽣态

Prometheus需要安装多个Export且只能存储浮点数据类型的问题，同时

也解决了TICK技术栈中在监控数据图形展⽰、报警通知等⽅⾯的缺

陷。但是该监控架构仅解决了主机+中间件的监控问题，⽆法解决以下

监控问题：

·云产品监控：对RDS、SLB、OSS、VPC、CDN等云产品的监

控。

·站点监控：站点的可⽤性、响应时间、延时监控。

·⽇志监控：⽇志的存储、⽇志查询、⽇志监控报警。

·代码监控：业务代码层次，⽐如Java、PHP代码层⾯的性能监控。

为了解决这套监控架构在云产品、站点、⽇志、代码等⽅⾯的监

控问题，我们先来看看云监控、Zabbix、Prometheus这三个监控⽅案的

功能特性对⽐情况，如表12-2所⽰。

我们通过实践发现，云监控在云产品监控、站点监控、⽇志监

控、代码监控等⽅⾯功能优势明显。这些都被云平台产品标准化了，

所以针对这些⽅⾯的监控⾮常完善。只不过云监控在主机系统OS层⾯

的监控深⼊度不够，特别是对中间件的监控，还是需要通过云监控API

完成⾃定义监控，这⽅⾯⽐较复杂。但是，可不可以把云监控也整合

到我们的监控体系中来呢？这样在云产品、站点、⽇志、代码等⽅⾯

的监控问题便迎刃⽽解了，从这个设想出发，便形成了驻云监控3.1版

本的监控体系。

12.3.4 监控⽅案⼗⼀：驻云监控3.1（智能监控）

驻云监控3.1的技术体系，指的是驻云先见监控系统，3.1监控技术

体系架构如图12-15所⽰。

表12-2 云监控VS Zabbix VS Prometheus

以下是图12-15的相关说明。

·主机+中间件监控：通过Telegraf+Prometheus完成主机OS层⾯及常

见开源中间件的监控。

·AlertHub：驻云⾃动研发，驻云先见系统的核⼼组件，将

Alertmanager+智能告警机器⼈（阿尔法⼆代）的功能进⾏合并。

·云产品监控/站点URL监控/⽇志监控/代码监控：直接通过云监控

报警回调写⼊我们内部报警通知系统，并进⾏报警合并、报警通知、

报警分析等操作。我们之所以把驻云监控3.1称为智能监控，是因为驻

云先见监控系统，汇聚了⼤量多个监控源的报警信息，这样做报警信

息合并、优化，可以使报警的通知更精准，甚⾄跟进⼤量报警数据及

智能算法，以做到真正意义上的趋势报警，防患于未然，对业务系统

提出⼤量智能优化的建议。

·我们也可以通过Telegraf调⽤云API，⽐如RDS API，取慢SQL、

RDS控制台对应性能数据，然后输出给到Prometheus，通过Prometheus

的Rule+Alertmanager实现更加灵活的⾃定义报警策略。值得注意的

是，常规监控的报警策略，云监控都完成了，这⾥的场景主要⽤于云

监控没办法完成的报警场景。⽐如，我们根据慢查询SQL语句全表扫

描的⾏数来做报警规则。

·InfluxDB+Grafana：将监控数据统⼀集中存储⾄InfluxDB中，然后

通过Grafana做监控数据的图形展⽰。

图12-15 驻云监控3.1技术体系架构

服务器监控数据Grafana的展⽰效果如图12-16所⽰。

图12-16 服务器监控数据Grafana的性能展⽰效果图

RDS（性能监控数据）Grafana展⽰效果如图12-17所⽰。

图12-17 RDS Grafana性能展⽰效果图

RDS（慢SQL）Grafana展⽰效果如图12-18所⽰。

图12-18 RDS（慢SQL）Grafana展⽰效果图

通过驻云监控3.1体系，即图12-15我们也能看出，云监控的占⽐⽐

较⼤。也正如前⾯所说，监控的未来趋势主要是云监控。当前我们之

所以还采⽤“Prometheus”这套开源的监控技术，主要是因为需要弥补云

监控在中间件、容器⽅⾯、报警合并通知等监控功能⽅⾯的不⾜。随

着云平台的功能逐步完善及成熟，云平台中⾃带的云监控也逐渐完善

及成熟，云监控也必然会成为互联⽹监控的主流。

第13章 云端容器/DevOps实践

云计算推进了IT体系的发展及技术架构的变⾰。IT体系的发展经

历了物理机体系阶段、云计算体系阶段，现在即将进⼊容器体系阶

段。预计到2020年，将有超过50%的全球企业在⽣产环境中运⾏容

器。在以前，业务跑在物理机房中，为了上架⼀台服务器⽀撑业务，

需要⾛审批购买、搭建环境、上架机房等烦琐流程，时间耗费周期是

按天来计算的。但如今，我们在云平台中购买⼀台服务器就如同在淘

宝上购物⼀样，可按需索取。计算资源的开通、时间耗费周期都是按

分钟来计算的。相信随着云计算机的发展，容器技术也会逐渐普及。

到那时，计算资源已经创建好，我们可直接从容器中索取计算资源，

且时间耗费周期将达到秒级（Docker容器⼀般启动的速度是1～3

秒）。相应地，对应的系统架构也从以前的单机/集群架构转换到如今

云普及的分布式架构，并且即将进⼊微服务架构阶段。

容器技术让我们既不⽤关注底层是物理硬件，也不⽤关注云平台

⽤的是亚马逊还是阿⾥云，因为不管是哪种平台，业务都能⽆缝地运

⾏在各个平台中［本质上如同Java虚拟机（JVM）］。即我们对计算

资源的使⽤已脱离了硬件，甚⾄是对各个云平台的依赖。⽽微服务架

构给我们研发的灵活性、业务后期迭代带来了极⼤的可扩展性，对应

⼤量的微服务也能更加⽅便、更加⾼效、更加适合地运⾏在容器中。

由此也可见，容器技术和微服务架构也是相辅相成的。容器技术的出

现，不仅引领着云计算的未来发展趋势，也引领着IT技术体系的发

展，更是让传统运维⾃动化演变成基于容器的⼀套DevOps技术体系，

并成为如今的⾏业标准。本章主要针对当前最热门的容器技术，通过

真实客户案例来分享云端最佳实践。

13.1 云端容器技术的⼗⼆⼤实践

在云端，越来越多的客户使⽤Docker容器技术来进⾏业务部署。

下⾯的实践案例中，⼀家做新零售的客户在线下的测试环境中已经使

⽤了Swarm进⾏发布及运⾏。在云端⽣产环境的部署，客户希望全⾯

使⽤最新的容器资源编排技术来进⼀步提升相应的发布及维护效率。

本章要讲解的云端容器技术的实践内容，也主要通过这家客户的案例

来跟⼤家进⾏分享。

13.1.1 容器实践1：关于云端容器资源编排技术的选择

我们先来看看在云端如何选择容器相关的资源编排技术。Docker

是容器技术中最佳的实践技术，基本上提到Docker⼈们当即就会想到

容器技术。我们在服务器中部署了多个Docker进程来实现不同的应

⽤，然后把这些应⽤打包成Docker镜像，可以⽆缝迁移或运⾏在各个

云平台上，甚⾄是物理机类型的服务器中。

但值得注意的是，Docker技术其实是⼀个单机版技术。⽽类似

K8S（Kuberneters缩写，K和S之间有8个字母，所以简称K8S）的容器

编排⼯具的核⼼是解决应⽤部署在单机Docker中时，所存在的扩容、

缩容、故障⾃愈等容器资源管理问题。例如，⼀个服务器宕机了，容

器编排⼯具可以⾃动将这个服务器上的服务调度到另外⼀个主机上运

⾏，⽆须进⾏⼈⼯⼲涉。特别是在⼤规模应⽤中，容器编排⼯具可以

使容器的管理⾮常⾼效。

当前最为热门的容器编排⼯具技术当属K8S和Swarm，两者的对⽐

如表13-1所⽰。

表13-1 K8S和Swarm优劣势对⽐

总的来说，如果对容器的可靠性要求不⾼，Swarm⽐较合适；如果

是对外服务，或者是需要提供⾼可靠服务的场景，K8S更合适。基本上

80%的中⼩型企业，其业务都较简单，因此在资源编码技术的选型⽅

⾯，我个⼈还是推荐使⽤Swarm，因为它可以快速⼊⼿。当然此案例

中，由于对容器管理我们有更精细的要求，⽐如限制容器的使⽤性能

等，所以默认优先选择K8S。

除了K8S和Swarm外，很多⼈也喜欢把Mesos拿来做对⽐。K8S、

Swarm是针对Docker的⼀套资源编排系统，但Mesos不同，它是⼀套分

布式系统，不仅能和Docker集成来做资源编排，还可以运⾏不同的分

布式计算平台，如Spark、Storm、Hadoop、Marathon和Chronos等。

作为Mesos项⽬的早期⽀持者和使⽤者之⼀的Twitter公司（⽣产集

群规模达万级别节点），在2019年5⽉2号宣布从Mesos全⾯转向

Kuberneters（K8S）。这意味着Kuberneters已成为容器资源技术的标

准，已得到互联⽹公司的普及。⽽在云端，我们也⼏乎很难看到有公

司在⽤Mesos做容器资源编排了。

13.1.2 容器实践2：结合K8S的DevOps流程

在绝⼤多数的K8S实践中，K8S的应⽤场景主要是CI/CD（可持续

集成/可持续交付）的可持续交付环境，即实现应⽤及资源的快速部

署。我们通过GitLab来管理代码，通过Jenkins+Maven对代码进⾏全⾃

动编译及打包，最终⽣成Docker镜像并传到私有仓库中。然后再结合

K8S，把Docker镜像推到测试环境/预⽣产环境/⽣产环境中运⾏。这⾥

值得注意的是，传统的DevOps流程中，是在操作系统中通过执⾏git

pull命令来拉取代码进⾏更新发布的。⽽结合容器的DevOps流程，是先

将代码打包成Docker镜像，然后把Docker镜像推到容器中运⾏，从⽽完

成更新发布，如图13-1所⽰。

图13-1 结合K8S的CI/CD DevOps流程图

13.1.3 容器实践3：关于K8S集群的配置

通过实践1和实践2的介绍，在容器资源编排及DevOps中的实践，

我们都是优先选择K8S作为容器的资源编排。在本客户案例中，为了实

现更多的灵活性及功能性上的要求，并且考虑到当时阿⾥云的K8S服务

还不够成熟，所以我们采⽤了在ECS上⾃建K8S的⽅式。前期K8S集群

的配置清单如表13-2所⽰。

表13-2 云端⾃建K8S集群的配置清单

K8S具体⽤来部署什么应⽤呢？这其实是个值得我们探讨的话题。

在使⽤容器编排技术时，为了让对应容器⾼可⽤，也为了让机器性能

的利⽤率更⾼，因此容器会根据状态是否存活，以及机器性能使⽤⾼

低的情况，在不同的节点之间调度漂移。加上本⾝K8S就会消耗机器性

能，所以总体来说，K8S不适合部署对性能配置依赖很⾼的应⽤。这就

间接说明了为什么我们⼀般很少将数据库部署在应⽤中，⽽是把业务

代码部署在容器中，因为这样可以实现快速部署。以上4台服务器主要

是⽤来部署业务的，⽽数据库等应⽤都是单独部署的。

以上服务器的配置清单，⽤的是8核64GB。CPU和内存资源配⽐为

1:8，这是完全偏向⼤内存的机器配置。在没有缓存应⽤的前提下，⽤

这样的配置仅部署业务代码，显然是不合理的。其实这也是⽆奈之

举，最开始我们的服务器配置采⽤的是8核32GB，但由于客户应⽤代

码⽤的是Ruby的⼀个⽼框架，对内存的消耗⾮常⼤，⽤8核32GB有时

候会造成机器的内存不⾜，所以才⽆奈升级到8核64GB。在实践中，

在云端推荐使⽤8核16GB、8核32GB的配置来部署K8S集群。

13.1.4 容器实践4：K8S云端部署架构

在ECS中，K8S的部署架构如图13-2所⽰。

图13-2 云端⾃建K8S集群架构

前端SLB通过配置转发规则，配置到Kube-Proxy的代理端⼜上（代

理端⼜会将请求映射转发⾄K8S集群内对应的Docker服务端⼜上）。

Master和Node节点都有Flanneld进程，Flanneld⽹络⽤于K8S集群通

信。

在Master节点上，主要部署Etcd（配置管理）、APIServer（集群控

制⼊⼜）、Controller-Manager（资源⾃动化控制中⼼）、

Scheduler（资源调度）进程服务。

在Node节点上，主要部署Kubelet（POD管理）、Kube-Proxy（端

⼜映射）、Docker进程服务。

除了以上进程外，我们还部署了Nginx及HAProxy，具体的⽤途后

⽂会跟⼤家详细介绍。

13.1.5 容器实践5：K8S插件之DNS

K8S的DNS插件，并不是主要⽤途类似域名解析的传统DNS。在

K8S内，应⽤服务之间的调⽤不能⽤集群IP。因为资源编排调⽤，应

⽤部署的POD可能会发⽣迁移导致集群IP变动。所以应⽤和应⽤之间

的调⽤，考虑通过服务器名完成。⽽K8S的DNS主要完成服务器名和

集群IP地址的映射，由此可见DNS插件是K8S⾮常重要的功能。

图13-3 容器内ping服务器名失败截图

图13-4 容器内ping服务器名成功截图

如若DNS插件未配置正确，我们在容器中ping对应的服务器名

时，会出现unknown host的错误，如图13-3所⽰。

如若DNS插件配置正确，我们在容器中就能ping通对应的服务器

名，如图13-4所⽰。

DNS插件YAML的核⼼配置明细如图13-5所⽰。

10.254.0.0/8是集群的IP端，此配置需要跟集群环境配置保持⼀

致，否则会导致集群内通信异常。replicas：3表⽰DNS服务运⾏了3个

副本以保障⾼可⽤。

13.1.6 容器实践6：容器的Web管理控制台

1.K8S插件之Dashboard认证（对LDAP的⽀持）

K8S Dashboard是K8S⾃带的⼀个Web UI控制页⾯，⽤户可以通过

Dashboard在K8S集群中部署容器化的应⽤，对应⽤进⾏问题处理和管

理，并对集群本⾝进⾏管理。这对⾮系统运维专业⼈⼠（⽐如研发⼈

员、测试⼈员）来说很⽅便，可以对K8S集群进⾏应⽤发布和部署等操

作。相反，如若未部署Dashboard，则需要通过部署kubectl命令⾏⼯具

来对K8S集群进⾏⽇常的管理及维护，这对部署⼈员的专业要求较⾼。

K8S⾃带的Dashboard⽀持密码、证书认证，但对LDAP的认证不太⽀

持。为了解决这个问题，我们引⼊了Nginx，它可以很⽅便地解决此问

题，其架构如图13-6所⽰。

图13-5 DNS的YAML配置

图13-6 Nginx的LDAP对K8S的Dashboard认证

我们在Dashboard前加上Nginx做反向代理，Nginx中的第三⽅

LDAP模块就完美地解决了我们对LDAP的需求。Nginx核⼼配置如下：

ldap_server qbzladp {

url

ldap://ldap.qiaobangzhu.cn/dc=qiaobangzhu,dc=cn?sub?(objectClass=inetOrgPerson); binddn "cn=admin,cn=kubernetes,ou=groups,dc=ldap,dc=cn"; binddn_passwd k8s_aliyun_****;

group_attribute member;

group_attribute_is_dn on;

require group "cn=aliyun01,cn=kubernetes,ou=groups,dc=****,dc=com"

require valid_user;

}

server {

listen 8088;

server_name ***.***.***.***;

location / {

expires 7d;

auth_ldap "Forbidden";

auth_ldap_servers jwladp;

autoindex on;

proxy_pass http://172.16.1.173:8080;

proxy_set_header Host $host:8080;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Via "nginx";

}

access_log on;

}

2.Rancher对K8S的管理

Rancher是⼀个开源的企业级容器管理平台。有了Rancher，企业再

也不必⾃⼰使⽤⼀系列的开源软件从头搭建容器服务平台了。Rancher

提供了在⽣产环境中使⽤的管理Docker和K8S的全栈化容器部署与管理

平台。但在实际运⽤中，相⽐于K8S的复杂，也有很多⼈选择Rancher

⾃带的Cattle资源编排来完成容器的管理，它的优点主要是⽅便快捷。

当然Rancher也能集成K8S、Swarm、Mesos（相⽐于K8S和Swarm来说

不常⽤），这使得我们可以通过Rancher来管理K8S，⼤⼤降低了K8S

的使⽤门槛。相较于K8S⾃带的Dashboard，还是推荐使⽤Rancher做

K8S的管理页⾯。

在本实践案例中，最开始的时候我们采⽤K8S⾃带的Dashboard来

管理集群，后⾯为了进⼀步提升研发发布的效率，我们引⼊了

Rancher。Rancher和K8S的集成也⽐较简单，我们采⽤⼀台4核8GB的

ECS单独部署了Rancher，然后在全局模式下执⾏了已存在集群的导⼊

操作，并登录到K8S集群的Master服务器执⾏了Rancher平台的YAML部

署⽂件，如图13-7所⽰。

图13-7 Rancher导⼊集群

执⾏完成之后会⽣成相应的与Rancher Server通信的Agent进程。

Rancher Server端与Rancher Agent端通过API获取到K8S集群的信息后，

在Rancher控制台就能看到K8S集群的相关信息，如图13-8和图13-9所

⽰。

图13-8 K8S集群资源性能使⽤情况

13.1.7 容器实践7：K8S业务应⽤+⾃建DNS实践

实践5中曾介绍过K8S集群内的DNS，K8S集群的DNS只是针对集

群内Service的解析映射。部署在K8S中的应⽤要解析外部域名，那这块

要怎么做呢？我们不可能⼿动配置把解析IP放在Docker环境的hosts⽂

件中，或者在Docker环境中的/etc/resolv.conf中配置DNS Server。因为

如果重启Docker，这些配置都会丢失。⽽在本案例中，我们在内⽹中

⾃建了DNS Server，架构如图13-10所⽰。

图13-9 K8S集群的系统POD

图13-10 K8S+⾃建DNS

K8S中的业务代码要连接Redis和MySQL，需要采⽤内部⾃建的

DNS Server。结合上⽂⾃建DNS的实践内容，我们发现：

Docker环境中的DNS是继承ECS宿主机的DNS，因此只需要配置宿

主机的/etc/resolv.conf即可。

在宿主机ECS中，/etc/resolv.conf变更nameserver后，需要重启

Docker重新加载。

在Ubuntu下，/etc/resolv.conf的管理是ResolvConf服务管理，并且

有些阿⾥云Ubuntu镜像是采⽤DHCP来管理DNS及IP的，因此需要变更

IP的管理⽅式为static。这样我们配置的/etc/resolv.conf，就不会因为重

启服务器，⽽使得配置的DNS默认被DHCP重置了。

13.1.8 容器实践8：K8S Master节点⾼可⽤

Master节点⾼可⽤，就是在不同机器上部署APIServer、Controller-

Manager及Scheduler。我们可以在API-Server启动命令中⽤“--apiserver-

count=3”参数指定APIServer的节点数，这样我们就可以开启多个

APIServer节点，来保障APIServer的⾼可⽤。由于APIServer是K8S集群

的控制⼊⼜，所以K8S Master节点的⾼可⽤，基本上就是保障

APIServer⾼可⽤即可。

Node节点需要和Master节点进⾏通信，即跟集群控制的⼊⼜

APIServer进⾏通信。虽然我们已经启⽤了多个APIServer，但是如若

Node仅连其中⼀个Master节点的APIServer地址，这个Master节点宕机

的话，则会导致连接该Master节点的所有Node节点从集群中丢失。所

以为了保障连接的Master节点⾼可⽤，我们最后还需要在APIServer前

⾯加个四层的SLB，如图13-11所⽰。

图13-11 SLB+K8S Master⾼可⽤架构

但是在实践中，SLB的⽅案未通过。因为在APIServer中报错，集

群对于SLB的IP不识别。⽽这主要是因为我们集群内通信采⽤的是SSL

加密，在集群的kubernetes.pem证书中我们看到以下配置：

"sans": [

"kubernetes",

"kubernetes.default",

"kubernetes.default.svc",

"kubernetes.default.svc.cluster",

"kubernetes.default.svc.cluster.local",

"127.0.0.1",

"172.16.1.1",

"172.16.1.2",

"172.16.1.3",

"172.16.1.6",

"10.1.0.1"

]

在以上证书配置中，“127.0.0.1”“172.16.1.1”“172.16.1.2”等IP地址是

允许跟K8S通信的IP地址（⽩名单地址），由于SLB健康检查⾃带的IP

地址不在K8S通信证书的⽩名单地址中，所以SLB⽆法与APIServer通

信，APIServer中就出现了SLB的IP不识别的对应报错。既然SLB不能做

APIServer的负载均衡，我们就在每台机器上安装HAProxy，通过

HAProxy做APIServer的负载均衡来解决这个问题。架构如图13-12所

⽰。

图13-12 HAProxy+K8S Master⾼可⽤架构

我们在要连接APIServer的所有机器上都搭建HAProxy来保障

HAProxy是独⽴部署的。这样⼀来，单台HAProxy即使宕机也只是影响

本机，并不影响其他机器的调⽤。HAProxy核⼼配置如下：

frontend haproxy-https

bind 127.0.0.1:443

mode tcp

option tcplog

tcp-request inspect-delay 5s

tcp-request content accept if { req.ssl_hello_type 1 }

default_backend k8s-api-https

backend k8s-api-https

mode tcp

option tcplog

option tcp-check

balance roundrobin

default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250

maxqueue 256 weight 100

server k8s-api-1 172.16.1.173:6443 check

server k8s-api-3 172.16.1.175:6443 check

server k8s-api-2 172.16.1.176:6443 check

需要特别注意的是，在HAProxy的配置中，IP绑定在127.0.0.1上，

主要与kebernetes.pem证书中添加的IP地址相对应。否则我们新添加的

Node节点就⽆法与APIServer通信，或者需要重新制作kebernetes.pem证

书。在每台Node上，HAProxy搭建完毕后，我们需要针对客户端的配

置做如下更改。

·Kubectl：config配置中的Server地址。

·Kubelet：bootstrap.kubeconfig及kubelet.kubeconfig配置⽂件中的

Server地址。

·Kube-Proxy：kube-proxy.kubeconfig配置⽂件中的Server地址。

13.1.9 容器实践9：K8S Node节点⾼可⽤

相较于Master节点的⾼可⽤来说，让Node节点⾼可⽤要⽅便许

多，在云端结合ECS的镜像功能能让Node节点进⾏快速横向扩展。我

们把现有Node节点打个镜像，然后开通⼀台ECS，这时，只需要变更

Kubelet及Kube-Proxy启动命令中的IP地址，Node节点就会⾃动加⼊到

集群中。Kubelet的配置如下：

[Unit]

Description=Kubernetes Kubelet

Documentation=https://github.com/GoogleCloudPlatform/kubernetes After=docker.service

Requires=docker.service

[Service]

WorkingDirectory=/var/lib/kubelet

ExecStart=/root/local/bin/kubelet \

--address=172.16.1.174\

--hostname-override=172.16.1.174 \

--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest \

--experimental-bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig \

--kubeconfig=/etc/kubernetes/kubelet-kubeconfig \

--tls-cert-file=/etc/kubernetes/ssl/kubelet.pem \

--tls-private-key-file=/etc/kubernetes/ssl/kubelet-key.pem \

--cert-dir=/etc/kubernetes/ssl \

--container-runtime=docker \

--cluster-dns=10.254.0.253 \

--cluster-domain=cluster.local. \

--hairpin-mode promiscuous-bridge \

--allow-privileged=true \

--serialize-image-pulls=false \

--register-node=true \

--logtostderr=true \

--v=2

[Install]

WantedBy=multi-user.target

Kube-Proxy的配置如下：

[Unit]

Description=Kubernetes Kube-Proxy Server

Documentation=https://github.com/GoogleCloudPlatform/kubernetes After=network.target

[Service]

WorkingDirectory=/alidata/lib/kube-proxy

ExecStart=/root/local/bin/kube-proxy \

--bind-address=172.16.1.174 \

--hostname-override=172.16.1.174 \

--cluster-cidr=192.168.0.0/16 \

--kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig \

--logtostderr=true \

--v=2

Restart=on-failure

RestartSec=5

LimitNOFILE=65536

[Install]

WantedBy=multi-user.target

这⾥，只需要更改172.16.1.174的IP地址为最新的ECS内⽹IP地

址，然后重启Kubelet及Kube-Proxy进程，Node节点就会⾃动添加到集

群中了。如若需要删除Node节点，只需要通过⼀条kubectl delete node

命令即可将其删除。

13.1.10 容器实践10：K8S部署架构优化

本案例中，最开始在ECS中部署，我们采⽤的是通过4台机器部署

的K8S集群。Master和Node节点冗余是⼀起部署的，这在架构上其实是

不合理的。⽐如上线后，我们经常遇到由于部署业务代码的原因⽽导

致Node节点的ECS性能跑满的问题，这不仅会影响部署在Node节点上

的Master节点的稳定性，还会影响整个集群的稳定性。随着业务的发

展，最终我们将集群架构进⾏了变更，如图13-13所⽰。

图13-13 云端⾃建K8S+Rancher部署架构

配置清单如表13-3所⽰。

表13-3 云端优化后的K8S架构配置清单

从原集群迁移到新集群中也⽐较⽅便。新开了3台4核8GB的机

器，搭建Master节点。迁移的核⼼点是需要将原集群中ETCD的数据迁

移⾄新开通的3台机器中，完成上述操作基本上迁移就成功了⼀⼤半。

其他的迁移细节，本⽂就不再过多介绍。

13.1.11 容器实践11：⾃建K8S迁移阿⾥云K8S托管版+Rancher

早期我们在云端ECS中⾃建K8S，主要原因是当时阿⾥云K8S相关

产品的功能服务还不那么完善。云端⾃建K8S后续的维护、版本升级、

版本兼容性等问题也给我们带来了很⼤困难。现在，阿⾥云容器服务

⽇益成熟，已能部署投⼊到应⽤⽣产环境中，这在很⼤程度上降低了

我们⾃建带来的维护成本。由于业务环境都是跑在Docker中的，Docker

跨平台的特性让业务代码从⾃建K8S迁移⾄阿⾥云K8S中成为⼀个⽆缝

迁移的过程。我们只需要在阿⾥云K8S中拉取私有仓库中的Docker镜

像，重新部署⼀下即可。

阿⾥云容器服务K8S版基于原⽣K8S进⾏适配和增强，简化了集群

的搭建和扩容等⼯作，它通过整合阿⾥云的虚拟化、存储、⽹络和安

全等能⼒来打造云端最佳的K8S容器化应⽤运⾏环境。产品架构如图

13-14所⽰。

如今，阿⾥云容器服务K8S集群有3种形态：专有版

Kubernetes（Dedicated Kubernetes）、托管版Kubernetes（Managed Kubernetes），以及Serverless Kubernetes。它们的对⽐如表13-4所⽰。

图13-14 阿⾥云容器服务Kubernetes版

表13-4 阿⾥云3种K8S集群形态对⽐

我们采⽤阿⾥云K8S托管版直接托管了Master节点，这样我们就不

⽤⾃⼰去部署配置Master，也不⽤担⼼Master节点⾼可⽤，这些都会默

认被阿⾥云K8S服务完成。在阿⾥云K8S管理控制台中，我们也可以让

Node节点的资源选择利⽤率不⾼，或者将废弃的ECS加⼊到集群中来

做资源复⽤。⽽同样，我们也能将托管版的K8S导⼊到⾃建的Rancher

中，导⼊流程跟上⽂提到的⾃建K8S导⼊Rancher的流程基本⼀致，这

⾥不再赘述。不过，需要注意的是，由于托管版的Master节点不能直接

SSH，因此可以通过阿⾥云CloudShell或者安装Kubectl客户端来操作管

理K8S，从⽽把K8S导⼊到Rancher中进⾏管理。

云诀窍

对于专有版Kubernetes、托管版Kubernetes，由于我们能操作Master

节点，所以能将其导⼊到⾃建的Rancher中。但Serverless Kubernetes中

的Master已被封装，因此不⽀持导⼊。

13.1.12 容器实践12：K8S监控实践

监控是运维中的第⼀道防线，能让我们快速发现问题。只有第⼀

时间知道问题所在，才能触发后续的处理流程。K8S本⾝也是个中间

件，从本质上来说，与Tomcat监控没什么不⼀样。当然，我们要从不

同的维度来全⾯性监控K8S，保障出现问题能第⼀时间定位到问题的所

在。监控项实践如表13-5所⽰。

表13-5 K8S集群监控

13.2 DevOps发展的四个阶段

正如前⾯所说的，云计算推进了传统技术架构的变⾰，使其由曾

经的物理机架构阶段演变到了如今的云计算架构阶段。⽽容器推进了

云计算架构的变⾰，未来即将进⼊容器架构阶段，即业务的部署不依

赖云⼚商平台，可以横跨多个云平台进⾏⽆缝部署。我们知道在运维

领域，运维⾃动化⼀直是运维技术造诣最重要的体现，也是运维的灵

魂。同样，容器也在运维领域引领着运维⾃动化的技术变⾰。接下来

主要介绍容器所引领的运维⾃动化发展的4个阶段。

13.2.1 ⼈⼯阶段

在单机架构、集群架构的物理机IT体系下，服务器没有那么多，

我们的⽇常运维全部依赖⼈⼯。⽇常运维维护需求全由⼈⼯输⼊命令

解决，这是运维的最原始阶段。在⼈⼯苦⼒的阶段，我们完全没有精

⼒考虑运维⾃动化，甚⾄连运维⾃动化这个概念可能都没听说过。

在这个时候，⾏业赋予我们⼀个荣誉称号：“7×24背着笔记本的农

民⼯”。何为“7×24”？就是⽆论何时何地都会带着笔记本，以保证在出

现监控报警时⾃⼰能够第⼀时间上线处理故障。我在⾼铁上、⽕车

站、过年的时候、晚上做梦的时候、逛街的时候、看电影的时候等⼏

乎任何时间和地点都处理过运维故障。那又何为“农民⼯”呢？以前做

传统运维的时候，更多是在跟硬件打交道。我装过系统，编译过内

核，编译过驱动，去过机房，布过线，扛过服务器等。IDC机房的服

务器上下架期间，我们经常扛着服务器，所以我们称⾃⼰为“农民

⼯”。对于传统运维，我们经常要做如下⼯作。

（1）和硬件相关的⼯作

和硬件相关的⼯作主要分为以下两类：

·搬服务器，⽹络部署，机器上架。

·硬件⽇常维护：联系机房重启机器，更换磁盘，更换内存，解决

硬件故障等问题。

（2）和系统相关的运维⼯作

和系统相关的运维⼯作主要分为两⼤类：

·系统环境运维状态维护：环境安装配置、性能调优、安全加固、

⽇常运维故障处理、运⾏状态监控及巡检等。

·业务代码变更发布：代码部署、代码⽇志查看、代码版本回滚、

代码运⾏环境重启等。

在做系统相关的运维⼯作时，需要登录⼀台台服务器以命令⽅式

完成⽇常维护⼯作，如图13-15所⽰。

图13-15 ⼈⼯阶段下的运维⼯作⽅式

13.2.2 脚本及⼯具阶段

随着云计算的普及，分布式架构也得到⼴泛应⽤。我们要维护的

服务器越来越多，我们开始尝试将⽇常重复的⼯作通过脚本、⼯具来

完成，以此替代⼈⼯⽅式，提升维护效率。运维⾃动化便是这个阶段

开始发展起来的，这让⼤家明⽩了批量服务器通过脚本及⼯具进⾏集

中化管理，是运维⼈员技术、效率最重要的价值体现。于是，⼤家⼀

致认为，不懂⾃动化的运维⼈员不是⼀个好运维⼈员。

1.运维⾃动化1.0

传统运维中，要说运维脚本领域排⾏第⼀的，当属Shell脚本了。

能把⽇常运维命令直接⽅便快捷地封装成Shell脚本，以此代替⼈⼯操

作，实属不错的提升⽇常维护效率的办法，简单且⽴竿见影。也许会

有⼈说Python也不错，但Python毕竟是⼀门⾼级编程脚本语⾔，能够掌

握的运维⼈员少之又少。以⾄于学会Python成了每⼀个运维⼈员的理

想。现下，在云端运维中，Python却逐步成为运维脚本的⾸选编程语

⾔。因为在传统运维中，⽇常的安装、部署、配置等⾸选通过Shell完

成⾃动化需求，在云端都能通过云平台的镜像、API等功能完成，且更

⽅便简单。所以通过Shell部署的时代逐渐被取代，我们需要进⼀步通

过Python脚本结合云API，完成符合业务场景的⾃动化部署，这是云端

脚本⾃动化运维的⾸要⽬标。

除了Shell/Python编程脚本可以完成⾃动化外，运维⾃动化⼯具⽅

⾯，当属Ansible、SaltStack、Puppet这三⼤⾃动化⼯具。Puppet配置烦

琐，较难掌握，在云端客户运维中不考虑。Ansible和SaltStack源码都

是基于Python，对喜爱Python的运维来说⽆疑是⾸选。在刚开始给客户

部署时，我们采⽤的是SaltStack，主要是因为对这个⼯具更熟悉些。但

随着客户的服务器增多，SaltStack C/S模式要安装Agent，管理起来⽐

较⿇烦，⽽且有时候SaltStack Server批量下发指令还会丢机器，导致有

些Agent不能执⾏对应指令操作。因为SaltStack存在这些缺陷，Ansible

最终成为运维⾃动化⼯具的⾸选，相⽐SaltStack和Puppet，Ansible⽆须

安装Agent，并且基于SSH协议，这让其使⽤起来⾮常便捷且⾼效，如

图13-16所⽰。

图13-16 运维⾃动化1.0版本

在⼈⼯阶段，我们需要⼀台台登录服务器并通过命令⽅式完成⽇

常维护⼯作。⽽在脚本及⼯具阶段，可通过⾃动化⼯具及脚本来集中

化来管理成百上千台服务器，这使得运维的效率得到了很⼤的提升。

2.运维⾃动化2.0

在运维⾃动化1.0中，要使⽤Ansible+Shell的⽅式，就需要熟悉

Ansible及Shell，可见是有⼀定技术门槛的。随着业务系统逐步增多、

服务器增多，频繁的业务更新迭代给我们带来新的运维挑战。

·随着需要运维维护的机器逐渐增多，运维需要熟练掌握

Ansible+Shell技术才能有效提升效率。并且还需要避免因为对Ansible不

熟悉⽽导致的误操作，这给运维带来很⼤的挑战。

·研发经常会有变更发布的需求，即使是简单的变更发布也需要运

维亲⾃完成。这种频繁简单的操作不仅浪费时间，也不利于及时变更

发布。

针对运维⾃动化1.0版本下的⾃动化⾯临的问题及挑战，我们把⽇

常运维经常⽤到的重复性的命令（如重启、版本更新、版本回滚等）

通过Rundeck图形化管理⼯具封装成⼀个Web控制台。运维、研发只需

要点击Web控制台中已经封装好的功能模块，就可以完成⽇常运维及⽇

常代码变更发布等⼯作，如图13-17所⽰。

在Ansible+Shell基础之上加⼊Rundeck后，可实现集中图形化管

理，并且还可以根据不同⾓⾊来进⾏权限划分。这样⼀来，运维⼈员

就不需要记住专业的⾃动化命令了，在页⾯上就能实现⾃动化管理，

不需要带着笔记本上线处理问题，在⼿机上直接点击变更发布即可。

关键的是，研发⼈员也可以⾃⾏去实现发布、回滚等操作。发布代码

不仅只是运维的任务了，研发随时随地可⾃⾏操作，这⽆疑也提升了

发布效率。

云诀窍

Python已成为云端通过脚本进⾏⾃动化运维的标准，Ansible⽆疑

也已成为云端通过⼯具⾃动化运维的标准。

图13-17 运维⾃动化2.0版本

3.DevOps1.0

随着互联⽹的发展，互联⽹业务之间的竞争⽇益激烈。企业要想

在互联⽹业务竞争的浪潮中不被淹没，除了业务的功能特性优势之

外，还要快速地更新迭代来不断满⾜⽤户需求，提升竞争优势和⽤户

体验。这时候，敏捷开发的思路被提出来。在此基础上，DevOps体系

被提出来。

DevOps的出现就是为了解决软件开发⼈员（Development，Dev）

和IT运维技术⼈员（Operations，Ops）之间的沟通协作问题，以使得

构建、测试、发布软件能够更加快捷、频繁和可靠。由此可见，

DevOps与运维⾃动化的概念是有很⼤不同的。运维⾃动化主要解决资

源集中管理⽅⾯的问题以提升运维效率，其关注系统维护层⾯。⽽

DevOps则主要解决持续集成（Continuous Integration，CI）及持续交付

（Continuous Delivery，CD）⽅⾯的问题以提升业务快速集成及交付，

其关注业务迭代层⾯。

在运维⾃动化2.0版本中，研发能通过运维提供的⼯具平台快速完

成代码部署交付到测试环境、预发环境，甚⾄到⽣产环境，这已经属

于DevOps体系中CI/CD中的CD功能。但是如何做到持续集成，即完成

代码的⾃动编译及⾃动测试，这是DevOps体系要解决的问题。

Jenkins是开源CI&CD软件的领导者，提供超过1000个插件来⽀持

构建、部署、⾃动化，以便满⾜任何项⽬的需要。Jenkins出现后很快

成为DevOps体系主流的最佳实践⼯具。通过Jenkins我们很快解决了软

件代码的⾃动编译及⾃动测试，并且对应的插件也能帮助Jenkins通过

SSH⽆缝打通后端服务器，通过Jenkins也能完成软件代码的部署交付，

如图13-18所⽰。

图13-18 DevOps1.0阶段

我们主要代码的部署是通过Jenkins拉取GitLab中的代码进⾏可持续

集成，进⾏代码编译及发布。ECS的⽇常运维还是通过

Ansible+Shell+Rundeck进⾏集中化管理。

13.2.3 平台化阶段

1.运维⾃动化3.0

运维⾃动化2.0中，虽然通过Rundeck对⽇常运维重复性操作，如批

量重启、批量发布、批量回滚等做了封装。但是⽇常⼤量⾮重复性的

运维操作，如定时⽇常运维设置修改、⽇常运维排错、⽇常服务器状

态巡查等，还是需要登录服务器执⾏运维命令，这也必然会降低我们

的运维效率。衡量⾃动化运维⼯作的情况就是登录服务器的次数。随

着运维⾃动化的发展，运维⾃动化从脚本及⼯具阶段演变⾄平台化阶

段，即运维⾃动化的终极⽬标就是不登录服务器，通过Web界⾯进⾏简

单设置操作就能完成所有⽇常运维管理⼯作。即我们需要在运维⾃动

化2.0基础之上进⼀步以平台界⾯“傻⽠式”操作来替代⽇常运维执⾏命

令、执⾏脚本/⼯具的⽅式，从⽽进⼀步提升运维效率。

随着云平台的普及，你会发现，云平台能对IT资源做⾃动化管

理，所以本⾝云平台就是⼀个⼤的运维⾃动化平台。也是因为云平台

的出现，我们的运维技术直接跳过⼈⼯阶段、脚本及⼯具阶段，到了

平台化这个阶段。在传统运维中（在IDC的硬件年代），也就是运维⾃

动化1.0及2.0阶段，运维⾃动化的核⼼更多的是通过CMDB（资源管理

系统），结合Ansible⾃动化⼯具，将服务器运维资源管理集中化、平

台化。⽽在云端，CMDB、资源管理早已被云⾃动化及平台化。甚⾄

传统运维做不到的硬件资源管理及维护，在云端都已不是问题。云平

台的出现，我称之为运维⾃动化3.0。图13-19所⽰为云平台中ECS产品

的运维⾃动化管理控制台界⾯。

图13-19 ECS运维⾃动化管理控制台界⾯

传统运维⾃动化的概念逐渐在弱化，⽽如今在云端很少还有⼈在

讲运维⾃动化，这是因为本⾝云平台已实现了平台化的运维⾃动化。

所以我们已将更多的精⼒由传统底层资源的运维管理转向业务层的运

维管理，这也是⼤家如今提到的更多的是DevOps的原因。

2.运维⾃动化4.0

运维⾃动化3.0从云平台层次解决了IT资源的管理、⾃动化运维等

问题，是真正意义上的平台化，⽤户不⽤熟悉及关⼼底层维护的技

术，只需在控制台⼀键式完成IT资源管理维护，它能满⾜80%的中⼩型

互联⽹需求。但由于每个公司的业务流程不同，我们的运维规范标准

也有所不同。⽐如，⾦融类业务的运维更多偏向安全性⽅⾯；电商类

业务的运维偏向快速扩容等资源管理⽅⾯；⽽政企类业务的运维更多

偏向以审批为导向的流程化管理⽅⾯。所以云平台通⽤的运维⾃动化

管理可能满⾜不了中⼤型公司对定制化的⾃动化诉求。好在云平台的

API开放让我们能通过代码去管理云资源，这使得我们能够⼆次开发适

合⾃⼰公司业务的运维⾃动化平台。甚⾄在做业务部署时，我们可以

不⽤仅仅局限于使⽤某个云⼚商平台进⾏部署，也就是说，我们可以

选择多个云⼚商做分布式架构，以保障业务的安全性及稳定性。由此

运维⾃动化从3.0演变⾄4.0版本，即跨云平台定制适合公司业务的运维

⾃动化平台。图13-20所⽰为驻云运维平台——运维⾃动化4.0的参考案

例。

图13-20 驻云运维平台

平台功能模块概要如下：

·账号管理：运维平台的登录，通过公司内部的LDAP集中进⾏⽤户

认证管理。

·客户管理：包含我们运维所有客户信息、运维档案信息，如我⽅

架构师、运维⼈员、销售⼈员、客户对接⼈员等，以及客户拜访记录

等。

·项⽬管理：项⽬总览、告警通知、接⼜管理、监控配置、堡垒机

配置、告警记录模块。

·资源管理：项⽬相关的云资源，通过API查询各个云平台的资源进

⾏汇总集中管理。

·系统管理：⽤户管理、分组管理、⾓⾊管理。

·配置管理：账户管理、堡垒机配置。

·任务管理：主要通过Ansible做任务下发及管理。

3.DevOps2.0

正如上⽂所述，云平台的普及，让我们把更多的精⼒由传统运维

的资源管理运维⾃动化转移到业务管理DevOps（持续集成/持续交付）

⾃动化上。即通过Jenkins⼀键式完成编译打包、部署上线，从⽽实现

业务的快速迭代及交付，这是DevOps的1.0阶段。随着业务的发展，业

务架构由传统的分布式架构演变成如今热门的微服务架构。采⽤微服

务架构，其实是业务层的解耦拆分，主要带来业务上的重组及快速迭

代等弹性优势。但随着微服务越来越多，维护的服务器也⽇益增加。

这给我们带来了极⼤的运维挑战，我们在以下⼏个⽅⾯的运维⼯作越

来越困难：

·CI/CD（可持续集成/可持续交付）的主要压⼒表现在可持续交付

上。虽然云平台的出现让我们资源的开通缩短⾄分钟级别。⼀个新环

境过来，或者业务压⼒增加，我们需要额外增加服务器资源，虽然通

过镜像开通ECS本⾝是分钟级别，也花费不了多少时间。但是业务的快

速更新迭代，使得打镜像、开机器的事情变成了重复性操作时，就会

显得效率较低。

·每台ECS上跑了多个微服务进程端⼜，这些微服务进程服务的管

理维护可能随着业务的微服务调度迁移等，使得运维侧的监控、维护

管理变得⾮常被动及烦琐。

·有些微服务造成系统的CPU、I/O压⼒很⼤。⽽部署另外⼀些微服

务的ECS，平时也基本上没有压⼒。在资源调⽤利⽤⽅⾯没有得到很好

的分配，存在很⼤的资源浪费问题。

虽然微服务解决了业务层架构的问题，但上述问题也暴露出，在

云端我们需要在运维侧有⼀套架构能⽀撑微服务。这⼀问题的核⼼其

实也是DevOps1.0的问题所在，即DevOps1.0主要通过Jenkins等技术解

决可持续集成⽅⾯的问题，但在可持续交付部署⽅⾯仍有不⾜。⼈们

常说Docker和微服务是天⽣⼀对，容器技术+微服务架构算是当今最为

热门的技术，也将领导技术领域下⼀个10年的发展。通过容器资源编

排技术Kuberneters+Jenkins+微服务架构，便成为如今的DevOps2.0体

系，如图13-21所⽰。

·CI/CD（可持续集成/可持续交付）上，代码提交到GitLab中，通

过Jenkins进⾏编译，然后打包成⼀个Docker镜像上传⾄私有镜像仓

库。线上的变更，只需要拉这个镜像即可；新增某个应⽤的台数时，

只需要定义YAML配置⽂件增加对应的副本即可。整个线上的更新迭

代，容器启动在秒级即可完成发布。

·容器Docker运⾏对应的微服务进程，对ECS没有依赖，我们定义

配置⽂件，不⽤关⼼对应的微服务跑在哪台ECS上，如果对应的Docker

异常，K8S资源编排会⾃动在不同的ECS节点进⾏冗余备份。

·容器Docker使⽤的资源，我们可以定义每个容器Docker具体要使

⽤多少CPU及内存，然后K8S资源编排⾃动调度对应的容器放在不同节

点运⾏，最⼤化地提升资源利⽤率。

·整个DevOps流程，也可以结合JIRA+Confluence做项⽬管理及知识

库管理。

图13-21 DevOps2.0阶段

所以引⼊容器资源编排的架构，让我们在CI/CD、运维管理、资源

管理上的效率都提升了⼀个档次。

云诀窍

GitLab+Jenkins+K8S+微服务是云端DevOps的最佳实践。

13.2.4 智能化阶段

智能运维，即当前如⽕如荼的⼈⼯智能和运维的结合——AIOps。

智能扩容、故障⾃愈、智能分析等进⼀步减少了⼈为参与，也进⼀步

提升了运维效率。AIOps的核⼼在于AI算法在运维领域的运⽤，但当前

在市⾯上类似的成熟解决⽅案及产品少之又少，还处于概念期。驻云

CloudCare体系，便是智能化阶段的典型代表，它是云计算时代的智能

诊断专家。通过将多年的云服务经验数字化，并结合基于⼈⼯智能的

诊断平台，CloudCare针对⽤户的IT资源进⾏检测与诊断，从云平台、

云主机到集群，为⽤户提供监控、安全、费⽤、优化等多⽅位的提

醒、告警及实施⽅案，帮助⽤户⼤幅地缩短IT系统的平均诊断时间，

提升IT系统管理效率，如图13-22所⽰。

图13-22 CloudCare 3.0整体系统架构

第三篇 云端安全篇

·第14章 云端安全⾯临的挑战和机遇

·第15章 云端⿊客常见攻击

·第16章 云端安全最佳防御⽅案

没有互联⽹安全，就没有国家安全。安全问题对互联⽹企业来说

是⾄关重要的。特别是业务量越⼤的应⽤，对安全问题就越敏感。随

着云计算的发展，云端⾯临着挑战也⾯临着机遇。在云端，如何通过

技术⼿段保障业务的安全性则是本篇的核⼼内容。通过常见⿊客攻击

案例，及结合云端最佳安全防御⽅案，本篇将带你⼀起⾛进⿊客攻防

的世界。

第14章 云端安全⾯临的挑战和机遇

安全是当前唯⼀不能被“云”化掉的特殊领域，安全带来的“⾼成

本”“灵活性”等问题冲击着云计算的核⼼优势。随着云计算的发展，安

全已成为云计算领域要解决的疑难问题。本章将针对我在云端安全领

域的⼀些所见、所想、所感进⾏介绍，希望本章的内容能对对云端安

全感兴趣的读者有所帮助和启发。

14.1 云端安全问题的现状

2013年，云在国内还不普及。作为阿⾥云架构师，那时候我和客

户经理⼀起去拜访国内某知名招聘⽹站企业，但当时并没有受到该企

业IT负责⼈的重视。那时候⾯对云，⼤多企业都持质疑的态度。当前

系统运⾏良好，为什么要上云？迁移成本、风险太⼤，所以⼤多数企

业不愿意上云，即使上了云，⼤多数企业也只是利⽤云运⾏官⽹等边

缘系统，很少有企业⼤规模地将主业务放在云端。

除了对云的陌⽣之外，被质疑最多的还是安全问题。受传统IDC

固化思想的影响，认为放在IDC机房的服务器看得见摸得着，能够把

控，让⼈觉得踏实，所以是安全的。⽽放在云端的数据，看不见摸不

着，也不知道存放在了哪⾥，让⼈感觉不踏实，安全风险很⾼。形成

这个冲击的核⼼原因，是云的模式和传统IDC机房上架的模式已经完

全不同。⾯对新事物，⼤家往往是陌⽣、恐惧，甚⾄抵触的。很多⼈

缺乏对云的了解，认为把应⽤及数据放在云端是种冒险⾏为。说起来

好笑，当初作为架构师，更多不是在给客户出技术⽅案，⽽是在跟客

户阐述及证明云是安全的，阿⾥云获得了哪些安全认证，云端有哪些

成功案例等。

随着云的普及，云技术更加成熟及稳定。如今如果有⼈还在对⽐

云技术的优势，企业还在问要不要上云，那必然会被互联⽹浪潮淘

汰，必然会被云时代淘汰。当前在云端实践中，更多的客户不是在问

使⽤云到底安不安全这类概念性的问题，⽽是针对通过云来部署业务

时遇到的实际安全问题进⾏咨询，想了解怎样利⽤云来保障业务安全

性。

云计算的确在成本、效率、灵活性等⽅⾯给我们带来了质的飞

跃，在云端安全问题上，很多⼈误以为使⽤了云，安全问题就得到了

控制或者解决。

在阿⾥云官⽹，我们看到图14-1所⽰的数据，可以看到，在云

端，每天要应对百亿次攻击。随着物联⽹、⼈⼯智能的技术发展，

在“万物互联”的未来，云会成为⽀撑这些技术发展的基础。但同时这

么庞⼤及复杂的体系，必然也会给云计算带来更加严峻的安全问题及

挑战。但值得欣慰的是，以前我们在IDC解决⼀个安全问题，要上架

对应安全设备、进⾏对应安全架构调整等，变更流程往往⼗分烦琐，

且效率低下。⽽如今依靠云本⾝的灵活性等技术特点，我们在云端可

选择对应的安全产品⼀键式解决安全类问题，也就是说，云让安全问

题更加快捷⾼效地被解决。例如，很多⽤户就是为了云盾免费的5G

DDoS流量防御⽽来，即买⼀台1核1GB的服务器，⼀个⽉的成本才50

元左右，但能免费获得5GB的DDoS流量防御，何乐⽽不为呢？

图14-1 阿⾥云某天防御数据⽰例

14.2 云端安全⾯临的三⼤挑战

互联⽹安全体制的不够健全、企业的安全技术体系不够完善、个

⼈的安全意识不够深化，导致互联⽹安全⼀直⾯临很⼤挑战。随着云

计算发展，互联⽹安全问题也⽇益严峻。

14.2.1 挑战⼀：安全⾏业状态不容乐观

2017年6⽉1号起施⾏的⽹络安全法，给安全⾏业带来了新契机。

在未来，除了云计算/⼤数据/⼈⼯智能等热门领域，还有⼀个领域会呈

现爆发式增长，那就是安全领域。虽然随着⽹络安全法的推出，安全

问题将逐步改善。但当前互联⽹安全⾏业的状态依旧不容乐观，主要

表现以下4个⽅⾯。

1.安全防御两极分化

具有安全能⼒的公司主要是BAT等⼀线互联⽹⼤公司，普通中⼩

型公司对安全的重视程度还不够，基本⽆安全防御能⼒。⽽中⼤型业

务，随着业务规模越来越⼤，⾯临的安全问题也会越来越严重，越来

越敏感。相反，那些中⼩型业务，由于其业务量不多，可能并不会被

⿊客注意到。所以这就直接导致了⼀个认识上的误区，即没有相关安

全事故、没有直接损失，就表⽰这⽅⾯没问题、很安全，如图14-2所

⽰。

图14-2 互联⽹企业安全防御两极分化

2.互联⽹安全意识堪忧

据《中国互联⽹络发展状况统计报告》统计显⽰，截⾄2018年6

⽉，中国⽹民规模为8.02亿。其中83%的⽹民采⽤弱⼜令，82%的⽹民

不注意定期更换密码，76%的⽹民存在多账户使⽤同⼀密码的问题。

最⼤的安全问题，并不是⿊客有多厉害，⽽是我们的安全意识低

下。

例如，总有⼈把密码设置为123456、⾃⼰的⽣⽇、⾃⼰的⼿机号

等，总有⼈把所有服务器的密码都设置为同⼀个，总有⼈把密码放在

Excel/Word/邮件中传送。

例如，很多⼈不太明⽩，为什么⾃⼰互联⽹上⾯的所有账号及密

码都有可能被窃取。随着互联⽹上的系统越来越多，很多⼈为了⽅

便，把所有系统的账户名、密码都设置为同⼀个，⽐如，淘宝账号、

微博、QQ密码等。这样⼀来，⿊客只需要简单地破解你⼀处的密码，

再⽤这个账号及密码到其他系统试⼀试就知道能不能登录了。

明明系统安全做得⾜够好了，为什么还是会被⼊侵？事实上，总

有⼈把很多系统部署在⼀起或者同⼀局域⽹内，⿊客利⽤“旁注”的攻

击⼿段，只需要攻击“弱⼩”的那个系统，以此为突破⼜，再通过“旁

注”⼊侵另外的系统即可。

3.安全产品的使⽤问题

最⼤的安全问题是不懂得如何使⽤武器反抗。现在云端有⼆三⼗

款安全产品，基本上能解决企业⾯临的所有安全问题。但是这⾥不仅

要让⼤家有⾜够的安全意识，还要求⼤家把这⼆三⼗款安全产品和其

他⼀两百款云产品结合起来运⽤，并解决对应的安全隐患及安全问

题。这已经是个⾮常专业的要求了，的确有点为难⼤家。更有甚者不

会使⽤安全产品便说云不安全。⽐如我之前的⼀个客户，做传统的在

线直播⼩⽹站，使⽤IDC的时候⽹站经常被⿊客攻击，从⽽瘫痪了。后

来⾃⼰迁移到了阿⾥云，问题还是没有得到解决，又被迫迁回了IDC。

后来我们接⼿解决了这个问题，再次迁到阿⾥云，只不过这次我们在

架构上进⾏了简单的调整，采⽤的是SLB+ECS的形式，并对系统进⾏

了安全加固及优化。另外，在云盾进⾏了更加细粒度的阈值触发调

整，不但解决了安全问题，还对ECS配置进⾏了优化调整（把固定带宽

变更为按量带宽），使得每个⽉能节省原来⼀半的成本费⽤。

4.安全⼈才匮乏

随着互联⽹的发展，⽹络安全形势⽇益严峻，对⽹络安全⽅⾯的

⼈才的需求也是越来越多。据相关资料显⽰，近年我国⾼校教育培养

的信息安全专业⼈才仅3万余⼈，⽽⽹络安全⼈才总需求量则超过了70

万⼈，缺⼜⾼达95%。这⼀⽅⾯是挑战，但从另⼀⽅⾯来看也是机遇。

在企业中，安全类的技术岗位⼈员招聘是最难的，甚⾄招聘⼀两年也

招不到合适的⼈员，⼤多数⼈员都满⾜不了企业对安全技能的要求。

其实这⽅⾯的问题就是前⾯所说的“安全防御两极分化”直接导致的，

可以说，整个市场的安全⼈员基本都集中在⼤型公司中。中⼩型企业

安全⼈员的招聘，⼀直是瓶颈。后来我们甚⾄放弃招聘，直接在从内

部向安全⽅向培养相关⼈才，这成为我们招聘安全相关⼈才的主要渠

道。

14.2.2 挑战⼆：云端安全环境复杂化的挑战

在安全领域，越简单的东西，安全风险越低；越复杂的东西，安

全风险越⾼。打个⽐⽅，⼀个简单的HTML官⽹，安全风险肯定很低。

对于HTML的静态展⽰页⾯，也谈不上⼊侵。相对来说，⼀个基于PHP

的电商，其安全风险肯定会⾼很多。先不说PHP代码是否存在很多安全

问题，PHP本⾝的安全漏洞就不少。越复杂的东西，涉及的技术也就越

多，⾃然，存在的安全风险和问题就更多了。

我们先来看看，云端⼀般都运⾏些什么业务，图14-3所⽰的就是云

端运⾏的常见业务。

图14-3 互联⽹业务概览

⽽互联⽹使⽤的热门操作系统就是云端要使⽤的操作系统，如图

14-4所⽰。

图14-4 云端操作系统概览

互联⽹使⽤的热门的开源技术就是云端要使⽤的技术，如表14-1所

⽰。

表14-1 云端热门技术概览

正如前⾯所说的，在安全领域，越简单的东西，安全风险越低；

越复杂的东西，安全风险越⾼。在云端，业务环境、系统环境、技术

环境，再加上本⾝云产品平台环境的多元化，会让安全场景变得复

杂，挑战加剧。未来，随着物联⽹、⼈⼯智能的发展，通过云实现

了“万物互联”，互联⽹环境也会进⼀步变得庞⼤且更加复杂，安全上

也将⾯临更⼤的挑战。

14.2.3 挑战三：安全对云优势的冲击

为什么说安全是当前唯⼀不能被“云”化掉的特殊领域？我们先来

看看云计算的优势特点，如图14-5所⽰。

可靠性、低成本、弹性扩展是云计算的核⼼优势，安全对云计算

的核⼼优势提出了很⼤挑战及冲击。可靠性⽅⾯，使⽤分布式的结构

⽐使⽤本地计算机更加可靠，它以某种⽅式保障了数据的安全性。下

⾯我们再来看看弹性扩展⽅⾯，如图14-6所⽰。

图14-5 云计算的三⼤优势

图14-6 安全和灵活的平衡

弹性扩展的优势，致使云端的应⽤进⾏资源扩展时更加快捷、灵

活，但同时也对安全提出了更为严峻的挑战，⾃古快捷和安全就是互

斥的，正所谓“鱼和熊掌不可兼得”，弹性扩展带来的⾃动化是把“双刃

剑”：⽅便部署，但风险较⾼。⽐如AWS⼀个字母造成了半个互联⽹瘫

痪，GitHub⼀条命令删除了整个数据库等安全事件，其背后都是灵活

性导致的安全问题，可见，弹性扩展所带来的安全风险相当严峻。

安全成本⼀直是个严峻的挑战。安全领域会涉及复杂的⾼端技

术，这也决定了安全领域攻防的成本同样⾼昂（这也是⿊⾊安全产业

链暴利的核⼼原因），如图14-7所⽰。

图14-7 阿⾥云⾼防IP防御弹性防护费⽤

云端有个⼩型旅游⽹站在每年的旅游⾼峰期都会遭遇别⼈的恶意

流量攻击，瞬时流量⾼达100GB。如果采⽤⾼防类安全产品，每天的

费⽤要⼀万多元。从客户的⾓度来说，这么⾼昂的防御成本，如若被

攻击⼀个⽉，那企业就要倒闭了。

再如，安全渗透测试的相应成本也不低。⼀次安全渗透测试⼀般

最低报价10万元起，单个⾼危漏洞报警5万元起。由于攻防成本⾼，导

致在安全⽅⾯投⼊的成本⼀直居⾼不下。⽽低成本是云平台的核⼼优

势，但云计算似乎没有将安全完全“云”化掉。

14.3 云端安全带来的两⼤机遇

所谓“乱世出英雄”，⾯临严峻挑战的同时也伴随着新的机遇。在

新的IT体系下，云计算、⼤数据将成为安全体系的基础核⼼保障。政

策驱动叠加，也将使得安全⾏业迎来爆发。

14.3.1 机遇⼀：云计算、⼤数据将成为安全体系的基础核⼼

保障

1.基础安全保障解决了⼤多数传统中⼩型安全问题

在传统模式下，IDC机房经常被⿊客攻击。⼀些菜鸟⿊客的随意攻

击，就可能导致⽹站⽆法访问。但云平台提供的基础安全防御，如云

盾的5GB免费DDoS基础防御等，解决了⼤多数传统中⼩型企业在传统

IDC模式下⾯临的安全问题。阿⾥云DDoS防护设置如图14-8所⽰。

图14-8 阿⾥云DDoS防护设置

2.利⽤⼤数据分析的优势发现潜在的⼊侵和⾼隐蔽性攻击威胁

云计算和⼤数据相辅相成，可以通过⼤数据的分析发现潜在⼊侵

和⾼隐蔽性的攻击威胁。⽽在云端，态势感知便是这⽅⾯的⼀个重要

的安全产品服务。态势感知结合了阿⾥⾃主研发的⼤数据和机器学习

算法，通过多引擎查杀帮助⽤户实时全⾯了解并有效处理服务器的安

全隐患，实现了对云上资产的集中安全管理，如图14-9所⽰。

图14-9 阿⾥云态势感知功能截图

3.推进云计算进⼀步发展

安全领域的挑战将推进云计算进⼀步成熟，促使其发挥真正的价

值和优势。云计算技术领域⽅⾯的发展，也会逐步解决安全⽅⾯⾼成

本等疑难问题，如图14-10所⽰。

阿⾥云之前推出的⼀款⽹络安全产品，即通过⼤量ECS低成本的节

点来抵抗DDoS的攻击流量，这是典型的通过技术解决安全⽅⾯⾼成本

问题的案例。

图14-10 阿⾥云安全⽹络截图

14.3.2 机遇⼆：政策驱动叠加，使得⾏业将迎来爆发

学校有关互联安全教育的不充分是当前⼈们互联⽹安全意识低下

的本质原因。市⾯上安全有关的培训也较少。

科技便是未来，互联⽹安全的重要性⽏庸置疑。没有互联⽹安

全，就没有国家安全。但中国互联⽹从1998年创建开始，到现在20

年，其安全还处于前期准备阶段。⽽2017年6⽉1⽇起施⾏的⽹络安全

法是⽹络安全的重要⾥程碑。这意味着⽹络安全将变得有法可循，意

味着⽹络的运营主体如果对安全不重视甚⾄出现影响较⼤的事故，将

会受到法律的处罚。⽽以前往往是，这样的事情发⽣了就过去了，责

任⽅不痛不痒。政策驱动叠加，必然会使得教育体系变⾰，可见，安

全⾏业也将迎来爆发式发展。

第15章 云端⿊客常见攻击

所谓攻防，只有知道了攻击原理，才能知道怎么防御。本章将带

领读者⾛⼊⿊客的世界，揭开⿊客的神秘⾯纱！

15.1 什么是⿊客

原本⿊客是指醉⼼于研究计算机技术和编程，⽔平超群的电脑⾼

⼿，但我们经常看到媒体报道⿊客盗取数据、⿊客攻击事件等负⾯新

闻，所以现在⿊客已被⽤来泛指那些专门利⽤电脑搞破坏或恶作剧的

⼈。

图15-1 ⿊客的⾓⾊分类

随着互联⽹安全的发展，每个阶段下的安全背景对⿊客的⾓⾊定

义也会有所不同，如图15-1所⽰。

综合来说，如今⼤家⼜中的⿊客有“好⼈”和“坏⼈”之分，当前圈

中称之为“⽩帽⼦”和“⿊帽⼦”。⽩帽⼦描述的是正⾯的⿊客，他可以

识别计算机系统或⽹络系统中的安全漏洞，但并不会恶意去利⽤，⽽

是公布其漏洞。⿊帽⼦，顾名思义，与⽩帽⼦相反，就是⼈们常说

的“骇客”，他们利⽤安全漏洞来搞破坏。在“好⼈”的⾓⾊中，当前也

称⿊客为“极客”，相信圈内⼈⼠对这个称呼也⽐较熟知。极客是美国

俚语“geek”的⾳译。随着互联⽹⽂化的兴起，这个词含有智⼒超群和

努⼒的语意，又被⽤于形容对计算机和⽹络技术有狂热兴趣并投⼊⼤

量实践钻研的⼈。总之，是⼀群以创新、技术和时尚为⽣命意义的

⼈，这群⼈不分性别，不分年龄，共同战⽃在新经济、尖端技术和世

界时尚风潮的前线，共同为新时代的计算机和⽹络技术做出⾃⼰的贡

献。

15.2 ⿊客⼊侵的途径：漏洞

很多⼈觉得⿊客神秘的⼀个核⼼原因就是不知道⿊客是怎么⼊侵

别⼈的，所以内⼼充满好奇和疑惑。⼊侵者只要找到复杂的计算机⽹

络中的⼀个薄弱点，就能轻⽽易举地闯⼊系统。⽽这个薄弱点就是计

算机中的漏洞，这便是⿊客⼊侵的途径。我在⼤学考软件测试⼯程师

时，就觉得软件测试的专业知识能帮助我发现这些安全漏洞。虽然软

件测试和⿊客安全渗透的本质都是找BUG，都是找漏洞，但是做的事

情完全不是⼀个⽅向。

我在最开始接触计算机的时候，⽤的是Windows 98操作系统，那

时候⽤的输⼊法是智能ABC。智能ABC有⼀个隐藏的安全漏洞：切换

到“智能ABC”后，依次按“V+↑+Del+Enter”键（引号和加号不要输

⼊），就会发现当前被选中的应⽤程序出错了，只有点击“确定”按钮

这⼀个选择，这个应⽤程序才关闭。这是我最早接触到的安全漏洞。

当前⼈们的互联⽹安全意识普遍低下，中国8.02亿⽹民，83%的⽹

民（2018年6⽉《中国互联⽹络发展状况统计报告》统计显⽰）采⽤弱

⼜令，82%的⽹民不注意定期更换密码，76%的⽹民存在多账户使⽤同

⼀密码的问题。密码漏洞⽏庸置疑已成为互联⽹中最⼤的安全漏洞，

随着互联⽹的发展，⽹民在各种平台中的账号和密码越来越多。为了

⽅便，总把密码设置成⼿机号、⽣⽇及简单的弱⼜令密码，总把各个

平台的⽤户名和密码都设置为同⼀个等。⽐如之前CSDN数据泄露的安

全问题，别⼈⽤该平台的⽤户名和密码去微博、淘宝等其他系统试⼀

下，基本上⾄少70%的账号能直接登录。接下来让我们看看世界最弱密

码排⾏榜TOP10，如图15-2所⽰。

图15-2 世界最弱密码排⾏榜TOP10

除了密码漏洞外，还有诸如Windows3389漏洞、管理员默认密码漏

洞、⽹站SQL注⼊漏洞、后台万能密码漏洞（‘or’=‘or’）等都是曾经热

门的⼊侵漏洞。另外，⼤家所熟知的Windows补丁，每次Windows的补

丁发布，对很多⿊客来说可谓是“福利”，这相当于告诉⿊客Windows有

哪些⽅⾯的安全漏洞。对应的安全漏洞，便是⿊客⼊侵的途径。

15.3 ⿊客⼊侵流程

漏洞是奠基⼊侵的基础，但⿊客真正⼊侵的流程没这么简单，是

⼀个漫长的研究及分析过程。⿊客常见⼊侵的分为以下五个步骤。

第⼀步：信息收集

信息收集⼀般是耗费时间最长的阶段，⿊客⼊侵前通常会通过扫

描⼯具或社会⼯程学来收集信息。

第⼆步：漏洞筛选

⼀旦⿊客对所要⼊侵的⽬标掌握了⾜够的信息，接下来便是对信

息做分析了，以寻找潜在的漏洞。常见的安全漏洞可能包括密码漏

洞、操作系统相关漏洞、中间件程序相关漏洞、开放端⼜相关漏洞、

数据传送相关漏洞、局域⽹/⼴域⽹相关设备漏洞等。

第三步：开始⼊侵

在收集到对应的漏洞后，在⿊客⼯具的辅助下，便能完成⼊侵，

如图15-3所⽰为⿊客常⽤的⼯具。

图15-3 常⽤⿊客⼯具截图

第四步：放置后门

完成⼊侵后⿊客⼀般会放置后门，常见做法就是种⽊马，或者打

开对应的管理员权限等，为今后可能的访问留下控制权限。

第五步：清理痕迹

在实现⼊侵攻击的⽬标后，最后⼀步便是扫尾。清理⼊侵的痕

迹，常见做法是，清理系统访问⽇志等，隐藏⾃⼰的访问；或者通过

VPN、跳板机的⽅式，隐藏真实的IP。

15.4 ⿊客常见系统层攻击

常见的⿊客攻击主要分为3类：系统层攻击、应⽤层攻击、⽹络层

攻击。结合前⾯介绍的内容可知，漏洞是⿊客⼊侵的途径。所以这三

⼤类攻击，都是针对不同层次级别的漏洞进⾏的常见攻击。

⾸先我们来看看系统层的攻击，系统层的攻击，即针对操作系统

OS级别的攻击，通过找到操作系统的漏洞来达到⼊侵的效果，⽽⽊马

和病毒便是系统层攻击最核⼼的两种⼿段。很多⼈把⽊马和病毒混为

⼀谈，把⽊马也称为病毒。⽊马本质上也是恶意程序，但是从功能及

危害性等⽅⾯来说，它们是有着很⼤区别的。

病毒，顾名思义，其主要特点是以破坏为主，是计算机系统中的

⼀种恶意程序。计算机中的病毒和医学⾓度的病毒本质上是⼀样的，

⼈中了病毒，其⾝体机能⽇常运作就处于⾮正常的状态。⽽计算机中

病毒后，同样表现出⽇常运作及⼯作的异常状态。⽐如之前传播范围

极⼴的勒索病毒“永恒之蓝”，还有之前“⼤名⿍⿍”的熊猫烧⾹病毒，都

是病毒⾥⾯的经典代表之作。勒索病毒主要利⽤编号为CVE-2017-0144

的系统漏洞，该漏洞通过SMB协议的SMB_COM_TRANSACTION2命

令触发。⽽熊猫烧⾹主要利⽤编号为MS06-014的系统漏洞，并且会利

⽤IE浏览器的漏洞进⾏⽹络攻击。

⽽⽊马，又称之为后门。⽊马和病毒在功能场景上有着本质上的

区别，病毒的“性格”特点主要以嚣张、引⼈注⽬地破坏为主，⽽⽊马

的“性格”特点主要以低调不被发现地窃取为主，即⽊马主要是为了窃

取⽬标的信息资源。

并且⽊马有个专业的名词，叫特洛伊⽊马，来源于希腊传说，希

腊联军久攻特洛伊不下，于是假装撤退，留下⼀个巨⼤的⽊马。特洛

伊守军以为是战利品，于是把⽊马运进城中，夜深⼈静，藏在⽊马中

的希腊⼠兵打开城门，致使特洛伊被攻陷。如今特洛伊⽊马在⿊客攻

击中⾮常常见，把⼀个窃取信息的恶意程序伪装成⼀张唯美的图⽚、

⼀款有趣的游戏、⼀段有意思的⼩视频，甚⾄是系统⽂件等，诱使⽤

户将其打开，然后在后台偷偷安装窃取信息的恶意程序。由此可见，

这款恶意程序窃取信息的⼿法和希腊联军攻击特洛伊的⼿法是⼀样

的，这种窃取信息的恶意程序就称为“特洛伊⽊马”，简称“⽊马”。

在⽊马的世界，不仅有上⾯提到的系统级⽊马，还有⽹马、⼤

马、⼩马。根据常见⽊马的应⽤攻击场景，我们可以再进⼀步将其细

分为以下4类。

（1）⽊马

⼤家常说的⽊马就是指这类操作系统的后门⽊马。前⾯跟⼤家介

绍的⽊马原理所描述的就是这类⽊马。Windows98系统曾惊现逆天后

门，Windows⾃带的⽊马门事件也让它的安全性受到了很⼤质疑，当然

如今早已不存在这个问题了。Windows系统的⽊马，就是exe可执⾏的

恶意程序。Linux系统的⽊马就是⼆进制可执⾏的恶意程序。Android系

统的⽊马当然就是apk可安装执⾏的程序了。

（2）⽹马

很多⼈把⽹马直接叫WebShell，这其实是不准确的。⽹马是⽊马和

⽹页的结合物，只不过通过⽹站挂载⽊马。我们访问⽹站，⽹站就会

偷偷把挂载的⽊马植⼊访问者系统中运⾏。其实⽹马本质上还是系统

⽊马，只不过它是利⽤常⽤的Web站点来传播⽽已。

（3）⼩马

说到⼩马、⼤马，这就跟系统级的⽊马有着本质的区别了。⼩马

和⼤马是指⼤家常说的WebShell，即⽤ASP、PHP、JSP写的⽹页后门

程序，属于典型的B/S软件架构应⽤。⼩马的源⽂件较⼩，容易隐藏，

不易被发现，其唯⼀的功能是上传⼤马。

（4）⼤马

⼤马源⽂件较⼤，不易隐藏，但功能较全⾯，如图15-4所⽰。

图15-4 JSP⽊马源码内容截图

这个JSP⽂件有三千多⾏代码，是⽤JSP实现的⼀段窃取信息的后

门程序，其他常⽤的WebShell⽊马如图15-5所⽰。

图15-5 常见WebShell

云诀窍

⼤家经常说被挂马，根据以上⽊马的分类，有可能是指被挂系统

级别的⽊马，也有可能是指被挂WebShell⽹页⽊马，其本质上是不同

的。

15.5 ⿊客常见应⽤层攻击

应⽤层攻击，即应⽤代码层的攻击。出现这类攻击的核⼼原因就

是编写的代码存在安全问题。这也是有的程序员⼯资才⼏千元，⽽有

的程序员⼯资⾼达⼏万元的原因。不同的程序员写出的代码在效率、

质量、安全性等⽅⾯是不能相提并论的。那⼤家写的代码带来的安全

问题，会带来的常见应⽤层攻击如下：

·SQL注⼊；

·跨站脚本攻击；

·密码暴⼒破解；

·恶意注册、刷单等；

·WebShell：⼩马、⼤马。

应⽤层常见攻击排⾏最前⾯的，当属SQL注⼊攻击。所谓SQL注

⼊，就是通过把SQL命令插⼊Web表单提交或输⼊域名、页⾯请求的

查询字符串，最终达到欺骗服务器执⾏恶意的SQL命令。具体来说，

它是利⽤现有应⽤程序，将（恶意的）SQL命令注⼊后台数据库，它

可以通过在Web表单中输⼊（恶意）SQL语句得到⼀个存在安全漏洞

的⽹站上的数据库，⽽不是按照设计者意图去执⾏SQL语句。⽐如先

前的很多影视⽹站泄露VIP会员密码⼤多就是通过Web表单递交查询字

符暴露出的，这类表单特别容易受到SQL注⼊式攻击。

SQL注⼊的问题主要是前端客户端输⼊的信息没有经过严格过

滤，导致我们直接输⼊SQL语句注⼊，从⽽从数据库获取数据。⽽跨

站脚本攻击的原理和SQL注⼊差不多，主要在前端页⾯对客户输⼊的

信息内容没有经过严格过滤，⽐如许多流⾏的留⾔本和论坛程序允许

⽤户发表包含HTML和JavaScript的帖⼦。假设⽤户甲发表了⼀篇包含

恶意脚本的帖⼦，那么⽤户⼄在浏览这篇帖⼦时，恶意脚本就会执

⾏，从⽽盗取⽤户⼄的Session信息等。总的来说，永远不要信任⽤户

的输⼊。在客户端和服务端严格控制输⼊信息的内容格式，是有效避

免被SQL注⼊和跨站脚本攻击的核⼼⽅法。

15.6 ⿊客常见⽹络层攻击

分布式拒绝服务（Distributed Denial of Service，DDoS）是当今⽹

络上危害最⼤的⿊客攻击，能让⽹络、系统业务、服务器全部瘫痪，

⽆法提供正常服务。DDoS攻击的前⾝是DoS攻击，在以前计算机性能

配置、⽹络带宽很低的时代，都是通过单对单地刷流量来攻击⽬标。

假如⽬标服务器是2核4GB 5Mbps的配置，我⽤4核8GB 10Mbps的客户

端对⽬标服务器端刷更多的请求流量，致使⽬标服务器因为请求压⼒

过⼤⽽⽆法正常对外提供服务。

随着Web2.0的迅速发展，随着云计算/⼤数据时代的到来，⼀个业

务往往是通过分布式架构来对外提供服务的，即前端通过负载均衡，

将业务请求转发给后端不同的服务器来处理,⽽不是单靠某台服务器来

满⾜庞⼤的业务请求。如今，BAT公司（百度、阿⾥、腾讯）服务器

的规模量级在20万台到50万台之间，⽽⾕歌服务器的规模量级在2003

年就达到了百万台级别。如今技术架构快速发展，单纯的DoS攻击早已

打不垮⽬标。这时，⿊客会将更多的客户端联合起来⼀起攻击⽬标

端，这也就演变成了如今的DDoS攻击。DDoS攻击的原理架构如图15-

16所⽰。

图15-6 DDoS攻击架构图

⿊客通过控制⼤量的客户端（“⾁鸡”，⼀般通过⽊马⼊侵控制）

向⽬标服务器发送⼤量⽹络请求包，导致⽬标服务器⽹络堵塞、服务

器性能飙升，不能对外正常提供服务。

在前⾯也跟⼤家介绍过，⿊客攻击的途径是漏洞。能发起DDoS攻

击的主要原因也是TCP三次协议的漏洞。DDoS攻击被誉为当前安全领

域及⿊客界唯⼀⽆法真正意义上解决的攻击，除⾮更改TCP三次握⼿的

协议，才能治根防御。

云诀窍

当前防御DDoS，都是侧⾯通过抗流量的⾼性能的硬件防⽕墙进⾏

流量清洗，这是唯⼀有效的措施。我有个客户曾在云端遇到瞬时

50Gbps流量的DDoS攻击，有⼀家供应商给他的解决⽅案是在服务器上

安装其提供的安全防御软件，每个⽉付费⼀万元。50Gbps的瞬时流

量，即服务器要处理50Gbps的瞬时TCP请求，这⽆疑远远超过服务器

的最⼤处理极限。安装防御软件可能会进⼀步消耗服务器性能，使得

问题加剧，DDoS攻击⽆疑是软件层⾯⽆法防御住的。

DDoS的攻击原理如图15-7所⽰。

图15-7 TCP三次握⼿原理

SYN Flood攻击是DDoS攻击中应⽤最为⼴泛、最为经典的攻击，

即客户端向服务器发送⼤量的SYN请求，⽽服务器端要处理及响应这

些请求就会导致服务器TCP连接资源耗尽，⽆法响应正常的TCP连接请

求。值得注意的是，DDoS攻击只是⿊客⽹络攻击的⼀种统称。⽽实际

上常见的DDoS攻击分为以下⼏种类型：

·SYN Flood

·UDP Flood

·ACK Flood

·ICMP Flood

云诀窍

值得注意的是，很多⼈把CC（Challenge Collapsar）攻击也纳⼊

DDoS攻击。虽然从攻击形式及攻击结果来看，CC攻击也是通过刷流量

造成⽬标业务系统⽆法对外提供服务，符合DDoS拒绝服务的特性。但

是从攻击原理来看，CC攻击是OSI七层模型中七层（HTTP层）的攻

击，是通过向⽬标刷URL的流量攻击导致⽬标⽆法正常对外提供服

务。⽽DDoS核⼼攻击原理主要是针对TCP三次握⼿，即属于OSI七层

模型中四层（TCP层）的攻击。因为原理不同，它们在云端的防御⼿段

也是完全不同的。CC攻击需要通过WAF应⽤防⽕墙进⾏防御，⽽

DDoS攻击需要通过⾼防IP进⾏防御。

第16章 云端安全最佳防御⽅案

在云端安全的实践中，我们发现传统的中⼩型企业，由于业务等

因素导致对安全问题的关注度不够，他们更注重对具体安全事件的问

题解决。⽐如，突然有⼀天⽹站被挂载⽊马，或者突然被⼈攻击等。

⽽中⼤型企业，随着业务的发展，对安全性越来越重视及敏感，所以

他们更多考虑的是体系化安全解决⽅案，⽽不是单纯局限在具体的单

个安全事件的处理上。根据当前⼤家对安全领域谈论的话题，以及相

关的分享和交流来看，⽬前云端安全总体分为两⼤类，⼀类偏向于安

全等级保护、安全合规流程等⽅⾯，政府类、⾦融类客户对这⽅⾯要

求较⾼。另⼀类则偏向于⿊客攻击的安全风险。但很少见到基于⿊客

安全攻击事件⽽设计的整套安全技术体系化的解决⽅案。⽽对于互联

⽹企业来说，这正是他们所缺少的解决⽅案。

关于安全技术体系的解决⽅案，例如，客户遇到DDoS攻击，我们

都知道要⽤⾼防的安全产品。问题是虽然花费⾼额成本买了⾼防类安

全产品，但是安全问题并不能真正有效地解决，到最后很可能被客

户“吊打”。我们没办法通过单⼀的安全类产品、单⼀的技术⼿段，来

解决安全⾯临的挑战⽽是要站在安全⾓度、架构⾓度、运维⾓度、业

务代码⾓度，甚⾄是站在⼀个更⾼的维度，通过安全技术体系架构来

真正解决安全问题。上⼀章主要介绍了⿊客如何攻击安全系统，本章

会围绕云端安全产品、云端安全架构、云端安全运维体系三个核⼼⽅

⾯，结合⼤量云端⽤户遇到的安全问题及场景，跟⼤家分享云端安全

最佳防御实践经验。

16.1 云端常见⿊客攻击的防御

云盾安全产品，是应对⿊客常见攻击最直接有效的解决办法，是

云端的安全保障第⼀道防线，更是解决安全问题的默认选择。

16.1.1 四款热门的云端安全产品

截⽌到2019年3⽉，阿⾥云官⽅推出了以下22款安全产品及服务。

·安全公告和技术

·DDoS防护

·Web应⽤防⽕墙（WAF）

·游戏盾

·安骑⼠

·态势感知

·SSL证书

·内容安全

·先知（安全众测）

·安全管家

·堡垒机

·加密服务

·数据库审计

·云防⽕墙

·实⼈认证

·数据风控

·⽹站威胁扫描系统

·爬⾍风险管理

·风险识别

·敏感数据保护

·云防⽕墙（旧版）

·⾦融级实⼈认证

对于安全产品来说，⼀是⼤部分⼈不知道它能⼲什么，有哪些功

能服务；⼆是这类产品跟⾃⾝业务联系不⼤。在云端主要有以下四款

安全产品，其基本上已成为互联⽹企业在云端最核⼼的安全产品保

障。

·系统层：安骑⼠

·应⽤层：Web应⽤防⽕墙

·⽹络层：DDoS防护

·检测及分析：态势感知

接下来主要围绕这四款核⼼安全产品，介绍怎么应对⿊客常见攻

击。相应的安全产品说明，主要参考阿⾥云产品帮助⽂档，更多配置

明细及介绍可参加官⽅产品⼿册。

1.安骑⼠对系统层攻击的防御

系统层的防御本质就是如何防御⽊马及病毒。⼀⽅⾯，及时给系

统打补丁，避免被⽊马、病毒⼊侵的可能性。另外⼀⽅⾯，给系统安

装杀毒软件，及时查杀⽊马及病毒。这些是防御⿊客常见系统层攻击

的必要⼿段。

对于个⼈⽤户，⼀般选择360安全卫⼠（只能查杀⽊马）、360杀

毒（⽊马和病毒都能查杀）、腾讯电脑管家，因为它们使⽤起来⽅便

快捷。如果想⽤更专业的杀毒软件，可以选择被誉为最强的杀毒软件

的赛门铁克和卡巴斯基，它们基本上可以让⽊马和病毒⽆处遁形。

对于企业级⽤户，不可能还在服务器上安装360安全卫⼠。曾经见

过客户⼲过这样的事情，这让企业级的系统安全防御变得⾮常业余。

因为个⼈⽤户的系统环境和企业级系统环境的应⽤场景是不太⼀样

的，个⼈⽤户的系统环境偏向⽇常娱乐、办公、⼯作，所⾯对的是个

⼈操作系统、娱乐、办公等软件环境。⽽企业⽤户的系统环境偏向企

业级应⽤，所⾯对的是企业级操作系统、企业级软件环境。⽤在个⼈

⽤户系统环境下的防御⼯具去防御企业级系统环境，有点⽜头不对马

嘴的感觉。所以对于企业级系统层攻击的防御，我们要⽤企业级的杀

毒软件。在云端，我们又要选择怎样的杀毒软件呢？安骑⼠便是针对

系统级攻击⾮常重要的防御⽅法。

阿⾥云安骑⼠是⼀款经受百万级主机稳定性考验的主机安全加固

产品，⽀持⾃动化实时⼊侵威胁检测、病毒查杀（包含⽊马）、漏洞

智能修复、基线⼀键检查、⽹页防篡改等功能，是构建主机安全防线

的统⼀管理平台。安骑⼠的架构如图16-1所⽰。

图16-1 安骑⼠架构图

正所谓道⾼⼀尺魔⾼⼀丈，攻和防永远对⽴。能否⼊侵，要看⼊

侵⼿段是否⾼超。能否防御，要看防御技术是否过硬。阿⾥云安骑⼠

集⽹络、主机、云产品安全于⼀体，对云上系统的所有安全进⾏风险

监控。关于安骑⼠的使⽤也是⾮常简单的，只需为想要防护的服务器

安装安骑⼠Agent即可。具体安装及使⽤⾮常简单，这⾥就不做介绍，

详细可参考阿⾥云帮助⽂档。安骑⼠有以下六⼤优势以防御系统层常

见⿊客攻击。

（1）轻量级

经受百万级Windows、Linux主机稳定性验证，对业务影响⼩，资

源消耗不超过10%CPU、50MB内存。

（2）便捷的统⼀安全管控

⼀键开通，即开即⽤。服务器上⽆软件操作界⾯，所有的数据展

⽰和操作均在云盾安骑⼠控制台中完成，天然⽀持批量管理。

（3）精准防御

多病毒检测引擎结合阿⾥云多年安全经验，⽀持主流病毒⾃动查

杀。

（4）安全闭环

既可检测安全问题和威胁，又能解决安全问题。⽀持漏洞⼀键修

复、病毒⼀键查杀和基线⼀键检测；⽀持⽹页防篡改。

（5）多引擎实时检测

实时全量采集数据，采⽤多病毒检测引擎、机器学习算法和

150+关联检测模型来提升主机⼊侵检测效率。

（6）⼤数据防御

每天拦截攻击数⾼达亿次，全⽹最⼤病毒库（恶意攻击源库、恶

意⽂件库、漏洞补丁库），防御模型能够精准快速地识别匹配恶意攻

击源、恶意⽂件及最新漏洞。

2.WAF对应⽤层攻击的防御

对于应⽤层的攻击，主要是因为代码存在安全问题，成为⿊客⼊

侵的漏洞。在云端，最为有效的解决办法就是使⽤云盾Web应⽤防⽕墙

（Web Application Firewall，WAF）。

WAF基于云安全⼤数据能⼒，⽤于防御SQL注⼊、XSS跨站脚本、

常见Web服务器插件漏洞、⽊马上传、⾮授权核⼼资源访问等OWASP

常见攻击，并过滤海量恶意CC攻击，避免⽹站资产数据泄露，保障⽹

站的安全与可⽤性。值得注意的是，WAF主要应对各类Web应⽤攻

击，确保⽹站的Web安全与可⽤性。仅⽀持对⽹站的HTTP、

HTTPS（⾼级版及以上）流量进⾏Web安全防护。

WAF的原理主要是通过拦截⿊客攻击请求，来达到防御的效果，

并不能真正解决底层代码存在的安全漏洞。WAF主要可以帮助解决以

下问题：

·防数据泄密，避免因⿊客的注⼊⼊侵攻击，导致⽹站核⼼数据被

拖库泄露。

·防恶意CC，通过阻断海量的恶意请求，保障⽹站可⽤性。

·阻⽌⽊马上传⽹页篡改，保障⽹站的公信⼒。

·提供虚拟补丁，针对⽹站被曝光的最新漏洞，最⼤可能地提供快

速修复规则。

WAF的使⽤也⽐较简单，在购买Web应⽤防⽕墙后，把域名解析

到Web应⽤防⽕墙提供的CNAME地址上，并配置源站服务器IP，即可

启⽤Web应⽤防⽕墙。启⽤之后，⽹站所有的公⽹流量都会先经过Web

应⽤防⽕墙，从⽽恶意攻击流量在Web应⽤防⽕墙上被检测过滤，⽽正

常流量返回给源站IP，确保源站IP安全、稳定、可⽤。

3.DDoS防护对⽹络层攻击的防御

第15章跟⼤家介绍过，⿊客攻击的途径是漏洞。能发起DDoS攻击

的主要原因也是TCP三次协议的漏洞。DDoS攻击被誉为当前安全领域

及⿊客界唯⼀⽆法真正意义解决的攻击，除⾮更改TCP三次握⼿的协

议，才能治根。当前防御DDoS⽹络层攻击，都是侧⾯通过抗流量的硬

件防⽕墙进⾏流量清洗，这也是唯⼀有效的措施。那么在云端，我们

如何防御DDoS针对⽹络层的攻击呢？答案就是：云盾DDoS⾼防IP。

云盾DDoS⾼防IP产品是针对互联⽹服务器（包括⾮阿⾥云主机）

在遭受⼤流量的DDoS攻击后服务不可⽤的情况，推出的付费增值服

务。DDoS⾼防IP产品使⽤专门的⾼防机房提供DDoS防护服务，通过

引流、清洗、回注的⽅式将正常业务流量转发⾄源站服务器，确保源

站服务器的稳定可⽤。

从引流技术上，DDoS⾼防IP产品⽀持BGP与DNS两种⽅案。防护

采⽤被动清洗⽅式为主、主动压制为辅的⽅式，对攻击进⾏综合运营

托管，保障⽤户可在攻击下⾼枕⽆忧。针对攻击，在传统的代理、探

测、反弹、认证、⿊⽩名单、报⽂合规等标准技术的基础上，结合Web

安全过滤、信誉、七层应⽤分析、⽤户⾏为分析、特征学习、防护对

抗等多种技术，对威胁进⾏阻断过滤，保证被防护⽤户在攻击持续状

态下，仍可对外提供业务服务。

阿⾥云基于⾃主研发的云盾产品，提供的DDoS防护能⼒已⾼达T

级。可以防护SYN Flood、UDP Flood、ACK Flood、ICMP Flood、

DNS Query Flood、NTP reply Flood、CC攻击等三到七层DDoS攻击，

可防护的攻击类型如下：

·Malformed Packes：有效阻断畸形单包类攻击

·Large Traffic Attacks：轻松应对流量拥塞型攻击

·Web Application Attacks：识别阻断Web应⽤攻击

·DNS Attacks：保护DNS服务器

·Connection Exhausiton Attacks：精确识别连接耗尽型攻击

·Other：⾃适应最新攻击类型

DDoS⾼防IP产品的⽹络拓扑⽰意如图16-2所⽰。

左侧是DDoS⾼防IP防护服务结构，右侧是阿⾥云提供的DDoS基

础防护服务结构。

使⽤DDoS⾼防IP产品时，把域名解析到⾼防IP（Web业务把域名

解析指向⾼防IP；⾮Web业务把业务IP换成⾼防IP），同时在DDoS⾼

防IP上设置转发规则。所有的公⽹流量都会先经过⾼防机房，通过端

⼜协议转发的⽅式将访问流量通过⾼防IP转发到源站IP，同时将恶意攻

击流量在⾼防IP上进⾏清洗过滤，并将得到的正常流量返回给源站IP，

从⽽确保源站IP被稳定访问。

图16-2 DDoS⾼防IP产品⽹络拓扑

4.态势感知发现潜在安全风险及问题

态势感知（产品现已更名为云安全中⼼）是⼀个实时识别、分

析、预警安全威胁的统⼀安全管理系统，通过防勒索、防病毒、防篡

改、合规检查等安全能⼒，帮助⽤户实现威胁检测、响应、溯源的⾃

动化安全运营闭环，保护云上资产和本地主机并满⾜监管合规要求。

云安全中⼼可帮助⽤户收集并呈现10余种类型的⽇志和云上资产

指纹，并结合⽹络实体威胁情报进⾏安全态势分析，扩⼤安全可见

性。

云安全中⼼的典型应⽤场景包括：

·实时监控云上业务整体安全，对多种安全事件进⾏告警，如异常

登录、⽹站后门、病毒攻击、异常进程等。

·定期对云上服务进⾏漏洞扫描和基线配置核查，针对检测到的漏

洞和风险配置项提供监控与修复服务。

·对多种⽹络和主机⽇志进⾏检索，调查访问量，统计和分析各维

度的原始⽇志信息。

·监控AK泄露、⽹络⼊侵事件、DDoS攻击事件、ECS恶意⾁鸡⾏

为等，并对ECS开放的端⼜进⾏实时监控。

·对ECS中发⽣的⼊侵事件，如Webshell、恶意软件、核⼼数据被加

密勒索等进⾏回溯，发现⼊侵的原因和⼊侵的全过程。

使⽤云安全中⼼，需要在ECS服务器中安装Agent本地安全插件。

在购买ECS实例时，选择安全加固即可⾃动安装Agent并开通云安全中

⼼基础版。云安全中⼼安装后⾃动开通基础版功能，基础版仅提供主

机异常登录检测、漏洞检测、云产品安全配置项检测，如需更多⾼级

威胁检测、漏洞修复、病毒查杀等功能，请登录云安全中⼼控制台并

单击右上⾓升级，购买需要的版本即可。

16.1.2 安骑⼠、WAF、态势感知三⼤使⽤误区

误区⼀：WAF的使⽤误区

WAF主要针对七层HTTP应⽤层的攻击防御，出现这类问题的主

要原因是代码编写⽅⾯存在安全漏洞，它会导致SQL注⼊、XSS跨

站、WebShell上传、后门隔离保护、命令注⼊、⾮法HTTP协议请求、

常见Web服务器漏洞攻击、核⼼⽂件⾮授权访问、路径穿越、扫描防

护等安全问题，⽽WAF能有效防御并解决这些问题。但这⾥有个误

区，很多⼈觉得只要使⽤WAF这些安全漏洞就能被修复了。实际上

WAF主要是对这些安全问题进⾏请求拦截，防⽌恶意请求转发到后端

源站，并没有根治代码层⾯相应的安全问题，这是我们在使⽤WAF时

要注意的⼀⼤问题。

误区⼆：⽤WAF防御系统漏洞

为什么Redis等软件漏洞要⽤安骑⼠来检测及解决，⽽不⽤WAF来

防御解决？⽽Jenkins、WordPress等软件漏洞却要⽤WAF来防御解决？

安骑⼠可以看作是企业版的杀毒软件，主要解决的是操作系统级别的

漏洞、⽊马、病毒问题。⽽WAF针对的是OSI七层模型中HTTP层的防

御，即Web漏洞的防御。对⽐之后就可以看出安骑⼠和WAF的使⽤场

景及对应误区，有时客户甚⾄会在云端遇到Nginx、Redis漏洞后直接

购买WAF。⽐如在Jenkins的Stapler Web框架中存在任意⽂件读取漏

洞。恶意攻击者可以通过发送精⼼构造的HTTP请求，在未经授权的情

况下获取Jenkins主进程，并访问Jenkins⽂件系统中的任意⽂件内容。

这⾥核⼼⼊侵的途径，是通过HTTP请求，所以WAF是唯⼀安全拦截

防御的保障。相反，如果这个漏洞是通过操作系统级别来进⾏远程访

问的，那就不能⽤WAF，只能通过操作系统级别的安骑⼠来进⾏检测

及修复。

云诀窍

在实践中，安骑⼠与WAF往往需要配合使⽤。⽐如我们最近发⽣

的⼀个真实案例，客户某Web应⽤被挂载⽊马，即典型的PHP的

WebShell后门。要解决这个问题，必须将WAF与安骑⼠结合起来使

⽤。WAF保障HTTP拦截具有安全风险的请求，避免⽹站再次被挂载

⽊马。⽽安骑⼠主要检测已经通过Web流⼊系统中的⽊马⽂件。

误区三：⽤态势感知解决问题

异常登录、漏洞管理是态势感知的功能还是安骑⼠的功能？态势

感知是否能解决漏洞、攻击⾏为等安全问题？云计算/⼤数据将成为安

全体系的基础核⼼保障，⽽态势感知就是⼀款在云时代下的⼤数据安

全分析产品和服务。异常登录、漏洞管理其实是安骑⼠的核⼼功能，

之所以在态势感知中看到这块内容，是因为态势感知收集后会呈现10

余种安全类型的⽇志和云上资产指纹，并且它结合⽹络实体威胁情报

进⾏安全态势分析，扩⼤安全可见性。所以态势感知不是为了解决问

题，⽽是发现问题。

16.1.3 DDoS和WAF三⼤实践技巧

实践1：DDoS防御治标不治本

监控报警，发现业务不可达。阿⾥云通知SLB地址被拉⼊⿊洞，控

制台提⽰攻击流量达到11GB。但由于客户成本⽅⾯的问题不使⽤DDoS

⾼防。

基于以上原因我们给出了如下的临时解决⽅法：

1）更换SLB（等同于更换IP）。

2）开启DDoS基础防护中的“安全信誉开关”。

通过上述操作，基础防护（免费）能⼒达到了10GB以上，基本上

帮助客户解决了这次攻击问题，但如果⿊客发起下⼀波流量攻击，会

导致新的SLB也被迫拉⼊⿊洞，所以这是⼀种临时的治标不治本的做

法。

实践2：DDoS和WAF的前后关系

在云端IDC机房中，每个IDC都部署了DDoS流量清洗集群，⽽流

量清洗集群主要是华为—赛门铁克专门为阿⾥定制的硬件（多板卡多

端⼜）和阿⾥⾃⼰设计的软件（云盾）。DDoS集群清洗，是机房级别

⽹络请求流量的⼊⼜。所以在实际应⽤中，DDoS⾼防产品要放在WAF

前⾯。

在云端我们遇到某⾦融类客户，每天都会出现PC站、⼿机站、移

动App等多处业务⽆法访问的情况，每次⼤约1～6⼩时，被⿊客DDoS

攻击峰值达到200GB以上，致使⽹站完全瘫痪，每⼩时损失近百万

元。客户虽然购买了阿⾥云WAF和DDoS⾼防IP等安全产品，但不会配

置，因⽽⽹络结构上仍存在严重安全隐患，安全产品没有起到任何防

护作⽤，⽹站仍然会被⿊客攻击导致瘫痪。我们来看看购买DDoS⾼防

IP和WAF后如何进⾏配置，如图16-3所⽰。

在域名解析中，有些域名解析到DDoS上，有些域名解析到WAF

上。这就出现了“对DDoS采⽤WAF攻击，对WAF采⽤DDoS攻击”的问

题，即域名解析到DDoS⾼防IP上，虽然防御住了DDoS流量攻击，但

是没办法防御应⽤层SQL注⼊、挂载⽊马等安全问题。⽽域名解析到

WAF产品上，虽然防御住了应⽤层的SQL注⼊、挂载⽊马等安全问

题，但是⾯对DDoS⾼流量攻击，⽹站也会瞬间瘫痪。可见，虽然花费

⾼额成本购买了DDoS⾼防IP和WAF，但是并没有很好地利⽤它们。

DDoS⾼防IP+WAF的正确配置如图16-4所⽰。

图16-3 DDoS⾼防IP+WAF的异常配置

图16-4 DDoS⾼防IP+WAF的正确配置

域名统⼀解析到DDoS⾼防IP上，DDoS⾼防IP过滤到三四层⽹络流

量攻击，然后再将请求转发⾄WAF产品上，最终WAF将正常请求转回

⾄源站。

实践3：综合流量攻击中的实践

并不是所有流量攻击都⽤DDoS⾼防IP，DDoS流量主要针对三四

层⽹络流量攻击，⽽CC流量攻击主要针对七层⽹络流量攻击。所以⾯

对DDoS流量攻击时，我们需要⽤DDoS⾼防IP防御，⽽CC流量攻击则

⽤WAF防御。

⽐如，客户被攻击，页⾯被刷流量，CC攻击流量⾼达1Gbps。这

时候客户应该采⽤WAF还是DDoS？事实上，这时候需要⽤WAF来防

御。

再⽐如，客户被DDoS攻击，瞬时流量⾼达50Gbps，同时CC攻击

流量⾼达1Gbps。请问要怎么使⽤云盾安全产品？答案是这时候需要⽤

DDoS+WAF结合起来防御。

16.2 云端安全架构四⼤策略实践

在云端安全防御中，有了第⼀道防线，我们就能⾼枕⽆忧地应对

⿊客常见攻击了吗？答案是否定的。从安全架构层来说，我们需要站

在系统层、应⽤层、⽹络层之上，从更⾼层次看待安全体系架构并解

决安全问题。安全架构的⽀撑，能从宏观⾓度避免⼀些安全问题，并

能直接提升业务系统的安全防御能⼒，这是云端安全防御中的第⼆道

防线。

16.2.1 策略⼀：云平台架构模式选择

在云端不同的架构模式所直接表现出来的安全特性也有所不同。

公有云⾯向的是互联⽹常规业务，⽐如电商、门户⽹站、视频、游戏

等业务，所有公⽹⽤户都能直接访问请求业务。但同时，由于业务直

接暴露在互联⽹中，所带来的安全隐患和挑战也是更⼤的。所以有些

政府应⽤或者局域⽹应⽤，直接部署在公有云上时安全挑战很⼤。这

时候⽤单独的数据中⼼部署云平台，并且做对应的公⽹隔离，设置仅

限局域⽹访问，这样安全风险就会相对较低。但这种场景相对来说还

是较少，随着云的普及，越来越多的传统企业将公司局域⽹如ERP、

OA等应⽤部署在公有云上，但为了解决安全性问题，通过专线+VPN

的技术⼿段把云端和公司内⽹打通，这已经成为较为成熟且主流的解

决⽅案，也就是混合云部署的模式。不同模式部署的特点及适⽤场景

如表16-1所⽰。

表16-1 不同模式部署的特点及适⽤场景

正如以上所说，在⼀些政府、⾦融领域，或者是⼀些政策、流程

的要求，以及定制化的需求等，使得公有云平台⽆法满⾜对应需求，

对此，⼀些⼤型企业就会选择专有云（私有化部署）来满⾜⾃⾝定制

化需求。这时候可以考虑使⽤阿⾥专有云或者传统OpenStack来部署，

并采⽤驻云的CBIS系统进⾏云产品资源管理。

驻云CBIS云计算商业服务集成系统，⾯向企业提供⼀整套对多种

云资源实现混合管理的云计算运营服务平台，不仅解决了企业内部管

理和使⽤云计算资源的客观需求，还⽀持企业对富余的云计算资源进

⾏对外售卖。在资源统⼀管理的基础上，CBIS更能进⼀步⽀撑混合云

平台的业务运营⼯作，实现对分公司、部门、项⽬的预算控制和费⽤

核算以及多维度管理⽤户资源。同时，CBIS还提供了灵活的商品上架

功能，CBIS的这些功能以及驻云所提供的⼀整套解决⽅案，帮助客

户“零基础零TCO”建⽴⾼可靠的⾃有品牌运营，成为云平台运营商。

在云平台管理过程中产⽣的个性化需求，CBIS可以有针对性地对组件

进⾏定制化，⽽不影响产品整体的稳定性，如图16-5所⽰。

图16-5 驻云CBIS架构

16.2.2 策略⼆：分布式架构是安全保障的基⽯

在前⾯“1+1>2”的案例中也曾提到，分布式架构是安全保障，也是

性能、稳定性的保障，同时还能冗余防御DDoS⽅⾯的攻击请求。正所

谓“鸡蛋不要放在⼀个篮⼦⾥”，通过分布式跨地域部署，能够进⼀步

提⾼安全性，如图16-6所⽰。

在分布式架构中，同地域的情况下，应尽量把应⽤及数据放在不

同的机房（可⽤区）。如果业务条件需要更⾼的安全性要求，可以进

⼀步把应⽤及数据放在不同地域（跨地域分布式架构，底层数据的同

步及延时性需要注意）。甚⾄可以通过容器技术跨云供应商进⾏分布

式部署。这样操作对底层平台依赖更少，不会因为底层⽹络、机房、

云平台的问题⽽导致业务不可访问。

16.2.3 策略三：全⾯开启云产品的安全机制

如果把业务部署在云端，数据包在云端内部的流转如图16-7所⽰。

图16-6 跨地域、跨平台分布式架构

图16-7 云端数据包流向图

当我们请求云端部署的业务后，数据包经过本地运营商（如电

信、⽹通、移动等）通过路由传输⾄云机房，进⼊云机房后会最先经

过DDoS流量清洗集群，然后经过CDN，之后数据包会流向Web应⽤防

⽕墙（WAF），然后再经过云平台的安全组⽹络规则，再到负载均衡

SLB上。SLB会将数据包转到ECS，数据包通过⽹卡流⼊内核，会先经

过Iptables。通过Iptables后，数据包会由内核空间流⼊⽤户空间，流⼊

到Nginx中。Nginx通过反向代理，会向应⽤服务器发起数据包转发。

应⽤服务器（Java、PHP、Node）处理数据包请求，期间可能会调⽤数

据库。发起新的请求⾄RDS数据库中，数据库处理完成后会返回数据

结果⾄应⽤服务器。应⽤服务器封装数据结果，将结果返回给客户

端。

技巧 实践技巧1：通过流向图，我们看到数据从安全类产品

流⼊操作系统层，然后流⼊Web服务层，再到达业务代码层，最终到达

数据库持久层。从数据流向上来看，我们⼀般需要在哪⾥做防御？在

每个流转路径，每个层都要做数据的安全限制，⽐如⽩名单等，保障

对应请求是安全可信的，能有效避免⿊客常见攻击。

实践技巧2：很多⼈觉得数据包的流向要先经过CDN再到DDoS集

群中。因为CDN不具备防御DDoS的能⼒，所以数据包的流向，CDN是

在DDoS后⾯。但在云端实践中，DDoS⾼防和CDN可能要同时使⽤，

但是数据包先经过集群清洗，再经过CDN，数据包绕路太远会影响静

态访问加速效果。如果既想通过CDN加速，又想具有DDoS防护能⼒，

可以使⽤SCDN产品，即实现了CDN–DDoS这种线路。

16.2.4 策略四：基于VPC的企业级安全架构

在云端企业级安全架构中，核⼼是基于VPC⽹络，能有效减轻或

避免⿊客针对⽹络层攻击。云端VPC⽹络和经典⽹络在安全⽅⾯和功

能⽅⾯的对⽐，已在第4章中详细介绍，这⾥仅对其进⾏简要说明，如

表16-2所⽰。

表16-2 经典⽹络和专有⽹络对⽐

所以在云端，特别是传统企业，需要让IDC及线下数据中⼼和云端

内⽹打通，即采⽤混合云架构的部署模式。云端VPC安全架构如图16-8

所⽰。

图16-8 云端VPC安全架构

企业局域⽹⼀般有AD/OA/ERP/邮箱/测试环境等硬件服务器，所以

在传统企业级架构中，硬件服务器必不可少。⽽在云时代下，企业级

架构的未来，即当前驻云内部采⽤的混合云部署结构，在公司⾥⾯看

不到⼀台硬件服务器，只需购买⼀台路由器（防⽕墙）、⼏个交换机

和⼏个AP即可，公司内部系统都可以部署到云上。这⾥会有⼈说，部

署在公有云上，内部系统不是对外了吗？我们可以采⽤VPN，把云上

环境和公司内⽹环境做IPSEC内⽹打通，公司AD/OA/ERP/邮箱/测试环

境等全部可以放在云端。云端不仅能和企业内⽹打通，也能和IDC、数

据中⼼的内⽹打通。普通VPN由于基于公⽹加密传输，如若对传输速

度、质量有⽹络要求，可将线路改为专线，以保障传输速度及质量。

16.3 云端运维安全实践⼗则

在云端安全防御中，第⼀道防线是云端安全产品，它是云端最直

接有效的安全解决⽅案。第⼆道防线是云端安全架构，能从宏观⾓度

避免⼀些安全问题，并能直接增加业务系统对安全防御的能⼒。⽽在

云端安全防御中的最后⼀道防线，即在运维层次的安全保障，进⼀步

做运维层安全加固应对⿊客常见攻击。

16.3.1 第⼀则：云端堡垒机的三种实践

堡垒机是远程控制的必要安全⼿段，即我们需通过堡垒机来对服

务器进⾏远程管理。堡垒机具备安全审计、权限管理等核⼼安全管理

功能，也可以避免⿊客恶意远程登录等安全问题。在云端堡垒机实践

中，有三种实践⽅案：

1）阿⾥云⾃带堡垒机（推荐，原因是与ECS云产品的⽆缝结合更

紧密）；

2）驻云CSOS云安全运维系统；

3）在ECS上⾃建JumpServer。

其中，JumpServer是知名开源堡垒机，下⾯以云端⾃建JumpServer

为例，介绍云端堡垒机安全审计的实践应⽤，如图16-9所⽰。

通过安全组控制，ECS不能直接对外提供SSH/RDP远程连接，只

能通过JumpServer实现。即想要SSH/RDP登录ECS，只能通过

JumpServer进⾏。这样就能在JumpServer上做安全审计、权限控制等安

全管理了。

JumpServer⽀持客户端及Web界⾯连接登录，基本上主流堡垒机，

包括阿⾥云⾃带堡垒机都⽀持客户端和Web界⾯登录的⽅式。

通过安全组+VPN，把云端和公司⽹络的内⽹打通。在公司内⽹中

的办公⽹络，能直接远程登录云端服务器。⽽在⾮公司⽹络，⽐如家

庭⽹络，需要提前拨号VPN登录公司⽹络，然后才能远程登录云端服

务器。这是当前云端最为成熟的⽹络架构。

图16-9 JumpServer在云端的实践应⽤

16.3.2 第⼆则：运维⽤户管理

运维⽤户管理，是指运⾏在操作系统中的进程⽤户，以及远程⽤

户⽅⾯的安全管理。合理的⽤户权限，能有效避免⿊客利⽤⽊马及病

毒对系统进⾏提权。

⾸先，程序采⽤⾮root⽤户运⾏，特别是PHP等中间件，安全漏洞

较多，如若采⽤root⽤户进程，root权限较⼤，则很可能出现利⽤漏洞

直接执⾏⼀些恶意代码或者程序的情况，存在较⼤安全隐患。

其次，我们在⽇常运维管理中，⼀般都直接禁⽤root⽤户远程登

录。如果对root⽤户直接开放，对远程控制的安全管理挑战较⼤，⽽

且直接⽤root登录运维操作，误操作的概率也较⼤。所以在运维规范

及标准中，默认禁⽤root⽤户远程登录，都是直接通过普通⽤户远程

登录，如若需要root权限，则通过su或者sudo命令切换成root进⾏操

作。

为了进⼀步控制安全性，我们还可以在SSH的配置⽂件中指定⽤

户才能远程登录，⾄于新增加的客户，如果不在指定⽤户中，则默认

不能远程登录。

16.3.3 第三则：密码安全管理

随着互联⽹应⽤的增多，⼤家要登录系统的地址、⽤户名、密码

也越来越多。有时为了⽅便，⼈们把密码明⽂存放在Email、Txt⽂

本、Word⽂件、Excel⽂件或者图⽚截图中。但这种⽅式存在极⼤的安

全隐患，特别是在运维管理过程中，为了⽅便，把服务器权限存放⾄

这些⽂本⽂件中，如果这些敏感⽂件泄露了，将会带来灾难性的安全

问题。

另外，在前⾯也跟⼤家介绍过互联⽹最⼤的安全隐患便是密码漏

洞。在服务器的密码管理中也经常存在这样的问题，有很多服务器密

码设置⼀样，也有很多服务器都是程序员⾃⼰随便设置的⼀个好记的

密码（弱⼜令），并且长时间不更新。

所以为了解决上述安全隐患，在实践中，密码的存储、传输，统

⼀采⽤Keepass专业密码⼯具，并且服务器的密码设置，都是采⽤密码

⼯具⽣成的随机密码。但我们发现，定期管理、修改密码等⽅式在维

护效率、安全性等⽅⾯都不是最优的。在云端，最好的密码安全管理

⽅案便是没密码。即服务器远程登录管理，采⽤证书⽅式是最为安全

的。其实，在亚马逊上，服务器的远程登录管理早就默认采⽤证书

了。虽然阿⾥云之前采⽤的是密码管理，但⽬前也已经⽀持证书登录

管理了。

由此可见，良好的密码安全管理，能有效避免弱⼜令等安全问

题，直接避免被⿊客进⾏密码暴⼒破解的可能性。

16.3.4 第四则：防⽕墙安全管理

在云端，我们需要通过安全组+Iptables防⽕墙的⽅式，来保障访问

连接的安全性。通过安全组+Iptables防⽕墙设置端⼜服务访问地址的⽩

名单/⿊名单，应该是在运维层⾯提⾼安全性最有效最直接的做法了，

也是运维层⾯安全防御的最佳实践，还能⼀定程度上应对⿊客针对⽹

络层⾯的攻击。

安全组主要针对属于同个安全组下ECS共⽤的端⼜安全规则设置，

⽽Iptables主要针对ECS访问级别能做更细粒度的安全规则设置。假设

以下场景服务器部署了常见的Web业务，其安全访问规则设置如下：

·Web服务器：需要开放80、8080、22端⼜。

·Windows服务器：需要开放21、3389端⼜。

·数据库服务器：需要开放3306端⼜。

每台服务器的端⼜规则都不⼀样，因此不能把这三类服务器放在

⼀个安全组下，并且把80、8080、22、21、3389、3306端⼜都放开，

这样既不便于维护，也不安全。如果考虑通过安全组来解决，为了设

置对应的安全规则，只能分别把Web服务器、Windows服务器和数据库

服务器各放在⼀个安全组下。这样虽然增加了安全组，但考虑到业务

夜间也要互访，因此还得把安全组打通，这⽆疑增加了对应的维护成

本。所以此时采⽤Iptables来做安全规则，也是⼀种较好的⽅案。由此

可见，某个安全组批量针对部署着同个端⼜服务的业务来做安全规

则，这再合适不过。⽽相⽐安全组，Iptables的四表五链，针对内核级

别的数据包控制，更适合做更细粒度的安全规则控制。Iptables和安全

组的对⽐实践如表16-3所⽰。

表16-3 Iptables与安全组的对⽐

我们来看⼀个具体案例，Iptables能根据进过内核的数据包state状

态来做控制，甚⾄能控制每秒经过内核数据包的个数。

#Main Firewall rules start ###########################

# create a LOGDROP chain to allow DROP then LOG

echo "Creating custom log chains: "

Iptables -N LOGDROP_ILLEGAL_PACKET

iptables -A LOGDROP_ILLEGAL_PACKET -j LOG -m limit --limit 120/minute --log-prefix "IPTFW-bad-flag " --log-level debug

iptables -A LOGDROP_ILLEGAL_PACKET -j DROP

echo -e "$GREEN Custom log chains created. $NO_COLOR"

# For the following rules we log and drop illegal network traffic

# can be set to a new log file by defining --log-level

# First thing, drop illegal packets.

echo "Dropping illegal INBOUND traffic - packets + networks: "

# iptables -A INPUT -p tcp ! --syn -m state --state NEW -j LOGDROP_ILLEGAL_PACKET

# New not SYN

iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j LOGDROP_ILLEGAL_PACKET

iptables -A INPUT -p tcp --tcp-flags ALL ALL -j LOGDROP_ILLEGAL_PACKET

iptables -A INPUT -p tcp --tcp-flags ALL NONE -j LOGDROP_ILLEGAL_PACKET # NULL

packets

iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j LOGDROP_ILLEGAL_PACKET

iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j LOGDROP_ILLEGAL_PACKET

# XMAS

iptables -A INPUT -p tcp --tcp-flags FIN,ACK FIN -j LOGDROP_ILLEGAL_PACKET # FIN

packet

iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOGDROP_ILLEGAL_

PACKET

echo -e "$GREEN Illegal INBOUND traffic dropped. $NO_COLOR"

#### HOLES ####

echo -en "Creating rules for allowed INBOUND traffic: $RED\n"

# Established - should be tightened to allowed IP later iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

## ICMP / Ping - should be tightened to allowed IP later iptables -A INPUT -p icmp -m icmp --icmp-type echo-request -m limit --limit 10/

second -j ACCEPT

iptables -A INPUT -p icmp -m icmp --icmp-type echo-reply -m limit --limit 10/second -j ACCEPT

iptables -A INPUT -p icmp -m icmp --icmp-type time-exceeded -m limit --limit 10/second -j ACCEPT

iptables -A INPUT -p icmp -m icmp --icmp-type destination-unreachable -m limit

--limit 10/second -j ACCEPT

iptables -A INPUT -p icmp -j DROP

###### DHCP Rules ######

iptables -A INPUT -p udp --dport 67:68 --sport 67:68 -j ACCEPT

16.3.5 第五则：端⼜安全管理

试想，在⼀台有公⽹IP的ECS上⾯，部署Redis服务的应⽤，存在

安全问题吗？我曾在很多线下沙龙分享过这个简单的案例，如图16-10

所⽰。

图16-10 数据库类服务绑定端⼜案例

这可能是当前80%的互联⽹会遇到的⼀个普遍现象，看似没问题，

但其实隐藏着很⼤的安全隐患。我们都知道数据是企业的⽣命、业务

的核⼼，⽽这些业务数据绝⼤多数都存放在数据库中。⽽在这个案例

中，是在⼀个有公⽹的ECS上，部署Redis数据库类服务。通常在正规

企业级应⽤中，是不允许数据库暴露在公⽹的，因为这种安全风险是

致命的。图16-8中，数据库类服务居然绑定在本机0.0.0.0上，表⽰本机

内⽹、公⽹、localhost等都能访问。这是个⼩细节，但也能体现较⼤的

安全问题。

⼀般数据库类服务，我们都是将端⼜服务监听绑定在127.0.0.1上。

对于MySQL、Oracle等关系型数据库，⼤家在使⽤过程中，基本上都

会通过⽤户名/密码进⾏AUTH权限认证校验。但有⼈在使⽤

Zookeeper、Redis、Memcache、MongoDB这些数据库类服务时，养成

了⼀个很不好的习惯，就是不喜欢设置auth权限认证校验。这个习惯存

在着较⼤的安全风险，在云端我们遇到太多客户业务由于没有进⾏这

⽅⾯基础的权限认证设置，导致⽹站被⼊侵挂载⽊马。

16.3.6 第六则：云端开源WAF实践

在实际应⽤层的防御中，我们可以⽤开源技术来防御。虽然效果

没有商业安全产品好，但基本能满⾜绝⼤多数安全需求。相⽐于

Nginx，OpenResty这块开源⼯具显然没有那么⾼的知名度。甚⾄刚开

始使⽤OpenResty时，也觉得⾃⼰在使⽤⼀个冷门技术。后来经过深⼊

实践才发现这个软件其实是个宝藏，这⽆疑成为云端开源WAF的最佳

实践。甚⾄很多商业的WAF产品，都是基于OpenResty做⼆次开发得

来的。OpenResty其实就是Nginx通过Lua进⾏了⼆次开发，然后可以随

⼼所欲地做复杂的控制及安全监测。⽰例配置如下：

http {

include mime.types;

default_type application/octet-stream;

#charset gb2312;

server_names_hash_bucket_size 128;

client_header_buffer_size 32k;

large_client_header_buffers 4 32k;

client_max_body_size 8m;

sendfile on;

tcp_nopush on;

keepalive_timeout 60;

tcp_nodelay on;

fastcgi_connect_timeout 300;

fastcgi_send_timeout 300;

fastcgi_read_timeout 300;

fastcgi_buffer_size 64k;

fastcgi_buffers 4 64k;

fastcgi_busy_buffers_size 128k;

fastcgi_temp_file_write_size 128k;

gzip on;

gzip_min_length 1k;

gzip_buffers 4 16k;

gzip_http_version 1.0;

gzip_comp_level 2;

gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on;

#limit_zone crawler $binary_remote_addr 10m;

log_format '$remote_addr - $remote_user [$time_local] "$request" '

'$status $body_bytes_sent "$http_referer" '

'"$http_user_agent" "$http_x_forwarded_for"'; include /alidata/openresty/nginx/conf/vhosts/*.conf;

lua_shared_dict limit 50m;

lua_package_path "/alidata/openresty/nginx/conf/waf/?.lua"; init_by_lua_file "/alidata/openresty/nginx/conf/waf/init.lua"; access_by_lua_file "/alidata/openresty/nginx/conf/waf/access.lua";

}

安装完OpenResty，其实就是安装了Nginx。只不过在nginx.conf主

配置末尾三⾏配置中引⼊了Lua的脚本，Lua的脚本便是OpenResty的

核⼼。config.lua是OpenResty的核⼼配置。

--waf status

config_waf_enable = "on"

--log dir

config_log_dir = "/tmp"

--rule setting

config_rule_dir = "/alidata/openresty/nginx/conf/waf/rule-config"

--enable/disable white url

config_white_url_check = "on"

--enable/disable white ip

config_white_ip_check = "on"

--enable/disable block ip

config_black_ip_check = "on"

--enable/disable url filtering

config_url_check = "on"

--enalbe/disable url args filtering

config_url_args_check = "on"

--enable/disable user agent filtering

config_user_agent_check = "on"

--enable/disable cookie deny filtering

config_cookie_check = "on"

--enable/disable cc filtering

config_cc_check = "on"

--cc rate the xxx of xxx seconds

config_cc_rate = "10/60"

--enable/disable post filtering

config_post_check = "on"

--config waf output redirect/html

config_waf_output = "url"

--if config_waf_output ,setting url

config_waf_redirect_url = "www.cloudcare.cn"

config_output_html=

从代码中可以看到常见的⽩名单/⿊名单、SQL注⼊、CC攻击等防

御功能，⽽这些都是智能式配置，基本上能应对⽇常绝⼤多数安全场

景。当然如若结合业务需求，需要更多七层防御的功能，那么就需要

基于Lua来进⾏定制化开发。

16.3.7 第七则：云端数据安全传输的标准

互联⽹应⽤中，苹果和⾕歌率先推进HTTPS的普及。

·苹果公司于2016年6⽉宣布，2016年年底前登录App Store的所有

iOS应⽤将强制使⽤HTTPS，App的⽹络传输必须通过HTTPS协议传

输，⽽不是HTTP协议。这意味着想上架App Store，必须要⽤HTTPS。

·⾕歌计划从2017年1⽉推出的Chrome 56开始，对未进⾏HTTPS加

密的⽹址链接直接采⽤红叉提醒。

在阿⾥云上运⾏着全国40%的⽹站，Web类应⽤在云端占了半壁江

⼭。HTTP协议是Web类应⽤的表现形式，⽽在云端，HTTP已成为过去

式，全球HTTPS时代已经到来。HTTPS在云端已成为数据安全传输的

标准，之前有很多对外服务都采⽤的是HTTP，⽽如今在云端HTTPS基

本已被普及。

在云端实践中，SSL⼀般证书配置在哪⾥？我们发现在CDN上可以

配置证书，在WAF上可以配置证书，在SLB上可以配置证书，甚⾄在

ECS上⾃⼰搭建Nginx也可以配置证书。下⾯就根据场景来说明证书具

体配置到什么地⽅合适，如表16-4所⽰。

表16-4 证书在不同云产品中的配置场景

HTTPS主要⽤于加密客户请求端和服务端之间的数据传输，避免

数据明⽂传输⽽被⿊客截取。在实际应⽤场景中，我们⼀般把证书存

放在流量⼊⼜处。特别是CDN+WAF+SLB+ECS的架构，并不是要在

CDN、WAF、SLB上都配置证书。

16.3.8 第⼋则：运维安全性能调优的三种⽅法

必要的运维调优，不仅能提升性能，还能提升DDoS攻击防御能

⼒。前⾯也提到过，分布式架构是安全保障，主要是因为分布式架构

既能提升业务性能及稳定性，又能提升抗攻击能⼒。

1）调优PHP进程数、Tomcat连接数等，让中间件发挥性能极限，

冗余更多攻击。

2）调优操作系统内核参数，冗余更多TCP连接。

net.ipv4.ip_local_port_range = 1024 65000

表⽰⽤于向外连接的端⼜范围。默认情况下很⼩，只有32768～

61000，建议改为1024～65000。

net.ipv4.tcp_max_syn_backlog = 8192

表⽰SYN队列的长度，默认为1024，加⼤队列长度为8192，可以

容纳更多等待连接的⽹络连接数。

net.ipv4.tcp_max_tw_buckets = 5000

表⽰系统同时保持TIME_WAIT套接字的最⼤数量，如果超过这个

数字，TIME_WAIT套接字将⽴刻被清除并打印警告信息。默认为

180000，建议改为5000。对于Apache、Nginx等服务器，配置

tcp_max_tw_buckets可以很好地减少TIME_WAIT套接字数量，但是对

于Squid效果却不⼤。此项参数可以控制TIME_WAIT套接字的最⼤数

量，避免Squid服务器被⼤量的TIME_WAIT套接字拖死。

net.ipv4.tcp_syncookies = 1

表⽰开启SYN Cookies。当出现SYN等待队列溢出时，启⽤

cookies来处理，可防范少量SYN攻击，默认为0，表⽰关闭。

net.ipv4.tcp_tw_reuse = 1

表⽰开启重⽤。允许将TIME-WAIT sockets重新⽤于新的TCP连

接，默认为0，表⽰关闭。

net.ipv4.tcp_tw_recycle = 1

表⽰开启TCP连接中TIME-WAIT sockets的快速回收，默认为0，

表⽰关闭。

3）进⾏架构调优，最好以分布式结构部署应⽤，增加更多服务器

来提⾼性能及冗余更多攻击。

16.3.9 第九则：通过冷备及热备进⼀步保障云端数据安全性

云平台⾃带的冷备/热备，基本上保障了企业绝⼤多数场景下的数

据存放安全，这也是基础保障，如表16-5所⽰。

表16-5 云产品冷备/热备概览

这是云端四款最为核⼼的数据存储类产品，我们需要在此基础

上，进⼀步采⽤冷备/热备的⽅式保障数据安全性。⽽云数据库Redis、

Memcache等NoSQL，由于缓存数据在业务数据中很少有场景需要做冷

备，基本上⾃带的冷备即可满⾜需求。OSS海量存储，同样在实际业务

场景中很难对海量数据做冷备，所以基本上默认都是采⽤⾃带的热备

来保障数据的安全性。因此，基于云平台⾃带冷备/热备，进⼀步保障

数据的安全性场景，基本上都是针对ECS和RDS这两款云产品的。

1.ECS数据冷备恢复⽂件的两种⽅法

案例场景：如果仅想恢复某⼀个⽂件应怎样操作？

我们不能直接回滚磁盘的快照，这会导致磁盘⾥所有⽂件都回滚

到上个备份时刻的状态。所以在云端主要采⽤以下两种⽅式。

第⼀种是采⽤磁盘快照⽅式，但是需要临时开通⼀块云盘，步骤

如下：

1）新开云盘，⽤已有快照创建云盘。

2）挂载在ECS上获取历史数据，复制要恢复的⽂件。

但是这种⽅式灵活性不⾼，⽽且操作也较烦琐。

第⼆种是通过TAR打包或者对应OSS⼯具，将⽂件复制备份到OSS

甚⾄线下IDC或者其他云平台中。这种⽅式更为灵活简单，不过这种情

况下的备份，可能要考虑数据不⼀致的情况。⽐如打包某个⽂件⽬

录，如若打包过程中有输⼊的写⼊操作等，可能会导致最终备份的数

据不⼀致。ECS数据冷备⽅案架构如图16-11所⽰。

图16-11 ECS数据冷备⽅案架构

2.RDS数据结合OSS的冷备

案例：RDS到期，导致备份被清空的坑点（在云端遇到过这种情

况）。

虽然RDS的备份可以将存放时间设置得很长。但问题是如果RDS

到期被释放，可能会导致RDS相关备份都被⾃动清空。所以为了解决

这个问题，我们可以通过API获取备份⽂件，进⼀步将备份⽂件存放在

ECS或者OSS中，如图16-12所⽰。

我们也可以通过xtrabackup备份⼯具，将备份还原⾄线下IDC甚⾄

其他云平台中。xtrabackup的使⽤步骤如下：

1）下载安装xtrabackup并进⾏相关参数配置。

2）停⽌MySQL。

3）指定MySQL配置⽂件及数据⽬录进⾏备份。

图16-12 RDS结合OSS的冷备

4）scp将备份⽂件复制到新机器或者线下服务器。

5）⾸先恢复事务，然后再恢复数据。

3.ECS数据热备：Rsync是数据热备的最佳实践

Rsync作为开源领域⼀款热门的增量⽂件同步⼯具、⽂件迁移⼯

具、⽂件备份⼯具，实在想不出有谁能替代这个好⽤且功能强⼤的⼯

具，如图16-13所⽰。甚⾄⼀些商业的迁移、备份⼯具，感觉都没有

Rsync好⽤。

图16-13 通过Rsync热备ECS的数据⾄不同数据存储⽬标中

我们可以通过Rsync将ECS中存放的⽂件数据实时热备⾄云端其他

ECS系统中，甚⾄线下IDC/其他云平台、OSS、NAS中。当然同步到

OSS中时，可以结合OSSFS磁盘挂载类⼯具⼀起使⽤。以下3个场景都

是Rsync经典的热备实践案例。

案例1：某电商2T商品图⽚数据热迁移。由于2T的⼩图⽚数量太

多，根本没办法采⽤压缩打包⽅式传输，且压缩时间⽆法估量，也没

办法直接scp，如果在传输过程中对源数据变更，会导致数据不⼀致性

的问题出现；如果出现异常中断，可能还要再次重传。于是我们提前

两周采⽤Rsync进⾏热备份迁移，最终⽆缝将数据从线下IDC迁移⾄云

端。

案例2：某电商4G数据迁移的失败案例。为什么说是失败案例呢？

因为刚开始我们觉得4G的数据量不⼤，所以做这块数据迁移时，我们

直接先停⽌了服务，然后打包数据⽬录，结果仅这个操作就花了3个⼩

时，整个迁移花了⼀晚上时间。此外，我们没有考虑到这4G的电商数

据，⾥⾯存放着⼤量商品⼩图⽚，所以这种全量迁移的⽅式没有多⼤

可⾏性。事后我们进⾏了问题复盘，最终发现，采⽤Rsync提前做热备

份迁移，可以完全⽆缝地实时迁移。

案例3：在云端Rsync热备份的实践中，有客户向我们提出性能的

挑战。如果单纯跑Rsync⽽不添加任何限制条件，可能导致线上的⽹络

传输、I/O性能被占⽤，客户担⼼影响线上业务运作，这个问题要怎么

解决？事实上，Rsync⾃带的限流功能，就完美地解决了这⽅⾯问题。

如：限制为1000k Bytes/s，可采⽤如下命令：

rsync -auvz --progress --delete --bwlimit=1000

Rsync有个缺陷，就是并不是实时的，但Rsync+Inotify的结合能实

现实时同步。这在前⾯的共享⽂件实践中有详细介绍。

4.RDS数据热备：混合云架构实践

此案例在前⾯云端实践案例中有详细介绍，由于客户业务对数据

的安全性保障要求较⾼，⽽RDS⾃带的冷备/热备⽅案已经满⾜不了业

务诉求，因此考虑采⽤混合云结构，因为它能轻松⽅便地实现异地容

灾备份。云端混合云架构解决RDS容灾热备如图16-14所⽰。

技巧 实践技巧1：基于VPC+专线打通云上和数据中⼼内⽹。

实践技巧2：RDS采⽤DTS将线上和线下数据库做实时同步。

实践技巧3：MongoDB采⽤原始态副本集，线下存放⼀份线上副本

集。

实践技巧4：RabbitMQ采⽤镜像复制模式+SLB组成两台机器的⾼

可⽤。

实践技巧5：⾃建MySQL主从+（DNS+Consul）实现数据库⾼可

⽤，并且⼀份从库热备⾄线下IDC机房中。

实践技巧6：⾃建Redis主从+（DNS+Consul）实现数据库⾼可⽤，

并且⼀份从库热备⾄线下IDC机房中。

图16-14 云端混合云架构解决RDS容灾热备

16.3.10 第⼗则：加强安全巡检及安全培训管理

定期进⾏安全巡检，及时进⾏安全补丁更新、漏洞修复。必要时

采⽤安全渗透测试对业务及系统进⾏更加深⼊的安全评估。在运维侧

能及时发现问题，便能及时解决问题并且防患于未然，⽽不是被动地

应对⿊客攻击及修补安全问题。另外，提升安全意识在云端安全防御

⾮技术⽅案中⽐较重要。所以提⾼安全意识，是作为运维⼈员及技术

⼈员职业修养的必修课。

16.4 云端防御综合案例总结

图16-15 云端⾼防架构

⼀个⽹站，瞬时流量有100GB的流量攻击，采⽤了阿⾥云的⾼防

IP来防御。但是后端服务器的配置只有2核2GB，能抗住吗？

这是⼀个云端实践的真实案例，如图16-15所⽰。

第⼀步，采⽤安全类云产品。使⽤阿⾥云DDoS⾼防IP应对恶意攻

击流量的清洗效果⽴竿见影，但是⽹站仍然打不开，⾸页访问卡住并

⽩屏。出现这种情况的主要原因是这种⾼流量攻击，虽然绝⼤多数攻

击流量都被DDoS⾼防IP防御住了，但是还是有少量恶意攻击流量流⼊

后端。⽽我们后端只有⼀台2核4GB的单机低配服务器，所以即使少量

恶意流量流⼊后端，也会导致服务器宕机，如图16-16所⽰。

图16-16 云端⾼防架构优化

第⼆步，对安全架构进⾏优化。⽴刻将该⽹站切换成分布式架

构，前端通过SLB将请求转发给后端4台4核8GB的服务器实施业务请

求。提升业务系统性能，使其能够⽀撑更多请求、冗余更多攻击请求

流量。架构切换后，打开⽹站还是有些卡顿，延时还是很⼤。在ECS

的操作系统⾥⾯，我们发现⽹站PHP配置的进程数仅有⼗⼏个，⽽且

内核中有对应TCP连接超时的报错。

第三步，在运维层次进⾏安全保障。最终我们将PHP的进程分配

优化成为静态模式，配置了256个进程。同时优化内核，让内核能⽀持

更多TCP连接。最终在运维侧进⼀步安全调优优化，解决了这次⾼流

量的DDoS攻击。

在云端安全防御中，第⼀道防线是云端安全产品，它是云端最有

效且直接的安全解决⽅案。第⼆道防线是云端安全架构，能从宏观⾓

度避免⼀些安全问题，并能直接提升业务系统的安全防御能⼒。⽽在

云端安全防御中的最后⼀道防线，是运维层次的安全保障。

第四篇 云端架构篇

·第17章 云端千万级架构的演变

·第18章 云端架构的应⽤

对于在云端如何构建千万级架构，本篇结合前⾯云端选型篇、云

端实践篇、云端安全篇中相应阿⾥云最佳实践经验，向⼤家分享⼀个

⼩型⽹站如何逐步演变到千万级架构的过程。另外，结合云端热门的

不同互联⽹业务的特点，在架构设计中要如何考量和偏向，又有哪些

秘密和诀窍，本篇也进⾏了最后的总结分享。

第17章 云端千万级架构的演变

⼀个好的架构是靠演变⽽来的，⽽不是单纯靠设计。刚开始做架

构设计时，我们不可能全⽅位地考虑到架构的⾼性能、⾼扩展性、⾼

安全等各⽅⾯的因素。随着业务需求越来越多、业务访问压⼒越来越

⼤，架构不断地演变及进化，进⽽造就了⼀个成熟稳定的⼤型架构。

淘宝⽹、Facebook等⼤型⽹站的架构，⽆⼀不是从⼩型规模架构，不

断进化及演变成⼀个⼤型⽹站架构的。

17.1 架构原始阶段：万能的单机

架构的最原始阶段，即⼀台ECS服务器搞定⼀切。传统官⽹、论

坛等应⽤，只需要⼀台ECS即可，对应的Web服务器、数据库、静态

⽂件资源等，都可以部署到⼀台ECS上。⼀般5万PV到30万PV访问

量，结合内核参数调优、Web应⽤性能参数、数据库调优，基本上能

够在⼀台ECS上稳定运⾏。

图17-1 万能的单机架构

采⽤单台ECS的架构，如图17-1所⽰。

●架构实践注意要点

·⽤什么服务器配置选项是此阶段运维架构需要重点考虑的。

·另外根据业务请求流量，选择⽹络带宽（采⽤固定带宽还是按量

带宽）、磁盘类型，这样就能有效节省前期部署成本。

关于架构实践可参考第4～6章以及第8章。

17.2 架构基础阶段：物理分离Web和数据库

当访问压⼒达到50万PV到100万PV的时候，部署在⼀台服务器上

⾯的Web应⽤及数据库等服务应⽤，会对服务器的CPU、内存、磁

盘、带宽等系统资源进⾏争抢。显然单机已经出现性能瓶颈。将Web

应⽤和数据库物理分离单独部署，即可解决对应性能问题。这⾥的架

构采⽤ECS+RDS，如图17-2所⽰。

●架构实践注意要点

·⽤什么服务器配置选项依然是此阶段运维架构需要重点考虑的。

·数据库单⽴出来，注意设置好RDS的⽩名单，保障数据库的安全

性。

关于架构实践可参考第5章。

17.3 架构动静分离阶段：静态缓存+对象存储

当访问压⼒达到100万PV到300万PV的时候，前端Web服务就会出

现性能瓶颈。⼤量的Web请求被堵塞，同时服务器的CPU、磁盘I/O、

带宽都有压⼒。这时候我们⼀⽅⾯要将⽹站图⽚、js、css、html及应

⽤服务相关的⽂件存储在OSS中进⾏静态资源集中管理，另⼀⽅⾯要

通过CDN将静态资源分布式缓存在各个节点实现“就近访问”。通过将

动态请求、静态请求的访问分离（“动静分离”），有效解决服务器在

磁盘I/O、带宽⽅⾯的访问压⼒。

该架构采⽤CDN+ECS+OSS+RDS的形式，如图17-3所⽰。

图17-2 物理分离Web和数据库架构

图17-3 静态缓存+对象存储的架构

●架构实践注意要点：

·CDN可以直接进⾏动静请求分离，但在此⽤户量规模下，可能很

多⼈觉得没必要⽤OSS。不过我还是建议将静态资源采⽤独⽴的⼆级

域名集中部署在OSS中，⽅便后续架构扩展，也⽅便CDN回源请求加

速。当然，如若业务⽅⾯没有未来扩展的考虑等，直接采⽤CDN是最

⾼效便捷的做法。

关于架构实践可参考第4章、第8章和第9章。

17.4 架构分布式阶段：负载均衡

当访问压⼒达到300万PV到500万PV的时候，虽然“动静分离”有效

分离了静态请求的压⼒，但是动态请求的压⼒已经让服务器“吃不

消”。最直观的表现是前端访问堵塞、延迟、服务器进程增多、

CPU100%，并且出现常见的502、503、504等错误码。显然单台Web服

务器已经满⾜不了需求，这⾥需要通过负载均衡技术增加多台Web服务

器（对应ECS可以选择不同可⽤区，进⼀步保障⾼可⽤）。因⽽告别单

机时代，转变到分布式架构阶段。

该架构采⽤CDN+SLB+ECS+OSS+RDS的形式，如图17-4所⽰。

图17-4 负载均衡的分布式架构

●架构实践注意要点

此阶段的架构中，采⽤七层SLB即可满⾜绝⼤多数应⽤场景及业务

压⼒。但在⾼并发场景下，我们优先考虑四层SLB，但是这可能会增加

架构的运维配置管理⼯作量。

关于架构实践可参考第4章、第7章和第8章。

17.5 架构数据缓存阶段：数据库缓存

当访问压⼒达到500万PV到1000万PV时，虽然负载均衡结合多台

Web服务器，解决了动态请求的性能压⼒。但是这时候我们发现，数据

库出现压⼒瓶颈，常见的现象就是RDS的连接数增加并且堵塞、

CPU100%、IOPS飙升。这时候可通过数据库缓存，有效减少数据库访

问压⼒，进⼀步提升性能。

该架构采⽤CDN+SLB+ECS+OSS+云数据库Memcache+RDS的形

式，如图17-5所⽰。

图17-5 数据库缓存的架构

●架构实践注意要点

数据库缓存，需要业务代码改造及⽀持。哪些热点数据需要缓

存，这需要业务⽅⾯重点规划。并且云端数据库缓存，已不推荐在ECS

中⾃⾏搭建Redis、Memcache等。

关于架构实践可参考第4章和第8章。

17.6 架构扩展阶段：垂直扩展

当访问量达到1000万PV到5000万PV时，虽然这个时候通过分布式

⽂件系统OSS已经解决了⽂件存储的性能问题，也通过CDN解决了静

态资源访问的性能问题，但是当访问压⼒再次增加时，Web服务器和数

据库仍然是瓶颈。在此我们通过垂直扩展，进⼀步切分Web服务器和数

据库的压⼒，解决性能问题。

“何为垂直扩展，按照不同的业务（或者数据库）切分到不同的服

务器（或者数据库）之上，这种切分称之为垂直扩展。”

垂直扩展第⼀招：业务拆分

在业务层，可以把不同的功能模块拆分到不同的服务器上进⾏单

独部署。⽐如，将⽤户模块、订单模块、商品模块等拆分到不同服务

器上部署。

垂直扩展第⼆招：读写分离

在数据库层，如果结合数据库缓存，数据库压⼒还是很⼤，那么

可以通过读写分离的⽅式，进⼀步切分及降低数据库的压⼒。

垂直扩展第三招：分库

结合业务拆分、读写分离，在数据库层同样可以把⽤户模块、订

单模块、商品模块所涉及的数据库表（⽤户模块表、订单模块表、商

品模块表）等，拆分出来分别存放到不同数据库中，如⽤户模块库、

订单模块库、商品模块库等。然后再把不同数据库分别部署到不同服

务器中。

该架构采⽤CDN+SLB+ECS+OSS+云数据库Memcache+RDS读写分

离的形式，如图17-6所⽰。

图17-6 数据库垂直扩展的架构

●架构注意要点：

·架构中后期，业务瓶颈往往集中在数据库层⾯。因为在业务层，

我们通过负载均衡能够快速添加更多服务器进⾏⽔平扩容，可以⽅便

快速地解决业务服务器处理压⼒。⽽数据库性能扩展不是简单加⼏台

服务器就能解决的，这往往会涉及复杂的数据库架构变更。垂直拆

分，相对在业务上改动较少，并且是数据库性能提升最为⾼效的⼀种

⽅式，也是中⼤型应⽤⾸先要采⽤的架构⽅案。

·此阶段的架构中，由于业务请求有⼀定压⼒，建议采⽤四层

SLB，虚拟主机、证书配置等七层功能需要放在后端服务器ECS搭建的

Nginx上来控制，但是这可能会增加架构的运维配置管理⼯作量。

关于架构实践可参考第4章和第10章。

17.7 架构分布式+⼤数据阶段：⽔平扩展

当访问量达到5000万PV及以上时，也就是说真正达到千万级架构

以上访问量时，垂直扩展的架构也开始“⼭穷⽔尽”。⽐如，读写分离

仅解决读的压⼒，⾯对⾼访问量，在数据库“写”的压⼒上⾯“⼒不从

⼼”，会出现性能瓶颈。另外，分库虽然将压⼒拆分到不同数据库中。

但当数据量达到TB级别以上，显然已经达到传统关系型数据库处理的

极限。

⽔平扩展第⼀招：增加更多的Web服务器

在将业务垂直拆分分布部署在不同服务器后，当后续压⼒进⼀步

增⼤时，可增加更多的WebServer进⾏⽔平扩展。

⽔平扩展第⼆招：增加更多的SLB

单台SLB也存在单点故障的风险，并且SLB也存在性能极限，如七

层SLB的QPS最⼤值为50000。可通过DNS轮询，将请求轮询转发⾄不

同可⽤区的SLB上⾯，实现SLB⽔平扩展。

⽔平扩展第三招：采⽤分布式缓存

虽然阿⾥云Memcache内存数据库已经是分布式结构，但是同样单

⼀的⼊⼜也存在出现单点故障风险的可能，此外，还可能存在性能极

限，如最⼤吞吐量峰值为512Mbps。所以我们在部署多台云数据库

Memcache版时，可以在代码层通过HASH算法将数据分别缓存⾄不同

的云数据库Memcache版中。

⽔平扩展第四招：Sharding+NoSQL

⾯对⾼并发、⼤数据的需求，传统的关系型数据库已不再适合。

需要采⽤DRDS（MySQL Sharding分布式解决⽅案）+OTS（基于列存

储的分布式数据库）对应的分布式数据库来从根本上解决问题。

该架构采⽤CDN+DNS轮询+SLB+ECS+OSS+云数据库

Memcache+DRDS+OTS的形式，如图17-7所⽰。

图17-7 ⽔平扩展的分布式机构

●架构实践注意要点

·⼤型应⽤中，海量业务数据的存储、分析给数据库带来了巨⼤挑

战。传统的关系型数据库明显已经“⼒不从⼼”，分布式数据库NoSQL

是适⽤技术发展的未来趋势。

·有了海量业务数据的基础，我们可以结合云端MaxCompute⼤数据

分析服务，来辅助业务进⾏价值创造。

关于架构实践可参考第7章、第10章、第三篇全部章节。

第18章 云端架构的应⽤

云端最热门的互联⽹应⽤，当属电商、游戏、移动社交、⾦融

等。回归到技术层⾯，⽆⾮还是⽤Java、PHP、Python等开发语⾔，

Oracle、MySQL、SQLServer等关系型数据库，以及MongoDB、

Redis、Memcache等⾮关系型数据库。回归到架构层⾯，则⽆⾮是⽤

负载均衡、数据库、对象存储等分布式架构。所谓万变不离其宗，即

业务千奇百怪，回归到架构层⾯还是⼀样的。只不过针对不同的业务

特点，我们在架构中的考量和偏向会有所不同。本章主要根据不同业

务的特点，向⼤家介绍不同业务在云端架构应⽤的“秘密武器”。

18.1 云端电商架构应⽤

如今的“双⼗⼀”活动，每次都伴随着紧凑的运维保障压⼒。业务

⽅需要做好充⾜的准备，拟好活动规划和宣传⽅案，评估好对应的活

动压⼒。技术⽅则需要做好充⾜的技术准备，准备对应的冗余机器，

以应对活动时的⾼峰期。并且活动期间，需要有专门的作战指挥中

⼼，全员上阵，我们技术保障就如同打仗⼀样。虽然如今在云端为电

商做运维保障，资源开通随开随⽤随关随停，相⽐以前不⽤再提前准

备机器上架应对活动压⼒。但是我们应对的电商业务特点还是不变，

所以我们运维架构⽅⾯的⼯作也是基本保持不变。

18.1.1 业务特点：活动

在电商类业务中做活动搞促销、搞秒杀与“双⼗⼀”⼀样，也是家

常便饭。不搞活动、不搞秒杀的电商，基本上都不算电商业务了。所

以在活动期间的流量，最低可能也是平时的⼏倍，甚⾄是平时的⼏⼗

倍。⾼并发是电商业务最为明显的业务特点。所以针对电商类业务架

构，⾼并发是要重点解决的问题。主要⽤到以下⼏点技术。

1.弹性伸缩

弹性伸缩也是云平台最为核⼼的功能，在电商类应⽤中，平时的

业务访问量，压⼒并不⼤。但在活动⾼峰期，我们需要开通更多资源

来应对业务压⼒。弹性伸缩可以根据我们定义的伸缩规则，⾃动开通

相应的ECS来应对业务压⼒。不过，根据实践来看，弹性伸缩在某些

情况下还是徒有虚名。因为在实际应⽤场景中，不仅仅是弹性伸缩出

⼏台ECS出来，这些ECS要挂载到对应的SLB下，还要跟GitLab、

Jenkins、监控等⾃动化平台打通，甚⾄需要与其他⼀些云资源配合使

⽤，⽐如要去数据库中添加对应⽩名单。所以这⾥⾯还涉及了很多的

配置，只有真正将这些都做到⾃动化后，才算真正做到轻松应对活

动。

2.API+镜像+快照

如果真正实现弹性伸缩，在未来API功能都完善后，基本上可以

通过程序应对业务压⼒。当前通过API+镜像+快照，能够实现快速开

通对应的ECS，这也是云端针对电商活动，快速进⾏扩容最有效的⽅

式。如果觉得API使⽤有门槛，也可以在阿⾥云控制台上进⾏⼿动操

作。

18.1.2 业务特点：商品图⽚

电商业务的另⼀个特点就是静态资源⼏乎占了业务请求流量的

80%。因为在电商类业务中，有⼤量商品图⽚，⽽这些商品图⽚往往

是商品详情介绍最为核⼼的⼀部分。⼏乎98%的商品都会有商品图⽚

介绍，还有⼀些可能会通过图⽚和⼩视频来介绍商品。所以静态资

源，在电商类应⽤中的占⽐是⾮常重的。针对这⼀业务特点，CDN已

成为电商类业务的标配。业务系统的⽹络流量基本上能减少80%，⽽

且访问电商系统的速度⾄少能提升50%以上。

18.2 云端游戏架构应⽤

以游戏类应⽤为例，伴随着硬件的升级迭代（以前内存只有MB

级别，磁盘只有GB级别。⽽如今内存在GB级别，磁盘却到了TB级

别。），竞技类游戏的游戏特效效果也越来越酷炫，这意味着游戏应

⽤对电脑主机的性能计算要求也越来越⾼。举个简单例⼦也能看出

来，星际争霸1.08的经典版本安装包仅有110M，⽽英雄联盟在2019年

6⽉27⽇更新的安装包⼤⼩⾼达9.2G。

随着互联⽹转向移动互联⽹，移动互联⽹的普及，本质上也是云

计算BGP⽹络的普及，衍⽣出的移动类游戏成为热门。那游戏业务的

特点是什么呢？令⼈印象最为深刻的应该就是分区的特点。那在云端

运维架构及部署⽅⾯又有什么不⼀样呢？接下来为⼤家详细分享。

业务特点：分区

相⽐传统B/S、C/S应⽤架构，游戏架构的特点在于其特有的“分

区”概念。

为了解决玩家的延时性，传统IDC机房的游戏架构，⼀般分为电

信和联通两⼤分区，其下又分为“北京”“上海”“江苏”等分区。这种按

照地域的分区，其实在物理层⾯是把服务器对应部署在不同地域的机

房中。这样部署主要是为了解决游戏玩家的延时性。例如，北京电信

的玩家登录上海电信的服务器，延时⼀定很⾼。

游戏分区的架构特性，使得⼤多数游戏架构⼀般不是分布式集群

架构（以下简称为“集群架构”）。如果北京电信玩家登录上海电信的

游戏服务器，会发现游戏⾓⾊的属性已回归到刚注册的时候。从这点

可以判断出，不同地域的游戏，应⽤层和数据库都是独⽴分开部署

的。在传统的分布式集群架构上，不管是从北京登录，还是从上海登

录，⽤户数据都是唯⼀的。因为这种集群架构，底层数据库并没有独

⽴开。不过游戏类架构中的分区只是游戏类业务的⼀个特点，也有不

少不分区的游戏。⽐如知名COC（部落冲突）游戏，就是全世界只有

⼀个区。有时候匹配部落战争，能匹配到国外很多其他的部落。由此

可见，底层数据库并不是通过分区隔离开⽤户的。

游戏分区的架构特性，决定了游戏架构的扩展性⾮常好。所谓的

数据库垂直分区、⽔平分区，又⽐如MySQL的主从读写分离，这种数

据库层次的扩展很烦琐，⼀般应⽤于集群架构中。⽽游戏架构呢？简

单来说，只需要⼀台服务器部署应⽤，⼀台服务器部署数据库即可。

如果⽤户量增加，⽐如上海电信的⽤户量增加，可以再独⽴部署⼀台

服务器和⼀台数据库。因⽽就有了上海电信⼀区、上海电信⼆区这样

的区分。

传统IDC机房部署游戏，地域之间访问的延时性，形成了这种很

强的地域性分区。如果我们通过云端来部署实践，这种分区在架构中

有什么区别呢？我们知道，云主机⽹络都是多家运营商接⼊（BGP）

的，因此有效解决了传统机房部署遇到的问题——不同地域不同运营

商的玩家访问延时的问题。所以通过云来部署的游戏应⽤的分区，就

没有北京电信分区、上海电信分区之说了。可以简单地称之为⼀区、

⼆区、三区等，也可以不同区取个好听的别名，⽐如⼀区之风云再

起，⼆区之逐⿅中原，三区之雄霸天下。另外，游戏类业务偏向计

算，需要中⾼配类型服务器配置。型号优先选择CPU与内存资源配⽐

为1:2的类型，即8核16GB的配置基本上是游戏类经典配置。

分区只是游戏⾏业⼀个很突出的特点，⼏乎所有类型的游戏都具

有这个特点。但不同游戏的类型，在架构及技术上是有所区别的。游

戏按照应⽤划分，主要分为页游、⼿游和端游。但页游、⼿游和端游

在架构及技术上具体有什么区别呢？

1.页游与⼿游、端游的架构区别

页游是⽹页游戏的简称，这类Web游戏应⽤，都属于B/S架构的范

畴。需要注意的是，这⾥说的⽹页游戏，以及本章所介绍的游戏架

构，并不包括单机游戏。单机游戏根本不⽤跟服务端进⾏通信，也就

谈不上架构了。

⼿游是⼿机游戏的简称，端游也就是客户端游戏的简称，⼿游和

端游的特点是需要在⼿机、电脑上安装客户端。所以⼿游和端游就是

典型的C/S架构。

页游是B/S架构，⼿游和端游是C/S架构。B/S的架构基于浏览器，

所以⽤户不⽤关⼼程序的升级，当程序升级时，我们只需要在服务器

端更新⼀下，客户下次在浏览器访问时，就会⾃动把最新的数据返

回。⽽C/S的架构，每次程序升级时，可能都需要客户⼿动在⼿机或者

电脑上下载最新的客户端或者升级包进⾏更新。

2.页游、⼿游、端游的技术区别

页游、⼿游、端游后端的技术可能相差不⼤，主要技术区别在于

前端。页游采⽤HTML5、Flash等前端技术。⼿游，如果是Android系

统采⽤Java技术；如果是iOS系统主要采⽤Object C。端游⾸选是

C++了。

18.3 云端移动社交架构应⽤

传统社交主要是通过书信的⽅式，后来出现了2G⼿机，随着互联

⽹的发展，出现了QQ和UC等热门聊天⼯具，那时候互联⽹也是最单

纯的。再后来，随着移动2G/3G/4G甚⾄到现在5G⽹络的发展。互联⽹

转向移动互联⽹，社交主要转为移动社交。从陌陌聊天软件再到微

信，现在微信更是被誉为是⼀种⽣活的⽅式。然后从视频直播，再到

抖⾳等，当前，移动社交已成为社交的主流形式，也是云端⽐较热门

的应⽤。

业务特点：海量

如今移动社交类应⽤，相⽐早期的聊天类⼯具，在聊天内容上有

很⼤的变化。早期的聊天内容，偏向⽂字及聊天⼯具默认的⾃动表情

符号（不是如今各种搞笑的表情包）。⽽如今聊天内容不仅仅局限于

⽂字内容，还有朋友圈等功能包括⼤量的⾳频、短视频、图⽚等内

容。⽽且移动社交类的⽤户基数起点就很⾼，⽐如⼀个⼏万⽤户的⽹

站，其⽤户量对Web类应⽤来说已经不低了。但相⽐移动社交类，如

果仅有⼏万⽤户，那这个应⽤应该早就被下架了。所以移动社交类，

⽤户量⼤也是业务⼀⼤特点。以⽤户量⼤为基础，结合聊天、朋友圈

等功能，有海量的⽂字信息、⾳视频、图⽚内容存储。所以针对移动

类这⼀业务特点，我们在架构设计上有两个侧重点。

⼀⽅⾯，是⼤量的信息存储。传统关系型数据库已经应付不过

来，需要通过MongoDB、列存储等分布式数据库来进⾏存储。

另⼀⽅⾯，⾳视频、图⽚等半结构化海量数据，必然需要通过

OSS对象存储分布式⽂件系统来解决。特别是OSS中的图⽚处理、⾳

视频转码等功能，这是移动社交类中必不可少的业务需求，所以OSS

⼏乎成为移动社交类的标配。当然也可以在OSS的基础上，结合

CDN，对OSS中存储的⾳视频、图⽚等数据进⾏访问加速。

18.4 云端⾦融架构应⽤

早期作为阿⾥云架构师去拜访客户，被客户挑战及质疑最多的就

是安全问题。⽤云存储数据到底安不安全，客户担⼼核⼼数据不被⾃

⼰掌控，发⽣数据被泄露、被窃取等安全问题。特别是传统⾦融类应

⽤，更是拒绝上云。后来随着余额宝业务全部稳定运⾏在阿⾥云上，

以及互联⽹及云计算的发展，云计算成为企业级应⽤、互联⽹应⽤部

署的必备选项。⽽恪守成规坚持⽤IDC等物理机进⾏业务部署的企业所

带来的巨⼤成本，已经很难⽀持业务⾛得更远。

业务特点：安全

安全是⾦融类业务应⽤的代名词。相⽐传统互联⽹应⽤，⾦融类

应⽤对安全的要求更⾼。不过随着互联⽹的发展，明显的趋势是传统

⾦融也在向互联⽹⾦融转型。针对⾦融类业务在安全⽅⾯的要求，我

们在云端架构设计上主要分为以下⼏个⽅⾯。

为了满⾜银⾏、证券、保险、基⾦等⾦融机构对安全性的要求，

云端采⽤独⽴于公有云的机房集群来部署⾦融云平台，相⽐于传统的

公有云平台，在安全性、服务可⽤性和数据可靠性等⽅⾯作了⼤幅增

强。独有的⾦融云平台，是保障⾦融类应⽤架构部署的基础。⾦融云

的安全特性主要有如下三点：

1.安全合规

⾦融云按照⼈民银⾏和银保监会的合规标准建设，在安全性、服

务可⽤性和数据可靠性等⽅⾯做了⼤幅增强。

⾦融云建设和管理参照的⾏业标准有：《⾦融业信息系统机房动

⼒系统测评规范》《⾦融⾏业信息系统信息安全等级保护测评指南》

《银⾏业信息系统灾难恢复管理规范》《⽹上银⾏系统信息安全通⽤

规范》《商业银⾏业务连续性监管指引》《银⾏业⾦融机构信息科技

外包风险监管指引》《保险信息安全风险评估指标体系规范》《保险

公司信息系统安全管理指引（试⾏）》《证券公司⽹上证券信息系统

技术指引》《证券期货业信息系统安全等级保护测评要求》等。

2.与公共云差异明显

⾦融云与公共云在产品与服务上存在着明显差异，两者的对⽐如

表18-1所⽰。

表18-1 ⾦融云与公共云安全性对⽐

3.⾦融云可以提供专享产品与服务

·独⽴的资源集群

·更严格的机房管理

·更⾼的安全容灾能⼒

·更严格的⽹络安全隔离要求

·更严格的访问控制

·遵从银⾏级的安全监管及合规要求

·专门的⾦融云⾏业安全运营团队、安全合规团队、安全解决⽅案

团队

·专门的⾦融云客户经理和云架构师

·更严格的⽤户准⼊机制

另外，安全类产品是保障⾦融类应⽤的标配。安骑⼠企业版专业

版保障系统层安全，这是系统层防御的必选项。WAF应⽤防⽕墙保障

应⽤层安全，这是应⽤层防御的必选项。⾦融类应⽤跟其他互联⽹应

⽤的区别在于其他互联⽹应⽤由于成本等原因前期不考虑使⽤WAF，

⽽⾦融类应⽤考虑到业务敏感性，基本上会选择WAF，以便让应⽤层

有安全保障。在⽹络层⽅⾯，DDoS⾼防IP可以根据⽹络攻击情况来选

择性进⾏添加。

在IT⽅⾯⾦融公司会有⽐较严格的安全流程控制管理，因此在实

施具体技术时，相应安全规范、安全加固也会细致许多。所以相应地

也要加强相关⼯作⼈员的安全意识，做好安全培训和安全管理⼯作。

Document Outline

推荐序

前言

绪言 云计算带来的技术变革

第一篇 云端选型篇

第1章 云平台的选型

1.1 全球云厂商占比

1.2 国内云厂商的现状

1.2.1 阿里云

1.2.2 腾讯云

1.2.3 华为云

1.2.4 百度云

1.2.5 其他云厂商

第2章 云产品的选型

2.1 阿里云产品概要

2.2 云产品的8/2选择原则

2.2.1 五个技术优势

2.2.2 两个非技术优势

2.2.3 选择自建环境的条件

第3章 软件技术选型

3.1 “宇宙最火”的语言

3.2 硬件的天下

3.3 “后台强大”的语言

3.4 “胶水语言”

3.5 “世界上最好”的语言

3.6 最适合高并发的语言

3.7 唯一的前后端语言

3.8 不可替代的机器语言

第4章 系统技术选型

4.1 云端网络的三种选型策略

4.1.1 策略一：网络类型选型的五个注意点

4.1.2 策略二：入网请求选型的四种方法

4.1.3 策略三：出网请求选型的三种方法

4.2 云端Web服务器的五点选型考虑

4.2.1 考虑一：稳定性

4.2.2 考虑二：性能

4.2.3 考虑三：对负载均衡功能的支持

4.2.4 考虑四：前端静态数据缓存

4.2.5 考虑五：丰富的插件及支持灵活的二次开发

4.3 云端负载均衡选型的五个方面

4.3.1 对比方面：四大热门负载均衡的优缺点

4.3.2 分类方面：五大类型负载均衡的原理场景详解

4.3.3 演变方面：负载均衡的两种演变

4.3.4 性能方面：负载均衡隐藏的性能秘密

4.3.5 选型方面：云端负载均衡的两种选型

4.4 云端存储的四种类型

4.4.1 类型一：块存储

4.4.2 类型二：共享块存储

4.4.3 类型三：共享文件存储

4.4.4 类型四：对象存储

4.5 云端缓存的两大选型秘籍

4.5.1 秘籍一：云端静态缓存唯一的选型

4.5.2 秘籍二：云端动态缓存唯一的选型

4.6 云端数据库选型的三个方面

4.6.1 分类方面：数据库的三大分类

4.6.2 性能方面：数据库的性能秘密

4.6.3 选型方面：云端数据库选型的两点考虑及一个步骤

第5章 配置选型

5.1 衡量业务量的指标

5.1.1 一台Tomcat跑两亿PV的笑话

5.1.2 衡量业务量的指标

5.2 业务访问量与性能压力指标的转换

5.2.1 指标转换原理

5.2.2 性能指标转换计算模型实践

5.2.3 业务指标转换计算模型实践

5.3 云端服务器配置模型

5.3.1 PV量对应的服务器配置

5.3.2 服务器CPU/内存配置模型

5.4 云端带宽配置选型

5.4.1 带宽配置估算模型

5.4.2 带宽类型选择的8/2原则

第二篇 云端实践篇

第6章 云主机实践

6.1 云网络下的业务新架构

6.2 云的技术本质优势

6.2.1 云主机与硬件服务器性能对比的误区

6.2.2 云的本质优势在于分布式架构

6.3 云时代下的资源自动化管理

第7章 云端负载均衡实践

7.1 “1+1>2”经典架构

7.2 单机+SLB架构的必要性

7.3 被LBHA误导的架构

7.4 DNS的两大主流实践

7.4.1 实践一：不推荐DNS作为负载均衡的误区

7.4.2 实践二：DNS不为人知的核心秘密功能

7.5 企业级Web架构实践

7.6 企业级负载均衡架构实践

7.6.1 七层SLB性能实践案例

7.6.2 互联网企业负载均衡架构实践

7.6.3 云端负载均衡中小型架构实践

7.6.4 云端负载均衡中大型架构实践

7.7 通过代理+VPN提速跨国际网络访问

7.7.1 跨国际网络访问的延时问题

7.7.2 解决跨国际网络访问的代理架构

7.8 通过反向代理提速跨国际网站访问

7.8.1 方案一：双域名反向代理架构方案

7.8.2 方案二：单域名反向代理架构方案

第8章 云端存储实践

8.1 云端块存储八大实践技巧

8.1.1 提升云盘I/O的三大技巧

8.1.2 云盘使用的五大技巧

8.2 云端共享文件存储的五种方法

8.2.1 方法一：Rsync文件共享实践

8.2.2 方法二：Rsync+Inotify文件共享实践

8.2.3 方法三：NFS文件共享实践

8.2.4 方法四：NAS文件共享实践

8.2.5 方法五：OSS文件共享实践

8.3 OSS文件管理的六大技巧

8.3.1 技巧一：使用API接口/SDK管理OSS

8.3.2 技巧二：使用阿里云管理控制台管理OSS

8.3.3 技巧三：使用图形化工具管理OSS

8.3.4 技巧四：使用本地文件系统挂载管理OSS

8.3.5 技巧五：使用FTP管理OSS

8.3.6 技巧六：使用命令行工具管理OSS

8.4 四招搞定OSS数据迁移

8.4.1 第一招：OSSImport工具

8.4.2 第二招：OSS在线迁移服务

8.4.3 第三招：跨区域复制

8.4.4 第四招：OSS离线迁移

8.5 运维容灾备份新篇章

第9章 云端缓存实践

9.1 使用静态缓存提升网站性能的四种方法

9.1.1 方法一：浏览器缓存

9.1.2 方法二：磁盘缓存

9.1.3 方法三：内存缓存

9.1.4 方法四：CDN（动静分离）

9.2 动态缓存的三种应用场景实践

9.2.1 场景一：数据库缓存

9.2.2 场景二：集中Session管理的六种策略

9.2.3 场景三：四招搞定动态页面缓存

第10章 云端数据库实践

10.1 垂直拆库三大应用场景实践

10.1.1 场景一：垂直拆库的应用实践

10.1.2 场景二：主从的四种实践方案

10.1.3 场景三：集群技术的应用实践

10.2 水平拆表三大应用场景实践

10.2.1 场景一：业务层水平分区拆表的三种方式

10.2.2 场景二：数据库层次水平分区拆表的方法

10.2.3 场景三：四大成熟分布式Sharding技术方案

第11章 云端运维实践

11.1 上云迁移的实践

11.1.1 上云的诉求

11.1.2 前期技术调研

11.1.3 三大运维痛点

11.1.4 上云迁移的挑战性

11.1.5 七步搞定上云迁移

11.1.6 上云前后的对比

11.2 混合云八大运维架构实践

11.2.1 混合云实践1：基于VPC+专线构建混合云架构

11.2.2 混合云实践2：RDS自建主从同步在混合云中的实践

11.2.3 混合云实践3：MongoDB副本集在混合云中的实践

11.2.4 混合云实践4：RabbitMQ+SLB高可用实践

11.2.5 混合云实践5：云端自建DNS实践

11.2.6 混合云实践6：Redis主从+Sentinel+Consul+DNSmasq高可用实践

11.2.7 混合云实践7：MySQL主从+Consul+DNSmasq高可用实践

11.2.8 混合云实践8：关于DNS的高可用

11.3 云端运维架构五大优化

11.3.1 优化一：云端配置选型

11.3.2 优化二：云端网络架构

11.3.3 优化三：云端负载均衡的选择

11.3.4 优化四：云端静态资源访问

11.3.5 优化五：云端运维管理

第12章 云端监控实践

12.1 物理机体系：三大监控方案实践

12.1.1 监控方案一：Shell/Python

12.1.2 监控方案二：Nagios

12.1.3 监控方案三：Nagios+Cacti

12.2 云计算体系：四大监控方案实践

12.2.1 监控方案四：Zabbix

12.2.2 监控方案五：云监控

12.2.3 监控方案六：驻云监控1.0（集群监控）

12.2.4 监控方案七：驻云监控2.0（自动化监控）

12.3 容器体系：四大监控方案实践

12.3.1 监控方案八：Prometheus+Alertmanager+Grafana

12.3.2 监控方案九：TICK技术栈

12.3.3 监控方案十：驻云监控3.0（容器体系监控）

12.3.4 监控方案十一：驻云监控3.1（智能监控）

第13章 云端容器/DevOps实践

13.1 云端容器技术的十二大实践

13.1.1 容器实践1：关于云端容器资源编排技术的选择

13.1.2 容器实践2：结合K8S的DevOps流程

13.1.3 容器实践3：关于K8S集群的配置

13.1.4 容器实践4：K8S云端部署架构

13.1.5 容器实践5：K8S插件之DNS

13.1.6 容器实践6：容器的Web管理控制台

13.1.7 容器实践7：K8S业务应用+自建DNS实践

13.1.8 容器实践8：K8S Master节点高可用

13.1.9 容器实践9：K8S Node节点高可用

13.1.10 容器实践10：K8S部署架构优化

13.1.11 容器实践11：自建K8S迁移阿里云K8S托管版+Rancher

13.1.12 容器实践12：K8S监控实践

13.2 DevOps发展的四个阶段

13.2.1 人工阶段

13.2.2 脚本及工具阶段

13.2.3 平台化阶段

13.2.4 智能化阶段

第三篇 云端安全篇

第14章 云端安全面临的挑战和机遇

14.1 云端安全问题的现状

14.2 云端安全面临的三大挑战

14.2.1 挑战一：安全行业状态不容乐观

14.2.2 挑战二：云端安全环境复杂化的挑战

14.2.3 挑战三：安全对云优势的冲击

14.3 云端安全带来的两大机遇

14.3.1 机遇一：云计算、大数据将成为安全体系的基础核心保障

14.3.2 机遇二：政策驱动叠加，使得行业将迎来爆发

第15章 云端黑客常见攻击

15.1 什么是黑客

15.2 黑客入侵的途径：漏洞

15.3 黑客入侵流程

15.4 黑客常见系统层攻击

15.5 黑客常见应用层攻击

15.6 黑客常见网络层攻击

第16章 云端安全最佳防御方案

16.1 云端常见黑客攻击的防御

16.1.1 四款热门的云端安全产品

16.1.2 安骑士、WAF、态势感知三大使用误区

16.1.3 DDoS和WAF三大实践技巧

16.2 云端安全架构四大策略实践

16.2.1 策略一：云平台架构模式选择

16.2.2 策略二：分布式架构是安全保障的基石

16.2.3 策略三：全面开启云产品的安全机制

16.2.4 策略四：基于VPC的企业级安全架构

16.3 云端运维安全实践十则

16.3.1 第一则：云端堡垒机的三种实践

16.3.2 第二则：运维用户管理

16.3.3 第三则：密码安全管理

16.3.4 第四则：防火墙安全管理

16.3.5 第五则：端口安全管理

16.3.6 第六则：云端开源WAF实践

16.3.7 第七则：云端数据安全传输的标准

16.3.8 第八则：运维安全性能调优的三种方法

16.3.9 第九则：通过冷备及热备进一步保障云端数据安全性

16.3.10 第十则：加强安全巡检及安全培训管理

16.4 云端防御综合案例总结

第四篇 云端架构篇

第17章 云端千万级架构的演变

17.1 架构原始阶段：万能的单机

17.2 架构基础阶段：物理分离Web和数据库

17.3 架构动静分离阶段：静态缓存+对象存储

17.4 架构分布式阶段：负载均衡

17.5 架构数据缓存阶段：数据库缓存

17.6 架构扩展阶段：垂直扩展

17.7 架构分布式+大数据阶段：水平扩展

第18章 云端架构的应用

18.1 云端电商架构应用

18.1.1 业务特点：活动

18.1.2 业务特点：商品图片

18.2 云端游戏架构应用

18.3 云端移动社交架构应用

18.4 云端金融架构应用