本文讲述了动态在线文档 SaaS 产品(以下简称 DynamicPPTService)在前期云平台选型的考虑因素、业务发展后出现的问题,以及系统迁移到 Azure Service Fabric 平台上进行微服务化的实施过程。最终,技术团队实现了用微服务化架构精细化管理系统的目的。同时也发现,微服务架构并不能让系统“显著瘦身”,因为一些应用无法微服务化,所以采用微服务架构增加了额外的云计算资源。
背景
DynamicPPTService 属于一家提供在线动态文档服务的美国科技公司,客户包括 PayPal,TIAA,Fidelity 等上百家美国知名金融服务机构。用户使用 DynamicPPTService 来设计符合自己风格样式的 PowerPoint 模板,连接数据动态生成最终文档。银行、保险行业用户对 X 产品有强烈的需求,因为他们服务的客户对数据高度敏感,所有他们需要展示与客户密切相关的数据,例如为客户量身定制保险计划或者投资组合等。奥博杰天(中国)的技术服务团队全权负责该产品的网站、SaaS 平台、手机 app 等产品的研发和技术支持工作。
DynamicPPTService 从 2010 年开始在 Azure 云上线以来,X 产品业务以每年 100% 以上的速度快速攀升。经过近 7 年的高速发展,不断增加的业务需求已经对现有的系统技术架构带来了巨大挑战,系统架构的升级改造势在必行。
挑战
DynamicPPTService 服务端托管在 Azure 的 PaaS 平台 Cloud Service 上,遵循 Cloud Service 的 Web Role 和 Worker Role 部署模式。在 Azure platform 中,Role 是一个提供特定服务的应用程序,每一个体都是一台虚拟机,因此每个 Role 都有完整的虚拟机资源。Web Role 在它的虚拟机设定内包含了 IIS 以及必要的功能,用来处理通过 http 和 https 访问的 web 请求。因此我们把用户工作区 (workspace),资源管理 (admin),动态报表管理 (doc center, library) 等提供 web 页面访问的模块都放到 Web Role。
Worker Role 适合用来挂载无使用者界面、以服务为主的应用程。我们把报表的处理 (construction),文档生成 (conversion), 消息发送(livesend, notification)等需要消耗时间的后台应用放置到 Worker Role。系统使用 Azure 的 SQL 服务存放用户上传的数据, 用 Blob Storage 存放用户生成的模板和上传的图片资源,用 Table Storage 存放一些系统配置和操作日志。还使用到 In Role Cache 作为数据缓存。
(点击放大图像)
最初决定使用 Azure PaaS 作为托管平台而没有选择 AWS 或其它厂商,主要处于四点考虑:
- Azure 在 PaaS 层的功能要强于其它厂商,界面操作也比较友好;
- 生产服务器并不直接部署,而是在新版本的测试完成后与“staging slot”交换,这意味着可以做到零停机时间;
- 微软的 Silverlight 来搭建系统界面, 能方便地支持多终端展示(从项目实际效果来看这一点的优势并不特别明显);
- 我们认为使用 Visual Studio + WCF 框架编程能带来比 Java 更高的开发效率, Java 工程师掌握 C# 的学习曲线也不太大。
注:在 Azure Cloud Service 中,提供了两个 deployment slot,生产 (production) 和分期 (staging)。在大多数应用环境中,我们通常对应一个 staging 环境 (用于上线前测试确认) 和一个生产环境。需要注意的是,运行 production 和 staging slot 都是收费的。参考.
这几年随着 DynamicPPTService 业务的发展, 服务端增加了更多的功能。 日益增大的用户访问量,也给旧系统带来了很大的挑战。 比较突出的几个问题是:
- 系统耦合度高,不利于协同工作。 由于功能变多,有前后台多个团队在共同维护代码,系统上线频繁。虽然也使用 Git 作为代码库,每次上线还是需要花大量的时间解决代码冲突,达不到敏捷开发的效果。
- 资源使用效率不高。例如 Web Role 中一些不频率使用的应用由于都打包在同一个 Role 中,被重复部署到多台虚机上。
- 使用的 In Role Cache 服务微软已经不再维护,需要替换。
注:In Role Cache 是 Azure 刚上线时提供的分布式 Cache 解决方案,微软宣布将于 2016 年 12 月 30 日停止对它的技术支持,建议大家改用推出不久的 Azure Redis Cache。参考.
方案
针对这些暴露出来的问题, 我们开始着手设计 DynamicPPTService 的新架构。技术上要达到的目标:
- 提高资源利用率。
- 降低系统耦合度,满足架构不断添加的新功能和模块。
- 最大化使用 Azure 提供的云计算特性, 尽量减少人工维护工作。
- 用 Azure Redis Cache 替换已经不支持的 In Role Cache 服务。
- 新增数据分析分析服务,它负责提供搜索和推荐功能。
我们认为使用微服务的框架能很好的解决系统耦合的问题。如果使用了微服务架构,就可以按需对个别服务实例数量进行增减,通过优化资源配置来提升系统整体性能。
经过讨论,我们可选的方案有三个:
方案一,将原系统拆分成多个独立的 service,延用之前 Azure Cloud Service 的 role 部署模式,每个 service 部署在一个 Web Role 或者 Worker Role 中。 这样带来的问题是每个 service 就要占用一个虚拟机。如果考虑高可用性,每个 service 至少要有 2 个以上实例,那整个集群使用的虚机数量还要翻倍。虽然单机使用的资源会比原来低,但是不足以抵消购买更多虚机所花的费用。
方案二,将原系统拆分成多个单独的 service,使用 Azure 推出不久的 Service Fabric 集群管理框架来适应微服务架构。 Service Fabric 类似于 AWS 的 BeanStalk,我们只需管理好自己的应用代码,其它的资源需求都可以交给 Service Fabric 去管理。它吸引我们的特性是:
- 微服务集群管理。提供集成界面对服务进行管理和监控,方便精细化控制系统服务。
- 高的密度的微服务部署方式。单个节点(虚机)可以托管多个服务。
但是如果使用 Service Fabric 也会带来两个问题:
-
第一,它不自带 IIS 支持。Web Role 中的应用要切换到 Service Fabric 要么能自带 HTTP 服务,要么使用 ASP.NET Core MVC 框架。这样做会牵涉到很多代码改动,工作内容涉及多个开发和测试团队。
注:ASP.NET Core MVC 默认使用 Kestrel 作为 HTTP 服务器。(参考)
-
第二,Service Fabric 中每个服务都必须独占虚机的端口。由于多数 web 服务都使用了 80 和 443 端口,这就造成了不同的服务只能部署到不同的虚机上,不能利用到 Service Fabric 单个节点可以托管多个服务这一优势。虽然 Azure 建议可以使用反向网络代理来解决这个问题,但是打开反向代理会把它后面所有 end point 的 http 端口暴露,会有安全隐患。
注: 关于 Azure 反向代理的内容,参考.
所以从我们掌握的知识来判断,用 Service Fabric 来替代 Web Role 管理前端服务,技术上优势并不明显。
方案三,考虑到方案二的限制,将 Worker Role 中的 construction, live send 和 notification 后台服务迁移到 Service Fabric 上,新增的数据分析服务也部署在 Service Fabric 上。原 Web Role 中的服务进一步拆分成 web 响应服务和后台 API 服务,将后台 API 服务部署到 Service Fabric 上,前端 Web 响应服务迁移到能更好支持 IIS 的 Azure App Service。这样的好处是:
- Worker Role 中的服务迁移改动小(只需要在调用启动服务的接口代码处进行稍微修改)。
- Web Role 中的应用迁移到 App Service 也基本不用改动。
- Web Role 中由于消耗资源的服务被迁移到 Service Fabric,剩下的 web 响应服务需要的云计算资源会减少。
方案三的系统架构如下图:
(点击放大图像)
实现
为了稳妥起见,我们决定采用方案三,分两步来吃螃蟹。第一步把 Worker Role 中的服务进行迁移,等上线正常后再进行第二步 Web Role 中服务的迁移。
第一步的重点在于需要将 Worker Role 中服务的代码进行改写。 由于 Worker Role 中代码框架结构和 Service Fabric 中代码结构基本类似,只是服务启动接入点方法从原来的 RoleEngryPoint 中的 Run() 方法改变为 StatelessService 中的 RunAsync。
(点击放大图像)
(点击放大图像)
经过 6 个月的重新部署,我们完成了 DynamicPPTService 微服务版本在 Service Fabric 上部署并顺利上线。 新版本上线后,通过 Service Fabric 的控制台我们能很好的管理系统的每个微服务,达到了设计预期。
不过实际减掉的云计算资源并没有预想的多,旧架构使用了 4 台 8core 56G 内存 服务器 (Azure 型号 D13) 运行 Web Role 应用, 6 台 2core, 8G 内存 服务器 (Azure 型号 D2) 运行 Worker Role 应用,6 台 D2 服务器运行 conversion 模块需要的 windows office 组件。使用微服务架构后,除去 App Service 按使用量计费,Service Fabric 集群使用了 5 台 D13 服务器。Conversion 模块需要调用 office 的资源必须运行在 window 的虚机上无法微服务化, 6 台 D2 服务器保留。 所以,如果把省掉的 6 台原 Worker Role 服务器和新增租用 App Service 所用的资源抵消,迁移到新架构后,还多使用了 3 台 D13 服务器。我们最终的架构如下图:
(点击放大图像)
总结
在 DynamicPPTService 架构升级的这个项目中。我们运用了微服务的架构设计原则,结合 Azure 的技术特性,很好的完成了架构扩展,解决了业务发展带来的技术挑战。技术团队很好的判断了 Azure Service Fabric 还有不完美的地方 (例如不支持 IIS、每个 node 节点部署的 service 都会占用一个独立端口) ,在架构设计时合理的避开这些技术劣势,充分发挥了 Service Fabric 擅长高密集度、精细化管理服务的优势。在实际部署中,因为有些应用不能微服务化,需要给它们保留资源,所以使用微服务架构并不能明显降低原系统所占用的资源。
作者介绍
李祎 ,曾担任惠普云部门 (Cloud BU) 解决方案架构师,卓望信息技术公司负责移动旗下网站www.139.com,shop.10086.cn,pim.10086.cn 系统架构,源讯 (Atos Origin) 开源软件专家全程参与 2008 奥运 IT 集成项目。现就职于奥博杰天技术有限公司担任解决方案架构师,公司卓越技术委员会 (TEC) 成员。 关注 PaaS 应用,云迁移等云计算领域的新技术和新产品应用。
感谢孟夕对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们。
评论