ASP.NET Web 缓存增强性能和可伸缩性

 ASP.NET Web 缓存增强性能和可伸缩性

 

概览:
  • 瓶颈限制显著降低
  • 静态和动态 Web 缓存
  • 必备的功能:过期、数据库依赖关系、PDF 部分内容以及更多功能
  • 对全球组织的特殊好处
  • Web 缓存服务器群集
  • 免费和商用解决方案


 

基于 ASP.NET(Microsoft Web 应用程序框架)的应用程序对企业的影响日益增大。 同时,由用户和处理数量的不断增长而导致的瓶颈限制继续促使 IT 专家们寻求更为优异的性能和可伸缩性。


 

问题:ASP.NET 瓶颈限制
导致 ASP.NET 应用程序中出现瓶颈的原因有多种。 最明显的原因为:数据存储技术不如 Web 应用程序体系结构的伸缩性强。 当您试图扩展应用程序时,ASP.NET 应用程序中处理数据存储或数据访问的任何一个位置都将立即陷入阻塞状态。 发生这种情况的两个区域为:会话状态存储以及来自关系数据库或大型数据库的应用程序数据(请参见图 1)。
图 1 ASP.NET 应用程序中产生性能瓶颈的常见区域。
如果 ASP.NET 应用程序正在对 Web 服务进行面向服务的体系结构 (SOA) 调用,则会出现另一种瓶颈限制。 之所以会出现速度减慢的情况,是因为 Web 服务与 ASP.NET 应用程序存在同样的问题(也就是说,在数据存储和访问中)。 很可能是 Web 服务场正在跨多个应用程序共享,因此其受到的压力远远大于任何一个 ASP.NET 应用程序,从而造成了可伸缩性瓶颈。
用户浏览器和 ASP.NET Web 场之间也可能出现瓶颈。 由于 ASP.NET 页面需要反复执行,从而大量占用 CPU 处理能力,以上瓶颈现象的发生与此相关。 在该过程中还会向用户频繁发送大量数据元素(图像、文档等)。
TechNet 杂志之前的文章中,我讨论了 ASP.NET 性能和可伸缩性的问题,主要侧重于会话状态和应用程序数据(请参阅“为 ASP.NET 应用程序提供可伸缩性”,2009年 6 月)。 在这篇文章中,我介绍了这些问题发生的原因,其中包括 ASP.NET 会话状态为何会随着 Web 场的增长而陷入阻塞状态。 我在文中提到,对于 ASP.NET 会话状态,分布式内存缓存是 Microsoft 现有存储方案的绝佳替代方案。 我描述了来自数据库的应用程序数据如何会导致可伸缩性瓶颈。 我还详细描述了分布式缓存如何利用不同的缓存拓扑来解决 ASP.NET 会话状态存储瓶颈,这些不同的缓存拓扑可提供不同的功能,但均注重于可伸缩性以及确保 100% 的正常运行。
最后,我大致列出了市场上不同的分布式缓存方案。 一些方案虽免费提供但功能有限,另外一些方案则是功能更加强大丰富的商业产品。 出于最佳性能和可伸缩性考虑,购买领先的商业产品则更为明智。


 

解决方案:ASP.NET Web 缓存
本文将该问题的定义作为背景,主要侧重性能以及用户浏览器和 Web 服务器或 Web 场之间的可伸缩性瓶颈。 理想情况下,您希望减少网页自身执行的次数。 如果网页在执行一次之后其输出结果没有任何更改,则为何要再次执行该网页? 为何不只是缓存输出? 这样用户即可在下一次直接从缓存中提取页面输出,而不是重新执行该页面。 重新执行页面会占用 CPU、消耗内存并需要使用其他 Web 服务器的资源,当然,还会造成数据存储的可伸缩性瓶颈问题。
ASP.NET 页面输出可缓存在 Web 服务器本身;Microsoft 提供的 ASP.NET 输出缓存机制允许您执行此操作,并且该机制运行效果良好。 但是,我对 ASP.NET 输出缓存尚存两点疑惑。
第一,它要求更改 ASP.NET 代码,并且至少需要在这些页面上放置标记,以指示您希望缓存它们的输出。 对于管理内部开发和外部购买的 ASP.NET 应用程序的 IT 人员来说,这一要求可能难度稍高。 此外,在更改应用程序代码时,您必须要采取质量保证措施以确保进程不会出现故障。 这样就会增加合并缓存的成本。
第二,ASP.NET 输出缓存将页面输出从本地缓存到各个 Web 服务器,并且还会缓存到各个 ASP.NET 工作进程中。 如果您有 Web 园(即 Web 服务器上的多个工作进程)或负载平衡的 Web 场,那么这种缓存方式将会对一致性和可伸缩性带来很大的负面影响。 在这些情况下,您就拥有有关缓存内容的多个断开连接的数据副本;对于高通信量的网站来说,这可能会带来非常棘手的管理问题。 在 ASP.NET 4.0 中,Microsoft 期望提供可扩展的缓存框架,使您可以通过合并第三方的分布式缓存在一个单独的进程或层中保留缓存。
根据此开发思路,我不赞同将页面输出缓存到 Web 服务器,而是倾向于将页面输出缓存到位于用户和 Web 场之间的单独的 Web 缓存服务器上(类似于反向代理;请参见图 2)。 如果不通过 Web 场处理大量的用户请求,而是由用户和 Web 场之间的缓存提供服务,那么就会减少 Web 场上的负载并增加 Web 场的可伸缩性。 从缓存提取网页输出并返回到用户,这一过程需要的资源比实际执行网页要少很多。 这是因为缓存是一种性能高且可伸缩的内存存储,它与任何磁盘存储均不相同,磁盘存储会在性能和可伸缩性方面出现问题。
图 2 位于用户和 Web 服务器之间的 Web 缓存服务器。
在本文中,我将讨论缓存网页输出如何解决瓶颈限制并显著提高可伸缩性和性能。 Web 缓存服务器可以在实现这些目标时发挥重要作用。
Web 缓存服务器截获用户对网页发出的 HTTP 请求,并查看这些网页输出是否已存在于缓存中。 如果存在,Web 缓存服务器就会将输出返回给用户。 用户请求甚至永远不会发送到 Web 服务器。 由于网页输出从缓存中提取,因此返回速度非常快。 另外,由于这些网页输出在内存中且网页不需要再重新执行,因此还能节省大量的 CPU 处理能力。
Web 缓存服务器可以与任何后端 Web 技术平台共同工作。 无论这些 Web 应用程序是由 Java、.NET、PHP 或其他语言所开发,只要它们使用 HTML 和 JavaScript,则均可与 Web 缓存服务器共同工作。 但是,Web 缓存服务器可能包括一些特定于平台的功能,因此功能可能会因解决方案的不同而有所差别。
Web 缓存解决方案有两种。 其中一种主要缓存静态数据,这意味着缓存的每个页面都应当是完全静态的,或在可预测的时间间隔内发生更改。 整个页面会在一定时间范围内被缓存,之后该页面就会过期并将从缓存中删除。 另一种方案主要进行动态缓存,更适合于动态网站或 Web 应用程序。
如果您的网站或 Web 应用程序是动态的,数据更改频繁且不可预测,则您应选择动态缓存。 现在,大多数网站至少会频繁更改它们的部分内容。 您至少应该能够将网页缓存 15 到 30 秒,不过通常能够缓存几分钟到几个小时,甚至在某些情况下能缓存几天或几周。
Web 缓存为大型跨国企业提供一个极大的好处:能够在不同的地理位置上分散部署 Web 缓存服务器。 在一家全球性组织中,您的主网站应用程序可能部署在纽约,但用户却分散在世界各地(旧金山、伦敦、东京、悉尼和迪拜)。 现在,要将 Web 缓存服务器按地理位置部署在这些区域则相对简单。 在来自欧洲的所有请求命中您的网站之前,它们都将经过欧洲的 Web 缓存服务器。 这样它们就不需要跨越大西洋,并且不会产生每个数据包所必经的 100 毫秒延迟。 这些请求基本上都可以从附近的缓存获得其副本。
我们来看另一个示例。 您在迪拜有一个服务于中东和南亚地区的服务器,并且有几十万个用户同时点击您的网站。 利用 Web 缓存,您在纽约的主数据中心的通信量将显著降低。 因为您并未缓存所有内容,因此并非所有通信被都停止,并且您缓存的任何内容都会定期从缓存(即无效缓存)中删除。 不过取决于您应用程序的性质,您可能已将通信量减少了 30% 到 50%。


 

Web 缓存中的必备功能
随着时间的推移,网站已不再只显示静态内容,而成为了全面交互的 Web 应用程序,其拥有频繁更改的动态数据。 这意味着如今的 Web 缓存需要满足动态网站的所有需求。 其目标是尽可能多地缓存网站内容,同时确保缓存内容正确无误、不过期且与数据库中的基础数据保持同步。 要达成以上所有目标,Web 缓存需要某些功能来避免数据完整性问题并提高性能和可伸缩性。
一个典型的 Web 缓存解决方案包括以下功能。


 

过期
过期功能可使您指定相关规则以决定缓存的网页以及缓存多长时间。 它还能使您根据绝对或滑动时间来将页面指定为过期。 绝对时间是指您希望在某个特定时间将某页面指定为过期,无论该时间是今晚午夜还是从现在起的 10 分钟后。 滑动时间则取决于某个特定网页是否经常被访问。 如果该页面未被访问或根本没有使用,您可能希望指定其过期。 如果网页在一段时间(如 10 分钟或 20 分钟)内未被使用,则此空闲时间可能会使网页过期。
绝对过期时间对于网页来说可能是最重要的过期时间。 Web 缓存产品可使您指定规则并选择要缓存的 URL 模式(称为“URI”)。 Web 缓存允许您指定永远不会缓存某些 URL。 它允许您指定在某个特定时间长度内缓存某些类型的 URL。
它应该还能允许您根据 URL 输出所附带的 HTTP 标头中提供的信息来指定何时过期各种 URL。 每个页面的 HTTP 标头可以包含相关信息,其中包括:页面缓存的时间长度,页面的过期时间以及页面最后一次更改的时间。 Web 缓存可以检查这些项目以监视页面内容是否已被更改,以及是否需要将新内容上载到缓存中。 若没有此功能,您就无法使陈旧数据无效或将其删除。


 

过期时重新加载页面
该方案的另一个重要功能是能够在页面过期时重新自动加载页面,无论页面是由于绝对时间还是空闲时间而过期。 例如,您可能会说:“这个页面在接下来的 20 分钟内流量较大。”那么在以后的 20 分钟内,Web 缓存会自动重新提取页面以使其始终具有最新的副本。
这样您就不必等待用户下一次请求该页面。 这是因为当请求到达时,您不希望用户经历由于从 Web 场重新提取该页面而带来的延迟。 因为您可以在背景中提取该页面,不过您需要首先执行该页面,这可能要花费您 5 到 10 秒的时间从 Web 服务器提取该页面。 即便这样也没有关系,因为当用户获取页面时,您可以在几毫秒的响应时间内将其返回,具体时长取决于用户距离的长短。


 

部分页面缓存
浏览器中显示的某些页面上包含拥有自己的 URL 的多个项目。 因此要呈现某个页面,Web 浏览器就必须调用多个 URL。 这实现了与部分页面相同的结果,但它并不称为“部分页面”,因为从服务器的角度出发,每个 URL 代表着独立的页面,并且每个页面均被单独缓存,而根据页面性质的不同,其缓存时长也不相同。
在其他情况下,单个网页在开发时其内容被划分为多个节。 某些是不会更改的静态节;某些则是动态节,其各个部分在不同的时间间隔后会发生更改。 实际上,部分页面缓存并不是简单地缓存整个页面,而是根据页面的类型(静态或动态)以及页面应当缓存的时长来缓存页面的节。
ASP.NET 允许您通过两种方法执行部分页面缓存:控制缓存和缓存后替换。 两者都需要您修改想要为其执行部分页面缓存的特定 ASP.NET 页面。 如果您没有自己的开发资源并且未曾在内部开发此 ASP.NET 应用程序,则该方法不可行。 不过,下文将为您介绍 ASP.NET 中各个类型的部分页面缓存。
要在 ASP.NET 中执行部分页面缓存,你可以通过创建用户控件来包含缓存的内容,并将用户控件标记为“可缓存”。这样您就可以将页面的某些部分作为用户控件来缓存,从而在重新执行该页面时只需从缓存中提取这些部分,而不必重新执行它们。 只有那些未制作为用户控件且未标记为“可缓存”的页面部分才需要重新执行。
利用缓存后替换,您虽然可以缓存页面,但页面内的某些部分或片段将被标记为“动态”或者“不可缓存”。这样在重新执行该页面时,实际上仅执行了动态或不可缓存的部分。 页面的其余部分从缓存获取,并且缓存的部分和动态部分被合并起来以返回页面输出。
有趣的是,部分页面缓存仅可在 Web 服务器上执行。 由于这个原因,实施一些编程工作是必要的。 在 ASP.NET 中,您可以在 ASP.NET 页面中进行编程以决定需要缓存的部分,从而完成部分页面缓存。 但是此缓存在 Web 服务器本身执行,并且仍需执行 ASP.NET 页面(至少是页面的某些部分)。
在 ASP.NET 中,部分页面缓存的实现基于 Microsoft 的规范,但在 Java 平台上出现了被称为 Edge Service Includes (ESI) 的部分页面缓存标准。 ESI 定义了一种基于 XML 的简单标记语言,该语言定义了可在网络边缘聚合、组合和传递的可缓存和不可缓存网页部分,无论其位于内容传递网络或终端用户浏览器,或是位于用户浏览器和 Web 服务器之间作为反向代理的 Web 缓存服务器。
因此,部分页面缓存的平台局限性非常高,当然,对于 ASP.NET 您必须使用 Microsoft 的方案。


 

数据库依赖关系
另一重要功能是数据库依赖关系,即当数据库中的数据更改时,允许缓存中的相应页面输出无效。 页面输出通常是基于数据库中的数据生成的。 它们描述的数据来自一个或多个数据库表中的一行或多行。 因此,如果更改了这些行,那么这些页面必须从缓存中删除。 由于这个原因,数据库同步功能很重要。 这意味着当数据库中的数据更改时,这些页面输出应当失效,并且应该将它们从缓存中删除。 此功能使您可以自动确定应何时从缓存中删除特定页面。
创建此依赖关系的一个方法是通过指定与问题页面相对应的 SQL“select”语句(或包含 select 语句的一个存储的过程调用),然后将页面的某些 GET/POST 参数与 SQL 语句中的参数相映射。 在运行时,网页参数用于执行 SQL 语句,并针对 SQL Server 2005/2008、Oracle 10g R2 或更高版本的数据库创建一个 SqlCacheDependency。 然后,当数据库中相应的行更改时,数据库服务器将触发一个由 Web 缓存服务器捕获的 .NET 事件。 接下来,相应的网页输出就会从缓存中删除(请参见图 3)。
图 3 当数据库行更改时从 Web 缓存中删除页面。


 

文件依赖关系
另一重要功能是文件依赖关系。 您可能会用以下指令来将页面输出与系统中的文件相关联:“如果更新或删除此文件,请无效此页。”然后 Web 缓存将会监视保存在共享文件夹中的该文件。 如果该文件被更新或删除,Web 缓存会自动从缓存中使相应的 URL 无效。 这样您就可以从系统中的任意位置更新该文件,无论当更改相关数据时它是否涉及另一个应用程序或者相关联的数据库服务器中的触发文件。 例如,如果您的数据存储在大型机上,而不是存储在 SQL 2005/2008 或 Oracle 数据库中,您可以使用文件依赖关系来使缓存页面无效。
这样您就可以在数据存储区或具体环境发生变化(Web 缓存不可直接访问这些变化)时通知缓存。


 

PDF 部分内容
现在很多人都在线访问 PDF 文件。 常见情况是他们一次阅读一页内容,逐页读完整个 PDF 文件。 只有少数人下载整个 PDF 然后在本地阅读;多数情况下他们会在浏览器中阅读文件。 在使用这种方式查看信息时,他们通常不通篇阅读文件,而是在读完某些部分后就放弃该文件。
因此为他们提供整篇 PDF 通常是一种资源浪费;实际上这在高峰时期可能会对性能的可接受性产生决定性的影响。 由于这个原因,PDF 部分内容处理功能在 Web 缓存中显得尤为重要。 它降低了 Web 服务器上的带宽负载,并可提高总体可伸缩性。


 

ViewState 缓存
ASP.NET 最重要的功能之一是能够声明在服务器上运行的控件并回发到同一页面上。 在 ASP.NET 发行之前的传统 ASP 中,您最多可以创建多个页面来处理在逻辑上属于同一页面的多个不同操作,例如,加载数据、保存数据或执行其他操作。 但在 ASP.NET 中,您不必再像这样大费周折。 窗体域和其他控件现在可以被声明在服务器上运行,而服务器只需将页面回发到本身。
为了处理这些回发而创建了一个 ViewState,它可以记忆控件标识以及分配给这些控件的动态信息。 实际上,ViewState 可跨多个回发保留页面控件的状态。
ViewState 是 ASP.NET 应用程序的一项重要功能。 实际上正是由于 Web 服务器发送给浏览器的信息才使得浏览器可以在用户下一次回发同样的页面时向服务器回发同样的信息。
例如,您可能会将客户加载在 customer.aspx 页上。 然后您对客户数据进行一些更改并单击“保存”。“保存”按钮将再次调用 customer.aspx,但也会发送 ViewState 以便使 customer.aspx 知道应如何处理该回发。 ViewState 包含 customer.aspx 已发送到浏览器的信息,而回发中则包含用户可能已修改的新数据。 这样 customer.aspx 就可以确定哪些内容已被更改以及哪些内容未被更改。 这只是一个简单的示例;ViewState 还可以包含页面上各个控件的动态创建的其他数据。
尽管 ViewState 是 ASP.NET 中非常有用的功能,不过在 Web 服务器和用户浏览器之间来回传送数据也会产生一些消耗。 当应用程序处于负载高峰期或用户距离 Web 服务器较远且 Internet 连接速度较慢时,这一消耗可能会对性能及可伸缩性带来负面影响。
不过如果 ViewState 可以被缓存在 Web 缓存中,那么它通常不必长途跋涉到达浏览器。 在这种情况下,只需将一个标记或唯一的 ID 发送给浏览器,这样当浏览器回传时,Web 缓存会根据唯一的 ID 重新插入 ViewState 并将其返回到 Web 服务器。 当浏览器再一次发出请求时,Web 服务器仅要求该请求中包含上一次的 ViewState。 ViewState 是否到达浏览器并不重要,因为浏览器将永远不会使用该信息,只有 Web 服务器才会使用该信息。
从技术角度来讲,ViewState 用于回发,因此在您执行回发时需要 ViewState,而 Web 缓存则可以缓存 ViewState。 由于一个 ViewState 可能只有几千字节大小,因此这样还可以节省大量带宽。


 

Gzip 压缩
现在大多数浏览器都可以解压缩 gzip 压缩的内容。 但并不是所有的 Web 服务器都被配置为自动压缩网页输出。 即使已被配置为自动压缩,各个 Web 服务器原本就已经在承受着高通信量的压力,这样做会占用服务器上大量不必要的 CPU 处理能力。 不过,如果通过一个中间代理 Web 缓存服务器来进行压缩,那么可伸缩性将会大大增加。
压缩永远不会更改的静态数据比较容易。 但是,ASP.NET 应用程序中的大多数页面都是动态的,并且要想压缩页面内容,页面输出不能每次都发生更改。 否则,压缩可能会给 CPU 带来过量的负载,甚至抵消节省的带宽。 不过 Web 缓存已经可以智能地计算出哪些动态页面输出是可缓存的(也就是说这些页面至少在短时间内是不会更改的),它还能够自动压缩任何缓存页面。 然后这些缓存的页面将以压缩格式多次提供给客户端,并且会显著减少带宽使用量。
除了已压缩的内容(例如 PDF、JPEG、TIFF 等),一个典型的 gzip 压缩几乎可将内容减小 80%。 一个好的 Web 缓存应允许用户指定要压缩的 URL 以及要忽略压缩的 URL。


 

可伸缩和动态 Web 缓存群集
Web 缓存是位于 ASP.NET Web 场(类似于一台设备)前面的服务器。 目前,ASP.NET Web 场可以从两个服务器增长到带有负载平衡器的 100 多个服务器。 因此,单个 Web 缓存服务器不能处理不断增加的 Web 场的负载。 根据经验,您需要为 Web 场中的每五个 Web 服务器部署一个 Web 缓存服务器。
拥有多个 Web 缓存服务器不仅可以提高可伸缩性,还能使 Web 缓存进行复制,以便当任何一个服务器出现故障或被撤走时,缓存不会丢失并且性能不会下降(请参见图 4)。
图 4 动态 Web 缓存群集(在运行时添加或删除服务器)。
一个好的 Web 缓存服务器应该能够生成 Web 缓存服务器群集,以便能够通过复制提供稳定性以及通过多台服务器提供可伸缩性。 尽管涉及到多个 Web 缓存服务器,但仍将其视为一个逻辑 Web 缓存。 即使在群集中有缓存的多个副本,它们仍始终保持同步。 简短说来,拥有 Web 缓存服务器群集使您能够在保持缓存逻辑正确性的同时扩大规模。
一旦您拥有了缓存群集,一个好的 Web 缓存应允许您指定不同的缓存存储方案,也被称为缓存拓扑。 主要的拓扑包括复制的缓存、分区缓存和客户端缓存。
复制的缓存是指整个缓存被复制到群集中的各个缓存服务器。 因此,每个缓存服务器都有整个缓存。 所有“获取”操作始终在服务器本地执行,并且速度非常快。 但是会在多个缓存服务器上执行更新,当群集中有两个以上服务器时,更新成本将会增加。
而在另一方面,分区缓存会分解(或分区)缓存,将每个分区储存在不同的缓存服务器上。 分区数目等于缓存服务器的数目。 这样您就可以通过添加更多缓存服务器来增加缓存存储容量,而这在复制的缓存中是无法实现的。 此外您还可以使用分区缓存在不同的缓存服务器上创建每个分区的备份,当任何一个服务器出现故障时,您就不会丢失缓存。 从每秒钟的存储容量和处理数量来看,分区缓存都是可伸缩性最强的缓存拓扑结构。
最后,客户端缓存是可与分区缓存或复制的缓存结合使用(尤其当实际缓存在 Web 缓存服务器以外的其他服务器上承载时)的拓扑结构。 客户端缓存将缓存的一小部分保存在客户端进程中,以便于就近使用最常使用的数据。 保存在客户端缓存中的内容取决于客户端最近提取的内容。 您可以为客户端缓存指定一个最大值,当达到最大值时,它将会开始清除(或删除)旧内容以便为新内容提供空间。 通过这种方式,客户端缓存占用的内存永远不会多于您指定的可行值。
如果使用多个 Web 缓存服务器而不生成缓存群集,您将得到多个断开连接的缓存副本。 如果您的站点是近乎静态的,则该结果尚可接受,但对于动态网站和 ASP.NET 应用程序,该结果可能会导致数据完整性问题。 此外,即使另一个 Web 缓存服务器的缓存中有用户请求的页面输出,您还是会将该用户请求发送给 Web 服务器,从而造成 ASP.NET Web 场上的负载增加。


 

缓存地理分布
目前许多 ASP.NET 应用程序网站都拥有全球用户,即使这些网站本身位于同一个地理位置。 由于基础结构的复杂性和高成本,网站通常不可能分布于多个地理位置。 例如,ASP.NET Web 场也必须将数据库服务器放置在同一个地理位置;由于涉及到高处理量的应用程序,数据库服务器通常不适合地理分布。 因此,最终用户会由于广域网络 (WAN) 延迟而遇到性能降低的问题。
解决该问题的一种方法是将 Web 缓存服务器放在各个不同的地理位置,然后将所有通信从该区域传送至最接近的 Web 缓存服务器上(请参见图 5)。 如果 Web 缓存服务器没有已缓存的页面,那么该请求将直接发送到主数据中心,即另一组 Web 缓存服务器所在的位置。
图 5 在地理位置分布环境中的 Web 缓存服务器。
因此,一个好的 Web 缓存应该能够创建服务器的层次结构,这样即使每个 Web 缓存并未缓存页面,它也知道要将请求传送至何处。


 

脱离数据库
如我在 2009 年 6 月的文章中所述,数据不会每次都发生更改;它保持不变。 遗憾的是,在没有分布式缓存的情况下,您将经历不必要的周期以反复复制相同的数据。 但是您不必每次都访问数据库。 既然是相同的数据,为何还要访问那里? 为何不从缓存中提取数据?
下面的示例突出反应了该问题。 某航空公司的网站主页更改不是很频繁;它可以被缓存较长时间。 有一位用户来到该主页上搜索航班。 由于其他用户也要预订座位,因此航班信息不断改变,该信息的更改是在后台进行的。
例如,如果客户搜索纽约到旧金山的航班,那么座位的空余决定了搜索结果。 座位空余取决于已订客户的数量,并且预订操作是不断发生的。 如果一位匆忙的业务员不小心输入了错误的信息,或者为确保预订到一个座位而输入了多项条目,那么事情就会变得比较复杂。
用户收到的结果中将会显示某个航班可以接受预订,该信息在缓存中每五分钟改变一次。 但是当客户确定要预订座位时,数据库中就会执行一次实时的检查。 这是因为在 1000 位查看航班信息的用户中,可能只有 10 位确定要预订座位。 所以即使提供的信息可能不完全正确,也可以向所有访问者显示航班信息。 在这种情况下,您可以缓存该页面,即使它是高度动态的。
但是您在缓存时应该清楚,提供这些信息可能会有风险,因为它们不是完全正确的。 然而在数据库中的预订页面上,确保所有信息的准确性和实时性是非常重要的。 这里要强调的是,每个应用程序都有可被缓存的常见信息,并且不必将每个网站用户都发送到航空公司的数据库中。
最简单的阶段是当您希望缓存全部图像的时候。 您不会更改供人查看的公司徽标、总裁图片或标准文档。 但是还有其他的一些部分是较为动态的。 在这些部分中,您可以指定规则并作出命令,例如,“我希望将该页面缓存一定的时间。”
对于其他页面,您可能会说:“我不知道要缓存多长时间,所以我想将它绑定到数据库。 如果数据库表中的该行发生了更改,我希望此页面失效。”这意味着该页面将会从缓存中删除以及重新加载,并且创建新副本。 每个页面的类别是不同的。 只要 Web 缓存允许您决定如何缓存页面,那么您缓存的越多,访问 Web 场的次数就越少。


 

指导原则
在大多数情况下,您可以从部署 Web 缓存中获得极大好处。 如果您仅有一台 Web 服务器,那么您的通信量可能不是很大,不足以遇到这些类型的问题。 但如果您的用户数量超过 1,000 个,您可能就已经有了负载平衡的 Web 场。 在这种情况下,您可能就需要探索优化性能和可伸缩性的方法。
提前计划。 不要等待问题的发生,因为一旦问题发生,您将会陷入惊慌。 当您还未遭遇任何重大问题时,这就是改善的最佳时间,但是这时候您必须能够说服高层管理者,使他们明白您为何要为这个项目筹集资金。 您可以通过下面这个不错的方法来达成目的:向您的管理者提出疑问,如果网站在高峰期(最长 30 到 60 秒一次点击)时响应时间特别长,那么会给企业带来多大损失。 如果您的网站瘫痪了 30 到 60 秒,又会有多大损失呢? 考虑这些问题有助于您说服企业的主管人员,使他了解到对 Web 缓存的需求。
我在上文中提到,免费和商业缓存方案都可供您使用。 随着 ASP.NET 越来越受开发人员的欢迎,出现了支持 .NET 的商业 Web 缓存方案。 不过,在撰写本文时,大多数 Web 缓存产品支持 Java 和 PHP。 其中大多数是基于软件的,但也有一些硬件设备方案。
在您决定选择何种方案时,请以您的企业和网站作为考量标准。 网站的动态程度如何? 网站拥有多少用户? 您需要多少缓存来帮助您解决问题?
然后,请考虑需要哪些缓存功能。 我们已在上文讨论过,缓存可加快处理速度并增强可伸缩性。 但有时它会为用户提供过时的信息。 在您考虑各种解决方案时,请注意权衡利弊。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值