本文共 2911 字,大约阅读时间需要 9 分钟。
1.前言
上一篇我们讨论了,介绍了如何根据应用的主要查询需求合理地设计数据分区存储方案,从而有效地提升系统的性能和扩展性.这一篇也是属于提升系统性能有关的,那就是静态内容托管.
2.概念
顾名思义,静态内容托管就是把动态内容静态化.网页通常都是动态页面,页面加载需要从数据存储中查询数据并加载到前端,然后呈现给用户.然而,云端的应用往往并发量很大,给数据库查询带来很大的压力,而很多页面所请求的数据很多时候是相同的,这时候就可以考虑使用静态内容托管的模式了.
这种模式节省计算资源,从而提升数据运算的效率,也给用户带来更好的体验.虽然web服务器已经在动态页面展示方面进行了很多的性能优化,甚至使用上了缓存技术,但是web网站还是避免不了要下载静态内容到客户端.在托管在云端的应用中,可以通过把应用所依赖的静态资源存储在云端,使用存储服务来获取的方式来使应用对计算服务的请求降到最低.因为云端的存储服务相对于计算服务来说,价格低廉很多.
在运算部署这种应用的时候,最需要考虑的就是云应用所依赖的资源必须是安全可靠的,匿名用户必须是无权访问这些资源的.
3.需要考虑的问题
1) 存储服务所存储的资源必须暴露出Http服务的Endpoing可供访问.
2) 为了最大化地提升性能,最好在全球各大数据中心使用Content Delivery Network(CDN)来缓存静态内容,实现加速.
3) 存储账户在全球各个数据中心之间是复制的,避免因为某个数据中心出现事故而受影响.
4) 当某些资源是静态化的,但是另一部分是需要调用计算资源的,那么这种应用的部署是最需要仔细考虑的.
5) 存储服务可能不支持使用自定义域名的使用.(不太明白)
6) 存储静态资源的容器(Container)必须有public 读取的权限,而一定没有public 写入的权限.
4.何时使用该模式
1) 最小化网站的费用(网站包含静态内容)
2) 需要通过CDN获取分布于全球的数据中心的静态资源.
5.案例
Windows Azure Object Storage 就是一个很容易在浏览器端获取的存储服务.在Windows Azure 中任何以对象存储的资源都可以在外部通过Http的URL的方式访问该资源:
http://[ storage-account-name ].blob.core.windows.net/[ container-name ]/[ file-name ]下面的图展示了这种模式:
在上图中,一个image资源的访问方式如下:
其实很多实用应用会使用外部存储和container来存储资源,下面演示了如何使用配置的方式配置外部的存储.
在Azure中有一个Setting类来处理配置参数的获取.
public class Settings{ public static string StaticContentStorageConnectionString { get { return RoleEnvironment.GetConfigurationSettingValue( "StaticContent.StorageConnectionString"); } } public static string StaticContentContainer { get { return RoleEnvironment.GetConfigurationSettingValue("StaticContent.Container"); } } public static string StaticContentBaseUrl { get { var account = CloudStorageAccount.Parse(StaticContentStorageConnectionString); return string.Format("{0}/{1}", account.BlobEndpoint.ToString().TrimEnd('/'), StaticContentContainer.TrimStart('/')); } }}这个类里面会提供基础的URL来获取资源,按照惯例,我们会有一个静态资源管理的类.
public static class StaticContentUrlHtmlHelper{ public static string StaticContentUrl(this HtmlHelper helper, string contentPath) { if (contentPath.StartsWith("~")) { contentPath = contentPath.Substring(1); } contentPath = string.Format("{0}/{1}", Settings.StaticContentBaseUrl.TrimEnd('/'), contentPath.TrimStart('/')); var url = new UrlHelper(helper.ViewContext.RequestContext); return url.Content(contentPath); }}这里是通过扩展HtmlHelper做到的,在前端我们可以像使用HtmlHelper一样调用静态资源.
6.相关阅读
The following pattern may also be relevant when implementing this pattern: