云服务是Azure上最重要的PaaS服务之一。相比于使用IaaS虚拟机,使用云服务会带来如下好处:
- 单点发布应用
- 与开发工具无缝集成,一键发布应用
- 应用自动部署
- 分钟级实现系统规模扩容、收缩
- 按照策略进行弹性伸缩(自2013年6月29日起)
- 灵活切换生产、过渡环境
- 自动收集性能数据和诊断信息
- 无需对OS及补丁进行管理
将一个普通Web应用发布为云服务也相当的简单。Azure为.NET/PHP/Java/Node.js/Python这些语言提供了开发环境集成,或者是发布工具。如果应用是采用这些语言开发的,而且可以运行在Windows Server上,那么基本上就可以以云服务的形式发布。为了让应用更好的运行,在应用发布之前,需要经过一些改造,这种改造的程度,取决于应用的架构和部署方式。
改造工作的目的,是让云服务符合互联网应用开发的最佳实践,即:无状态、多实例并发、自动化管理:
- 无状态的含义,是计算节点的无状态。状态信息(包括业务数据)全部存储在独立的存储服务上:SQL数据库、Blob、Table等。这样的好处,是计算和存储分离,可以独立扩展,同时也解决了数据分散在不同节点上这一弊端。计算节点无状态后,Azure可以快速增加或减少计算节点数量而不会影响应用运行,而单一计算节点的故障也不会影响系统运行。这种无状态设计可以同时提高系统可用性和可扩展性
- 多实例并发的含义,是任意一个组件都可以线性水平扩展,系统的处理能力不会受到单一一个组件处理能力的限制。那个组件处理能力不够了,增加其虚拟机实例数量即可。同时多实例运行可以天然消除单点故障,提供系统可用性
- 部署过集群的人都会明白管理一堆机器是多么麻烦。多实例解决了系统扩展性的问题,但带来了管理的难题。对于大规模分布式系统来讲,理想的管理方式是自动化管理。
如果我们把Azure看成一个云OS,那么每个处理请求的虚拟机就是一个“CPU”,Azure各种存储服务就是“硬盘”,连接各种节点的网络就是“总线”,云服务的部署过程就是这个云OS加载应用的过程。用户不需要关注应用是如何加载到每个“CPU”上的,只需要按照Azure的格式准备发布包,剩下的发布过程都是自动完成的。在云OS下,“CPU”数量(虚拟机实例数)是动态可调的,“CPU”可以动态更换,一个应用可以在多个“CPU”上并发执行
下图是一个Azure云服务的典型部署架构。图中的Web节点和Worker节点数可以灵活调整,而所有状态信息和数据都在计算节点之外。Web和Worker节点之间的通信,也是通过存储(比如Queue)来中转。
对于一个应用来说,跟状态和多实例相关的功能主要包括文件、缓存、session等。下面这张表,描述了不同情况下应用需要进行的改造:
场景 | 改造方式 | 说明 | 工作量 |
1.应用会向Windows文件系统读取、写入文件 | |||
1.1. 读取、写入配置文件 | 改造配置读写模块,将配置信息放在云服务的cscfg文件中,或是数据库中,或是Blob存储的文件上 | 这样的做的好处是,可以在运行时从单点修改配置,而且配置可以实时生效。否则,配置文件只能通过重新发布应用生效 | 小 |
1.3. 读取、写入数据文件 | 改造文件读写模块,将数据文件存储在Blob存储上 | 如果不改造,会造成写入的文件丢失 | 中 |
1.4.写入日志 | .NET可使用System.Diagnostics.Trace进行日志收集 | 这样可以借助Azure的诊断模块自动将日志收集到一个Table存储里 | 小 |
2.应用的某一组件只允许一个实例 | 利用Queue-Worker模式,将该组件改造为多实例并发运行。每个Role至少可运行2个实例 | 不改造的话会影响应用可用性,并且限制应用的可扩展性 | 中 |
3.Azure部署包准备 | 配置csdef,定义Web/Worker Role 配置cscfg,填入配置信息 | 最终应用的所有功能都将归入两类实例:Web Role和Worker Role。前者用来执行即时请求,后者处理非即时请求 | |
3.1 应用提供Web、REST等即时服务,运行在IIS上 | 增加一个或多个Web Role。每个Role提供一种服务 | 小 | |
3.2.应用的某些功能不是由Web驱动,而是定期执行或者异步执行,如批处理、Windows服务 | 增加一个或多个Worker Role,并定义其Run和OnStart方法。每个Role的多个实例可以均匀的获得任务,任务执行失败可以被其他实例继续执行。对于长时间运行的任务,最好支持断点恢复 | Worker Role也要做成无状态的,即任务输入和输出都尽量不存储在计算节点上。建议的方式是:控制指令通过Queue存储,数据通过数据库或Blob存储 | 小 |
4.应用部署依赖 | |||
4.1需要预先安装某些软件 | 在csdef中定义启动脚本,进行软件的自动下载和静默安装 | 中 | |
4.2需要修改注册表、注册COM组件 | 在csdef中定义启动脚本,进行系统配置的更改 | 小 | |
5. 应用使用了session,session在服务器端实现,并需要负载均衡支持session affinity | 配置session的持久化,使用数据库、Table或Caching存储session数 | ||
6. 应用使用了Cache | 如使用memcache,则将其替换为Azure Caching 如自行管理cache,建议替换为Azure Caching | Azure Caching是类似于memcache的分布式缓存 | 小 |
7.应用部署包大小超过10M | 将静态文件剥离,减小发布包大小。这些静态文件包括:图片、视频、库Dll等。剥离的文件可以打包放在Blob存储上,然后在云服务的csdef启动脚本中自动下载 | 减小部署包的好处是加快发布过程,避免在网络传输上的延迟 | 小 |
8.应用使用了内存锁进行线程/进程同步 | 采用分布式锁,比如Zookeeper/Redis锁;或者用轮询的方式去检测一个单一资源,如某个数据库字段、存储对象或者Cache数据 | 锁的应用一般是为了协调多个进程/线程的执行。在分布式环境下,这种协调也需要在所有结点间完成 |
以上这张表,并不是每个应用都会涉及。大部分应用只需要进行Web Role和Worker Role的定义即可
在改造完成后,即可按照不同的语言进行应用的发布:
- .NET: https://github.com/WindowsAzure-TrainingKit/HOL-DeployingCloudServices-VS2012/blob/master/HOL.md
- Node.js: http://www.windowsazure.com/en-us/develop/nodejs/tutorials/getting-started/
- Python: http://www.windowsazure.com/en-us/develop/python/tutorials/django-with-visual-studio/