从后端来讲,新浪微博可以分为Java和LNMP两大体系,特别是在LNMP方面积累了很多经验。发展初期,新浪微博侧重从性能角度出发,做架构方面的调整和优化。近两年,它投入人力、物力,把重点放在了弹性扩容方面。
本文由在新浪微博工作近七年、现任主站研发负责人的侯青龙分享新时代下的 LNMP 架构,基于混合云平台的 PHP 弹性扩容部署方案,以及具体维护过程中遇到的挑战。
新浪微博遭遇流量峰值挑战
新浪微博作为社交产品,经常出现因某些原因所致的话题突发流量峰值,且峰值不可预估。例如:
- 紧急突发事件:白百合出轨、周一见、宝宝离婚、女排夺冠
- 大型活动及三节保障:红包飞
- Push 推送:运营的各种站内,站外 push
话题业务的流量特点
话题业务的特点是平时流量比较平稳,波动很小,一旦出现突发事件,10 分钟时间流量就会突增 2-3 倍。像这样的流量,一般持续时间不会长,约 1 个小时左右。
从架构角度,如何处理?
新浪微博在做架构调整之前,和很多公司的处理方案都相似,采用设备冗余与服务降级两大传统手段。
设备冗余。各业务提前申请足够的设备保证冗余,正常情况下一台服务器 CPU 约在 20%-30% 左右,当峰值到来会达到 60%-70%,系统就会严重警告,需要做服务器扩容。一般情况下,系统会准备一倍左右的冗余。但这就存在一个问题,流量如果翻三倍、四倍怎么办?
服务降级。当突发流量峰值,系统将对非核心业务以及周边业务进行降级,PC 主站只保留主 feed。内部降级的方式有很多,降级后用户基本感觉不到。如极端情况下,系统一定主要保留微博主站,其他功能模块全下线,进而保证服务不会挂掉。
但从公司、老板层面,肯定不愿意出现这样的情况,因为降级对广告的影响很大。但是在传统架构下,面对突然产生的流量,技术只能这样做。
这两种传统手段,面临一系列的扩容和降级难题:
- 设备申请周期长。如机房从其他业务挪用服务器,周期不会太长。但每年三节都会对常规流量进行预估,做好几倍扩容。假设机器不够,会发起采购,但周期会非常长。
- 扩缩容繁琐。如下图,当服务器到位,做扩容,又是一个繁琐流程,还需要多部门共同合作。
- 设备运营成本高。如每个业务都做一定的冗余,假设一百台服务器,要用二百台来保证正常运营,可以想象这个成本会非常高。举例,PC 和手机端,业务峰值不在一个点,峰值不在一起,利用率也有所差别,就算同一事件,每个业务的负载也会不一。
业务之间拆借,也是行不通。因为短时间内,无法应对服务器之间的环境差异、代码等差异,初始化完毕,峰值也消失了。
综上所述,扩容和峰值是面对突发流量峰值的两个解决维度,但存在的问题是扩容不能针对服务器快速扩容、降级又对服务器损害相对较大。
新浪微博决定从架构层面解决这两个问题,通过引入混合云 DCP 平台,达到下面的效果:
- 降低设备运营成本。不希望为冗余准备的大量设备,一年中的很多时间空闲。
- 实现业务弹性扩容。各个业务之间峰值不一样,可通过技术把环境抹平,实现随时化的自由调度。
新浪微博混合云DCP平台简介
DCP(Docker Container Platform)平台解决思路是从业务的弹性角度,在各业务之间,无论是 Java 还是 PHP 等,通过抹平所有的环境,快速应对峰值,同时在基础设施上支持跨云。之后,在内容服务器用完的情况下,可借用公有云这份解决方案,把流量峰值问题迁移到公有云。
业务弹性调度。如下图,是旧的应对手段和弹性扩容手段的对比。实现弹性扩容后,系统会使用容器化来抹平各业务环境,把各业务之间的冗余部分放到共享池。这样一来,哪个业务需要扩容,就可以很简单地从共有池把这部分设备扩容。
因各个业务之间的峰值和负载程度不一,把其他业务的冗余设备拆借过来,实际扩容能力相比以前的 1~2 倍,可以提升到 2-3 倍。
基础设施支持跨云。如下图,是私有云和公有云各自的优势。针对各自的特点,在部署流量时,需做一些侧重操作。如针对常规的流量,优先会部署到私有云,保障体验、性能等都是最优。这里涉及公有云安全性和私有云之间有一定差异以及在性能上会有一定下降的问题。
假设在公有云流量部署 1 小时,其中可能公有云一些服务还会依赖于私有云服务,这样就会出现跨机房调用的情况。可服务只是微慢,而不是降级或停用,和之前相比优势很大。
另外,假设把常规的负载也部署到公有云,只要把所有底层全部做多机房部署,根据不同业务做流量分配即可。
DCP 平台架构。如下图,是 DCP 平台抽象版架构,主要分为主机、环境、服务和业务四层:
DCP平台抽象版架构
- 主机层。这层的作用是假设需要扩容 50 台服务器,这些服务器可能来自内网、也可能来自公有云。上层在使用过程中,需要通过 Adaoter 来提供,优先内网,之后去公有云创建。
- 环境层。这层主要是编排的过程,封装众多的原则性行为的 API。
- 服务层。负责根据众多 API,组合搭建一个服务。
- 业务层。业务层通过负载均衡把流量引入服务器。
私有云“化零为整”。如下图,是一个基于 DCP 的模型,左侧是传统架构,假设长方形是每个业务需要的机器,如 A 业务要扩充两台,就承载不了,就需降级。右侧接入到混合云后,把所有业务的环境抹平,所有设备放到共享池,假设 C 业务需要三台设备,在新的架构下,可轻松从共有池选取。
基于混合云 DCP 平台的 PHP 服务 Docker 化
服务 Docker 化。Docker 是从逻辑层面虚拟化,把环境做镜像差异化从而进行快速部署。Docker 服务启动快,镜像一次制作,多次快速部署,尤其适合动态扩容部署。
PHP 服务 Docker 化的部署方案设计。如下图,粉色部分是 PHP 服务相关组件nginx、php-fpm、memcache、scribe 等,这些组件容器单独部署。像代码、配置、日志等经常变更,黄色部分通过挂载的方式和 Docker 容器互动。
镜像制作。镜像制作的步骤如下:
- 从镜像仓库中拉出 CentOS 作为基础镜像
- 运行镜像
- 在运行容器中安装 PHP 环境相关软件包
- 提交修改并推送至仓库
- PHP 服务镜像制作完毕
镜像方案。基于 CentOS 6.7 来制作镜像,将 PHP 服务组件拆成独立镜像。这里涉及到的问题是“镜像占用空间相对较大,每个都超过 1G 大小。同时拉取镜像耗时太久,占用宽带较高。针对这个问题,解决的办法是将 PHP 相关的组件制作成一个镜像,服务通过容器命令来启动。
在部署过程中,主要解决三大核心问题:首次部署、代码上线与配置变更。
首次部署,如下图是首次部署的流程,由 DCP 平台发起扩容,把扩容的数据和业务相关的文件配置好,全部发到前端机。每一个前端机基于配置文件,进行拉取代码、启动容器和服务查询等操作。
代码上线。如下图,通过镜像完成上线,代码镜像使用 busybox 为基础,大小仅1M。
创建代码镜像。如下图,创建代码分为 Dockfile,Build,下载代码镜像、启动容器、拷贝代码三步骤。
配置文件更新。如下图,把配置文件制作成 Docker 镜像,每台机器拉取镜像,替换配置文件,自定义脚本执行 reload。
这里值得提醒的一些细节有:
- Docker 化后,宿主机运行在 Centos7.0
- 内核升级到 3.10
- 容器中的启动命令需要前台启动
- 经常变更的部分放在镜像外,通过 volume 挂接容器
- 网络模式:选用 host 网络模式
- 容器的 reload 或优雅重启采用 dockerexec xx reload 方式
基于混合云DCP平台的PHP弹性扩容
说到弹性扩容之前,先说三个概念:服务、服务池、集群。如下图,服务可以理解为业务,像新浪微博的红包飞、问答等。服务池,就是业务会部署到哪个机房。集群就是来自内网或公有云上的闲置不属于任何业务的机器。
扩容流程。如下图,整个流程分为资源申请、环境初始化和服务上线三部分。管理员向混合云平台发起请求,之后完成设备、服务初始化的过程、调度中心对服务进行部署,包括代码的拉取。初始化完成后,通过服务上线,把4/7层流量切入,部署整个监控中心。
扩容模板。一个新业务需要支持弹性扩容,都需要在 DCP 平台配置,与之相匹配的是配置系统,如下图。镜像地址 image.1.6.1、所有服务器组件的参数、挂载的容器、代码的挂载位置、配置容器参数等都需要提前配置好。
流量切换。这里和阿里云合作非常多,把公有云已经初始化好的前端机 IP 加载到负载均衡中,自动重启、部署,无须人为操作。
弹性容量的考虑。Push 时,就要考虑扩容,针对某一事件在某一地区进行部署,基于以往的数据 ,评估系统预估需要扩容的服务器。还有稳定性高、低峰的服务,针对一些每天晚上 9、10 点出现流量翻倍的情况,实现自动扩,自动退。
扩容控制、效果。如下图是抗峰值,话题服务器的扩容过程以及完成后的内部效果。需要 16G 机器,50台,在扩容系统输入完成,五分钟搞定。大概15分钟左右,流量峰值被削平。
总结
本文结合架构图和数据图,详细介绍了 LNMP 服务的Docker化,如何制作PHP服务相关镜像,最后结合DCP平台完成PHP服务的首次部署、配置更改、代码上线等。
目前,新浪微博主站 TV 视频站、头条问答、话题、红包飞、通行证等 LNMP 项目已全量部署,方便弹性扩容。同时,也将继续推进 PC 主站服务的部署。
视频地址:http://edu.51cto.com/center/course/lesson/index?id=166147
以上内容根据侯青龙老师在 WOTA2017 “高可用架构”专场的演讲内容整理。
侯青龙
新浪微博主站研发负责人
侯青龙
,2010 年加入新浪微博,先后参与过微博主站 V2 版至 V6 版的研发,主导过主站 V6
版、多机房部署以及淘浪合作等重大项目的架构设计工作。目前,他负责 PC
主站研发工作,致力于提升产品研发效率以及优化系统性能,善于在业务需求和产品研发之间找到最大公约数。在基于 LAMP
架构的大型系统架构设计、海量数据访问、分布式缓存设计等领域具有丰富的经验。