Drupal专业开发指南 第15章 页面

 

我们在前面讨论了很多,不过都是对站点的耗费资源的构件进行缓存,但是Drupal最大的优化是缓存整个页面视图。对于匿名用户,很容易做到这一点,这是因为所有页面对于所有匿名用户都是相同的。然而,对于登录用户,每个页面都是针对用户量身定做的。因此需要采用不同的缓存策略来处理这种情况。
    对于匿名用户,Drupal可以使用单个查询来取回缓存的页面内容,当然它还需要一些其它查询以加载Drupal本身。对于匿名用户的页面缓存,有两种缓存策略供你选择:普通模式和激进模式。当然你也可以禁用页面缓存。通过设置最小缓存有效期,你可以进一步的修改普通模式和激进模式策略。这些设置可以在Drupal管理界面“管理➤站点配置 ➤性能”中找到。该界面如图15-1所示。在接下来的部分中,让我们学习一下每种设置。
15-1.控制页面缓存行为的管理界面
 
禁用
    这将完全禁用页面缓存。通常在开发网站时使用。一般情况下,你都需要启用页面缓存。
 
注意 即使禁用了页面缓存,Drupal仍然缓存用户菜单、过滤后的内容、主题注册表、数据库模式、系统变量。这些构件级别的缓存不会被禁用。
 
普通模式
    与完全不使用缓存相比,普通模式对性能会有巨大提升,因此它是提升一个缓慢的Drupal站点性能的最简单方式之一。让我们仔细的看一下,当启用了普通模式缓存系统时,请求的生命周期。
    为了理解普通模式的页面缓存,你首先需要了解Drupal的引导指令流程。引导指令流程是由各个阶段组成的,这里的阶段就是一些更小的独立的步骤。Drupal利用了这个阶段性的引导指令系统,在提供一个缓存页面时,只需要加载和解析所需的代码,对于无关的代码,则不需要对其进行加载和解析,这样就将数据库查询降到了最小。
    图15-2详细给出了为匿名用户的请求提供一个缓存页面的流程。
15-2 本图展示了当处于Drupal的普通模式缓存设置下,为匿名用户提供缓存页面的请求生命周期。引导指令流程的前面5个阶段与缓存无关,在这里将其加进来是为了保持完整性。*表示一个数据库查询;**表示在该点的数据库查询次数是未知的。
 
    首先,请求进来以后,Web服务器就得执行index.php。在index.php中的第一行PHP代码,就是用来包含文件includes/bootstrap.inc的,该文件包含了加载引导指令的核心函数。接着,index.php会调用drupal_bootstrap()。
    drupal_bootstrap()负责执行每一个引导指令阶段。对于普通模式缓存,我们只需要关心DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE引导指令阶段就可以了。在该阶段,首先会从数据库中取回系统变量。假定缓存策略是普通模式,接下来的一步就是包含文件includes/module.inc。module.inc内部的函数是用来允许Drupal激活模块系统的。接着,Drupal将初始化实现了hook_boot()或者hook_exit()的模块。通过分别调用bootstrap_invoke_all(‘boot’)和bootstrap_invoke_all(‘exit’)来激活这些钩子。例如,统计模块,使用statistics_ exit()函数来追踪页面访问。节流阀模块使用throttle_exit()函数,根据当前的访问量来修改节流阀级别。
 
注意 在一个模块中使用hook_ boot ()或者hook_exit()函数,会为整个站点的性能带来负担,这是由于在处于普通缓存模式下,为访问者提供每个缓存页面时,都需要加载你的模块。当你实现这些钩子时,可用的函数也会受到限制,因为此时还没有加载includes/common.inc。常用函数比如t(),l(),和pager_query()此时都不可用。
 
    Drupal_page_cache_header()通过设置HTTP头部来准备缓存数据。Drupal将把Etag和304头部设置为适当的,这样浏览器就可以使用它们自己的内部缓存机制了,在适当的时候可以避免不必要的HTTP循环请求。如果浏览器发送的头部信息已经请求过它,那么缓存的数据将被发送给浏览器。
 
激进模式
    激进模式完全绕开了对所有模块的加载(如图15-3所示)。这意味着,此时不再为缓存页面调用boot(引导)和exit(退出)钩子了。因为不需要加载模块,所以需要解析的PHP代码少了。而需要执行的数据库查询也少了。如果你启用的模块使用了这些钩子(比如统计模块和节流阀模块),那么在激进模式下,它们可能不会正常工作。在管理界面“管理➤站点配置 ➤性能”,Drupal会给出警告,指出哪些模块可能会受到影响。
 
15-3 当处于Drupal的激进模式缓存设置下,为匿名用户提供缓存页面的请求生命周期,*表示一个数据库查询

老葛的Drupal培训班 Think in Drupal

Drupal版本: