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资源的访问方式如下:

<img src="http://mystorageaccount.blob.core.windows.net/myresources/image1.png"
     alt="My image" />
其实很多实用应用会使用外部存储和container来存储资源,下面演示了如何使用配置的方式配置外部的存储.

<Setting name="StaticContent.StorageConnectionString" 
         value="UseDevelopmentStorage=true" />
<Setting name="StaticContent.Container" value="static-content" />
在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一样调用静态资源.

<img src="@Html.StaticContentUrl("~/Images/orderedList1.png")" alt="Test Image" />
6.相关阅读

The following pattern may also be relevant when implementing this pattern:

  • Valet Key Pattern. If the target resources are not supposed to be available to anonymous users it is necessary to implement security over the store that holds the static content. The Valet Key pattern describes how to use a token or key that provides clients with restricted direct access to a specific resource or service such as a cloud-hosted storage service.






Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐