第12章—高速缓存
加快应用程序速度的方法之一是存储生成的HTML代码块,甚至整个页面,以供将来的请求使用。这种技术称为缓存,可以在服务器端和客户端进行管理。
ob娱乐下载Symfony提供了一个灵活的服务器缓存系统。它允许通过基于YAML文件的非常直观的设置将完整的响应、操作的结果、部分或模板片段保存到一个文件中。当底层数据发生变化时,您可以使用命令行或特殊操作方法轻松清除缓存中的选定部分。ob娱乐下载Symfony还提供了一种通过HTTP 1.1报头控制客户端缓存的简单方法。本章涉及所有这些主题,并提供了一些关于监视缓存为应用程序带来的改进的技巧。
缓存响应
HTML缓存的原理很简单:在请求时发送给用户的部分或全部HTML代码可以在类似的请求中重用。此HTML代码存储在一个特殊的位置缓存/
symfony中的文ob娱乐下载件夹),前端控制器将在执行操作之前查找它。如果找到了缓存的版本,则在不执行操作的情况下发送该版本,从而大大加快了处理速度。如果没有找到缓存的版本,则执行该操作,其结果(视图)存储在缓存文件夹中,以备将来的请求。
由于所有页面都可能包含动态信息,因此HTML缓存在默认情况下是禁用的。这取决于站点管理员是否启用它,以提高性能。
ob娱乐下载Symfony处理三种不同类型的HTML缓存:
- 动作缓存(带或不带布局)
- 部分、组件或组件槽的缓存
- 模板片段缓存
前两种类型由YAML配置文件处理。模板片段缓存是通过调用模板中的辅助函数来管理的。
全局缓存设置
对于项目的每个应用程序,HTML缓存机制可以在每个环境中启用或禁用(默认值)缓存
设置settings.yml
文件。清单12-1演示了启用缓存。
清单12-1 -激活缓存,在myapp / config / settings.yml
Dev: .settings: cache: on
缓存动作
显示静态信息的操作(不依赖于数据库或依赖于会话的数据)或从数据库读取信息但不修改信息的操作(通常是GET请求)通常是缓存的理想选择。图12-1显示了在这种情况下页面的哪些元素被缓存:要么是操作结果(它的模板),要么是与布局一起的操作结果。
图12-1 -缓存操作
例如,考虑一个用户/列表
返回网站所有用户列表的操作。除非用户被修改、添加或删除(这个问题将在后面的“从缓存中删除项”一节中讨论),否则该列表总是显示相同的信息,因此它是一个很好的缓存候选者。
缓存激活和设置是在缓存中逐个操作定义的。Yml文件位于模块中配置/
目录中。示例请参见清单12-2。
清单12-2 -激活动作的缓存,在myapp /模块/ user / config / cache.yml
list: enabled: on with_layout: false #默认值lifetime: 86400 #默认值
此配置规定了列表操作的缓存是打开的,并且布局不会与操作一起缓存(这是默认行为)。这意味着即使存在操作的缓存版本,布局(以及它的部分和组件)仍然会被执行。如果with_layout
设置设置为真正的
,该布局将与操作一起缓存,并且不会再次执行。
要测试缓存设置,请从浏览器调用开发环境中的操作。
http://myapp.example.com/myapp_dev.php/user/list
您将注意到页面中的操作区域周围有一个边框。第一次,该区域有一个蓝色标题,表明它不是来自缓存。刷新页面,操作区域将有一个黄色标题,显示它确实来自缓存(响应时间显著提高)。在本章后面,你会学到更多关于测试和监控缓存的方法。
请注意
插槽是模板的一部分,缓存一个操作也将存储在该操作的模板中定义的插槽的值。所以缓存是为槽工作的。
缓存系统也适用于带有参数的页面。的用户
模块可能有,例如,显示
的操作。id
参数显示用户的详细信息。修改cache.yml
文件也为这个操作启用缓存,如清单12-3所示。
为了组织你的cache.yml
,您可以重新组合一个模块的所有操作的设置全部:
key,也如清单12-3所示。
清单12-3 - A Fullcache.yml
例如,在myapp /模块/ user / config / cache.yml
list: enabled: on show: enabled: on all: with_layout: false #默认值lifetime: 86400 #默认值
现在,每一个调用用户/显示
使用不同的动作id
参数在缓存中创建一个新记录。这个的缓存:
http://myapp.example.com/user/show/id/12
将不同于this的缓存:
http://myapp.example.com/user/show/id/25
谨慎
使用POST方法或GET参数调用的操作不会被缓存。
的with_layout
背景值得多说几句。它实际上决定了缓存中存储的数据类型。对于没有布局的缓存,只有模板执行的结果和操作变量存储在缓存中。对于具有布局的缓存,将存储整个响应对象。这意味着有布局的缓存比没有布局的缓存快得多。
如果在功能上可以负担得起(也就是说,如果布局不依赖于依赖于会话的数据),那么应该选择带布局的缓存。不幸的是,布局通常包含一些动态元素(例如,连接的用户名),因此没有布局的动作缓存是最常见的配置。然而,RSS提要、弹出窗口和不依赖于cookie的页面可以用它们的布局缓存。
缓存部分、组件或组件槽位
第7章解释了如何跨多个模板重用代码片段include_partial ()
帮手。部分和操作一样容易缓存,其缓存激活遵循相同的规则,如图12-2所示。
图12-2—缓存部分槽位、组件槽位或组件槽位
例如,清单12-4显示了如何编辑cache.yml
文件上启用缓存_my_partial.php
部分位于用户
模块。注意with_layout
在这种情况下,设置没有意义。
清单12-4 -缓存一个Partial,在myapp /模块/ user / config / cache.yml
_my_partial: enabled: on list: enabled: on…
现在所有使用这个部分的模板都不会实际执行这个部分的PHP代码,而是使用缓存的版本。
<?phpinclude_partial(“用户/ my_partial”)? >
就像操作一样,当部分缓存的结果依赖于参数时,部分缓存也是相关的。缓存系统将存储模板的不同版本,因为有不同的参数值。
<?phpinclude_partial(“用户/ my_other_partial”,数组(“foo”=>“酒吧”))? >
提示
动作缓存比部分缓存更强大,因为当一个动作被缓存时,模板甚至不会被执行;如果模板包含对部分的调用,则不会执行这些调用。因此,只有在调用动作中不使用动作缓存或布局中包含的部分时,部分缓存才有用。
第7章的一个小提示:组件是放在部分之上的轻操作,而组件槽是根据调用操作而变化的组件。这两种包含类型与部分类型非常相似,并以相同的方式支持缓存。例如,如果您的全局布局包含一个名为一天
与include_component(一般/天)
为显示当前日期,请设置cache.yml
文件一般
模块在此组件上启用缓存:
_day: enabled:开启
当缓存组件或部分时,必须决定是为所有调用模板存储单个版本,还是为每个模板存储一个版本。默认情况下,组件的存储独立于调用它的模板。但是上下文组件(比如在每个操作中显示不同侧边栏的组件)应该在有模板调用它的情况下被存储多少次。缓存系统可以处理这种情况,只要您设置了上下文
参数真正的
,详情如下:
_day: contextual: true enabled:开启
请注意
全局组件(位于应用程序中的组件)模板/
目录)可以缓存,只要你在应用程序中声明了它们的缓存设置cache.yml
.
缓存模板片段
动作缓存只应用于动作的一个子集。对于其他操作——那些在模板中更新数据或显示依赖于会话的信息的操作——缓存仍然有改进的空间,但方式不同。ob娱乐下载Symfony提供了第三种缓存类型,它专门用于模板片段,并在模板中直接启用。在这种模式下,动作总是被执行,并且模板被分割为执行的片段和缓存中的片段,如图12-3所示。
图12-3 -缓存模板片段
例如,您可能有一个用户列表,其中显示了最后访问用户的链接,并且该信息是动态的。的缓存()
Helper定义模板中要放入缓存的部分。有关语法的详细信息请参见清单12-5。
清单12-5 -使用缓存()
助手,myapp /模块/ user /模板/ listSuccess.php
<!——执行的代码每一个时间--><?php回声link_to('最后访问用户',“用户/显示?id = '.last_accessed_user_id美元)? ><!——缓存代码——><?php如果(缓存!(“用户”)):? ><?phpforeach(美元的用户作为$ user):? ><?php回声$ user->getName()? ><?phpendforeach;? ><?phpcache_save()? ><?phpendif;? >
下面是它的工作原理:
- 如果找到了名为'users'的片段的缓存版本,它将用于替换
<?PHP if (!cache($unique_fragment_name)):
和<?php endif;? >
行。 - 如果不是,这些行之间的代码将被处理并保存在缓存中,并使用唯一的片段名称进行标识。
没有包含在这些行之间的代码总是被处理而不是缓存。
谨慎
行动(列表
在本例中)必须不启用缓存,因为这将绕过整个模板执行并忽略片段缓存声明。
使用模板片段缓存的速度提升不像使用动作缓存那么重要,因为动作总是被执行,模板被部分处理,布局总是用于装饰。
你可以在同一个模板中声明额外的片段;但是,您需要为它们每个指定一个唯一的名称,以便symfony缓存系统随后可以找到它们。ob娱乐下载
类调用的第二个参数,与操作和组件一样,缓存的片段的生命周期以秒为单位缓存()
帮手。
<?php如果(缓存!(“用户”,43200)):? >
如果没有给helper提供参数,则使用默认的缓存生存期(86400秒,或一天)。
提示
另一种使动作可缓存的方法是在动作的路由模式中插入使其变化的变量。例如,如果一个主页显示了连接用户的名称,除非URL包含用户昵称,否则它不能被缓存。另一个例子是国际化应用程序:如果希望在具有多个翻译的页面上启用缓存,则必须以某种方式将语言代码包含在URL模式中。这个技巧将增加缓存中的页面数量,但它可以极大地帮助加快交互式应用程序的速度。
动态配置缓存
的cache.yml
文件是定义缓存设置的一种方法,但它不方便是不变的。但是,在symfony中,您可以使用纯PHob娱乐下载P而不是YAML,这允许您动态地配置缓存。
为什么要动态更改缓存设置?一个很好的例子是,某个页面对于经过身份验证的用户和匿名用户是不同的,但URL保持不变。想象一个/显示条
页面与文章的评级系统。对匿名用户禁用评分功能。对于这些用户,评级链接将触发登录表单的显示。这个版本的页面可以被缓存。另一方面,对于经过身份验证的用户,单击评级链接将发出POST请求并创建一个新的评级。这一次,必须禁用该页的缓存,以便symfony动态地构建该页。ob娱乐下载
属性之前执行的筛选器中是定义动态缓存设置的正确位置sfCacheFilter
.事实上,缓存是symfony中的一个过滤器,就像web调试工具栏和ob娱乐下载安全特性一样。为了启用缓存/显示条
页面,如果用户未经过身份验证,则创建conditionalCacheFilter
在应用中lib /
目录,如清单12-6所示。
清单12-6 -配置PHP中的缓存,在myapp / lib / conditionalCacheFilter.class.php
类conditionalCacheFilter扩展sfFilter{公共函数执行(filterChain美元){美元的上下文=这个美元->getContext();如果(!美元的上下文->getUser()->isAuthenticated()){foreach(这个美元->getParameter(“页面”)作为美元的页面){美元的上下文->getViewCacheManager()->addCache(美元的页面[“模块”],美元的页面[“行动”],数组(“一生”=>86400));}}//执行下一个过滤器filterChain美元->执行();}}
对象中注册此筛选器filters.yml
在sfCacheFilter
,如清单12-7所示。
清单12-7 -注册自定义过滤器,在myapp / config / filters.yml
...security: ~ conditionalCache: class: conditionalCacheFilter param: pages: - {module: article, action: show} cache: ~…
清除缓存(以自动加载新的筛选器类),条件缓存就准备好了。它将仅对未经过身份验证的用户启用pages参数中定义的页面缓存。
的addCache ()
方法sfViewCacheManager
对象需要一个模块名、一个操作名和一个关联数组,其参数与在对象中定义的参数相同cache.yml
文件。例如,如果你想定义/显示条
Action必须与布局一起缓存,生存期为3600秒,然后写以下内容:
美元的上下文->getViewCacheManager()->addCache(“文章”,“显示”,数组(“withLayout”=>真正的,“一生”=>3600,));
侧边栏
替代缓存存储
symfony缓存系统默认将数据ob娱乐下载存储在web服务器硬盘上的文件中。您可能希望将缓存存储在内存中(例如,viamemcached)或在数据库中(特别是如果你想在多个服务器之间共享缓存或加速缓存删除)。您可以轻松地更改symfony的默认缓存存ob娱乐下载储系统,因为symfony视图缓存管理器使用的缓存类定义在factories.yml
.
默认的视图缓存存储工厂是sfFileCache
类:
view_cache: class: sfFileCache param: automaticCleaningFactor: 0 cacheDir: %SF_TEMPLATE_CACHE_DIR%
您可以替换类
使用您自己的缓存存储类或symfony替代类之一(ob娱乐下载sfSQLiteCache
例如)。方法下定义的参数参数
键传递给初始化()
方法作为关联数组。任何视图缓存存储类都必须实现在抽象中找到的所有方法sfCache
类。请参阅API文档(欧宝官网下载apphttp://www.ob娱乐下载symfony-project.com/api/symfony.html),以获得更多有关此主题的资料。
使用超快速缓存
即使是缓存的页面也需要执行一些PHP代码。对于这样的页面,symfony仍然ob娱乐下载加载配置、构建响应等等。如果您确实确定某个页面在一段时间内不会更改,则可以通过将生成的HTML代码直接放入ob娱乐下载web /
文件夹中。这多亏了阿帕奇人mod_rewrite
设置,前提是路由规则指定的模式结尾不带后缀或带后缀. html
.
你可以通过一个简单的命令行调用,一页一页地手动完成:
> curl http://myapp.example.com/user/list.html > web/user/list.html
从那以后,每次用户/列表
action被请求时,Apache会找到相应的list.html
页面并完全绕过symfony。ob娱乐下载代价是您不能再使用symfony控制页面缓存了(生命周期、自动删除等等),但是速度的提高非常惊人。ob娱乐下载
或者,您可以使用sfSuperCache
ob娱乐下载Symfony插件,它自动化了这个过程,并支持生命周期和缓存清理。有关插件的更多信息请参阅第17章。
侧边栏
其他加速策略
除了HTML缓存之外,symfony还有另外两种缓存机制,它们ob娱乐下载是完全自动化的,对开发人员是透明的。在生产环境中,配置和模板翻译缓存在myproject/cache/config/和myproject/cache/i18n/目录中,不需要任何干预。
PHP加速器(eAccelerator、APC、XCache等)也称为操作码缓存模块,通过将PHP脚本缓存在编译状态来提高它们的性能,因此几乎完全消除了代码解析和编译的开销。这对于包含大量代码的Propel类特别有效。这些加速器与symfony兼容,可以轻松地将应用程序的速度提高两倍。ob娱乐下载对于任何具有大量用户的symfony应用程序,建议在生产环境中使用它们。ob娱乐下载
使用PHP加速器,可以手动将持久数据存储在内存中,以避免对每个请求执行相同的处理sfProcessCache
类。如果希望将cpu密集型函数的结果存储在文件中,则可能会使用sfFunctionCache
对象。有关这些机制的更多信息,请参阅第18章。
从缓存中删除项
如果应用程序的脚本或数据发生更改,缓存将包含过时的信息。为了避免不一致和错误,您可以根据需要以许多不同的方式删除部分缓存。
清除整个缓存
的clear-cache
symfony命令行的任ob娱乐下载务清除缓存(HTML、配置和i18n缓存)。您可以给它传递参数来只擦除缓存的一个子集,如清单12-8所示。记住只能从symfony项目的根节点调用它。ob娱乐下载
清单12-8 -清除缓存
//擦除整个缓存> symfony clear-cacob娱乐下载he //短语法> symfony cc //只擦除myapp应用的缓存> symfony clear-cache myapp //只擦除myapp应用的HTML缓存> symfony clear-cache myapp template //只擦除myapp应用的配置缓存> symfony clear-cache myapp config
清除缓存中的可选部分
更新数据库时,必须清除与已修改数据相关的操作的缓存。您可以清除整个缓存,但是对于所有与模型更改无关的现有缓存操作来说,这将是一种浪费。这就是remove ()
方法sfViewCacheManager
对象适用。它需要一个内部URI作为参数(与提供给类的参数相同)link_to ()
),并移除相关的动作缓存。
例如,想象一下更新
的行动用户
模块的列用户
对象。的缓存版本列表
而且显示
需要清除操作,否则将显示包含错误数据的旧版本。要处理此问题,请使用remove ()
方法,如清单12-9所示。
清单12-9 -清除给定动作的缓存,在模块/ user /行动/ actions.class.php
公共函数executeUpdate(){//更新用户user_id美元=这个美元->getRequestParameter(“id”);$ user= UserPeer::retrieveByPk(user_id美元);这个美元->forward404Unless($ user);$ user->setName(这个美元->getRequestParameter(“名字”));...$ user->保存();//清除与该用户相关的操作缓存美元的缓存管理器=这个美元->getContext()->getViewCacheManager();美元的缓存管理器->删除(“用户/列表”);美元的缓存管理器->删除(“用户/显示?id = '.user_id美元);...}
删除缓存的部分、组件和组件槽有点棘手。由于可以向它们传递任何类型的参数(包括对象),因此几乎不可能在事后识别它们的缓存版本。让我们关注部分,因为对其他模板组件的解释是一样的。ob娱乐下载Symfony用一个特殊的前缀(sf_cache_partial
),模块的名称,以及部分的名称,加上用于调用它的所有参数的散列,如下所示:
//被调用的部分<?phpinclude_partial(“用户/ my_partial”,数组(“用户”=>$ user)? >//在缓存中被标识为/ sf_cache_partial / user / _my_partial / sf_cache_key / bf41dd9c84d59f3574a5da244626dcc8
方法可以删除缓存的部分remove ()
方法,如果您知道用于标识它的参数哈希值,但这是非常不切实际的。幸运的是,如果你加上sf_cache_key
参数。include_partial ()
Helper调用,你可以用你知道的东西来识别缓存中的部分。如清单12-10所示,清除单个缓存的部分——例如,基于modified用户
——变得容易。
清单12-10 -清除缓存中的部分
<?phpinclude_partial(“用户/ my_partial”,数组(“用户”=>$ user,“sf_cache_key”=>$ user->getId())? >//在缓存中被标识为/ sf_cache_partial /用户/ _my_partial / sf_cache_key /12//使用$cacheManager->remove('@sf_cache_partial?module=user&action=_my_partial&sf_cache_key='.$user->getId())清除缓存中指定用户的_my_partial;
不能使用此方法清除缓存中出现的所有部分。你将在本章后面的“手动清除缓存”部分学习如何清除这些。
要清除模板片段,使用相同的方法remove ()
方法。在缓存中标识片段的键也由相同的键组成sf_cache_partial
前缀、模块名、操作名和sf_cache_key
类包含的缓存片段的唯一名称缓存()
助手)。示例如清单12-11所示。
清单12-11 -清除缓存中的模板片段
<!——缓存代码——><?php如果(缓存!(“用户”)):? >.../ /不管<?phpcache_save()? ><?phpendif;? >//在缓存中被标识为/ sf_cache_partial /用户/列表/ sf_cache_key /用户//用美元的缓存管理器->删除(“@sf_cache_partial ?模块=用户操作= list&sf_cache_key =用户的);
侧边栏
选择性缓存清理会损害你的大脑
缓存清理作业中最棘手的部分是确定哪些操作受到数据更新的影响。
例如,假设当前应用程序有一个出版
列出出版物的模块(列表
操作)和描述(显示
操作的实例),以及它们的作者的详细信息用户
类)。修改一条User记录将影响用户出版物的所有描述和出版物列表。这意味着您需要添加到更新
的行动用户
模块,是这样的:
$ c=新标准();$ c->添加(PublicationPeer::AUTHOR_ID,这个美元->getRequestParameter(“id”));美元的出版物= PublicationPeer::doSelect($ c);美元的缓存管理器= sfContext::getInstance()->getViewCacheManager();foreach(美元的出版物作为美元出版){美元的缓存管理器->删除(“出版/显示?id = '.美元出版->getId());}美元的缓存管理器->删除(“出版/列表”);
当您开始使用HTML缓存时,您需要清楚地了解模型和操作之间的依赖关系,这样就不会因为误解了关系而出现新的错误。方法的调用。请记住,修改模型的所有操作可能都应该包含一堆对模型的调用remove ()
方法,如果HTML缓存在应用程序中的某个地方使用。
而且,如果你不想因为太难的分析而损坏你的大脑,你可以在每次更新数据库时清空整个缓存……
缓存目录结构
的缓存/
你的应用程序目录有以下结构:
cache/ # sf_root_cache_dir [APP_NAME]/ # sf_base_cache_dir [ENV_NAME]/ # sf_cache_dir config/ # sf_config_cache_dir i18n/ # sf_i18n_cache_dir modules/ # sf_module_cache_dir template/ # sf_template_cache_dir [HOST_NAME]/ all/
缓存的模板存储在(HOST_NAME)
目录(为了与文件系统兼容,点被下划线取代),在对应于其URL的目录结构中。例如,一个页面的模板缓存调用:
http://www.myapp.com/user/show/id/12
存储在:
缓存/ myapp /刺激/模板/ www_myapp_com /所有/ user /显示/身份证/ 12.缓存
您不应该在代码中直接编写文件路径。相反,您可以使用文件路径常量。控件的绝对路径模板/
当前环境中当前应用程序的目录,使用sfConfig: get(“sf_template_cache_dir”)
.
了解这个目录结构将帮助您处理手动缓存清理。
手动清除缓存
跨应用程序清除缓存可能是个问题。中的记录进行修改用户
表中的后端
应用程序中的所有操作都取决于此用户前端
应用程序需要从缓存中清除。的remove ()
方法需要一个内部URI,但应用程序不知道其他应用程序的路由规则(应用程序彼此隔离),因此不能使用remove ()
方法清除另一个应用程序的缓存。
解决方案是手动删除文件缓存/
目录,基于文件路径。例如,如果后端
应用程序需要清除用户/显示
行动在前端
应用程序的用户id
12
,它可以使用以下:
sf_root_cache_dir美元= sfConfig::得到(“sf_root_cache_dir”);cache_dir美元=sf_root_cache_dir美元.' /前端/刺激/模板/ www_myapp_com /所有的;拆开(cache_dir美元.' /用户/显示/ id / 12.缓存);
但这并不是很令人满意。该命令将只擦除当前环境的缓存,并强制您在文件路径中写入环境名称和当前主机名称。要绕过这些限制,可以使用sfToolkit: clearGlob ()
方法。它接受一个文件模式作为参数,并接受通配符。例如,不管主机和环境如何,你都可以清除前面例子中相同的缓存文件:
cache_dir美元=sf_root_cache_dir美元.' /前端模板/ * / * / /所有';sfToolkit::clearGlob(cache_dir美元.' /用户/显示/ id / 12.缓存);
当您需要删除缓存的操作而不考虑某些参数时,此方法也非常有用。例如,如果您的应用程序处理多种语言,您可能已经选择在所有url中插入语言代码。因此,到用户配置文件页面的链接应该是这样的:
http://www.myapp.com/en/user/show/id/12
属性的用户的缓存配置文件id
的12
在所有语言中,你都可以这么做:
sfToolkit::clearGlob(cache_dir美元.“/ * / user /显示/ id / 12.缓存);
测试和监控缓存
HTML缓存如果处理不当,会导致显示数据不一致。每次禁用元素的缓存时,都应该彻底测试它,并监视执行提升以调整它。
构建登台环境
在生产环境中,缓存系统很容易出现在开发环境中无法检测到的新错误,因为HTML缓存在开发中默认是禁用的。如果为某些操作启用HTML缓存,则应该添加一个新环境(在本节中称为登台),其设置与刺激
环境(因此,启用缓存),但是使用web_debug
设置为在
.
要设置它,请编辑settings.yml
文件,并在顶部添加如清单12-12所示的行。
清单12-12 - a的设置暂存
环境,在myapp / config / settings.yml
Staging: .settings: web_debug: on cache: on
另外,通过复制生产控制器来创建一个新的前端控制器myproject / web / index . php
)到一个新的myapp_staging.php
.编辑它以更改SF_ENVIRONMENT
而且SF_DEBUG
价值如下:
定义(“SF_ENVIRONMENT”,“暂存”);定义(“SF_DEBUG”,真正的);
就是这样,你有了一个新的环境。通过在域名后面添加前端控制器名称来使用它:
http://myapp.example.com/myapp_staging.php/user/list
提示
控件可以创建一个新的前端控制器,而不是复制现有控制器ob娱乐下载
命令行。例如,要创建一个暂存
环境myapp
应用程序,称为myapp_staging.php
在哪里SF_DEBUG
是真正的
,就打电话吧ob娱乐下载Symfony初始化控制器myapp staging myapp_staging true
.
监控性能
第16章将探索web调试工具栏及其内容。但是,由于这个工具栏提供了关于缓存元素的有价值的信息,下面简要介绍一下它的缓存特性。
当你浏览到一个包含可缓存元素(动作,部分,片段等)的页面时,web调试工具栏(在窗口的右上角)显示了一个忽略缓存按钮(绿色圆角箭头),如图12-4所示。此按钮重新加载页面并强制处理缓存的元素。注意,它不会清除缓存。
调试工具栏右边的最后一个数字是请求执行的持续时间。如果在页面上启用缓存,这个数字应该在第二次加载页面时减少,因为symfony使用缓存中的数据,而不是重新处理脚本。ob娱乐下载您可以使用这个指示器轻松地监视缓存的改进。
图12-4 -使用缓存的页面的Web调试工具栏
调试工具栏还显示在处理请求期间执行的数据库查询的数量,以及每个类别持续时间的详细信息(单击总持续时间以显示详细信息)。监视这些数据以及总持续时间,将帮助您更好地衡量缓存带来的性能改进。
基准测试
调试模式极大地降低了应用程序的速度,因为大量的信息被记录下来并提供给web调试工具栏。在浏览时显示的处理时间暂存
环境并不能代表它在生产环境中的情况,在生产环境中,调试模式是被打开的从
.
为了更好地了解每个请求的处理时间,您应该使用基准测试工具,如Apache Bench或JMeter。这些工具允许进行负载测试,并提供两个重要信息:特定页面的平均加载时间和服务器的最大容量。平均加载时间数据对于监视由于缓存激活而导致的性能改进非常有用。
识别缓存部件
启用web调试工具栏后,缓存的元素以红色框的形式显示在页面中,每个元素的左上方都有一个缓存信息框,如图12-5所示。如果元素已经执行,则该框的背景为蓝色,如果来自缓存,则为黄色。单击缓存信息链接将显示缓存元素的标识符、它的生存期以及自上次修改以来经过的时间。这将帮助您在处理脱离上下文的元素时识别问题,查看元素是何时创建的,以及可以缓存模板的哪些部分。
图12-5 -页面中缓存元素的标识
HTTP 1.1和客户端缓存
HTTP 1.1协议定义了一堆头文件,通过控制浏览器的缓存系统,这些头文件对于进一步加快应用程序的速度非常有用。
万维网联盟(W3C)的HTTP 1.1规范http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html)详细描述这些头文件。如果某个操作启用了缓存,并且它使用with_layout
选项,它可以使用以下部分中描述的一种或多种机制。
即使您网站用户的某些浏览器可能不支持HTTP 1.1,使用HTTP 1.1缓存特性也没有风险。如果浏览器接收到它无法理解的标头,就会直接忽略它们,因此建议您设置HTTP 1.1缓存机制。
此外,代理和缓存服务器也能理解HTTP 1.1报头。即使用户的浏览器不理解HTTP 1.1,请求路由中也可以有一个代理来利用它。
添加ETag头以避免发送未更改的内容
当ETag特性被启用时,web服务器会向响应添加一个特殊的报头,其中包含响应本身的签名。
ETag:“1 a2z3e4r5t6y7u”
用户的浏览器将存储此签名,并在下次需要相同页面时将其与请求一起再次发送。如果新的签名显示自第一个请求以来页面没有更改,服务器就不会返回响应。相反,它只是发送一个304:未经修改
头。它为服务器节省了CPU时间(例如,如果启用了gzip)和带宽(页面传输),为客户端节省了时间(页面传输)。总的来说,带有ETag的缓存中的页面加载速度甚至比没有ETag的缓存中的页面更快。
在syob娱乐下载mfony中,为整个应用程序启用ETag特性settings.yml
.下面是默认的ETag设置:
所有:.settings: etag: on
对于具有布局的缓存中的操作,将直接从缓存/
目录,这样流程就更快了。
添加最后修改的报头以避免发送仍然有效的内容
当服务器向浏览器发送响应时,它可以添加一个特殊的头来指定页面中包含的数据最后一次更改的时间:
最后修改时间:2006年11月23日星期六13:27:31 GMT
浏览器可以理解此标头,并在再次请求页面时添加If-Modified
相应的标题:
If-Modified-Since: 2006年11月23日星期六13:27:31 GMT
然后,服务器可以比较客户机保存的值和其应用程序返回的值。如果匹配,服务器返回304:未经修改
头,节省带宽和CPU时间,就像ETags。
在syob娱乐下载mfony中,可以设置last - modified
响应头,就像你会对另一个头。例如,你可以在一个动作中这样使用它:
这个美元->getResponse()->setHttpHeader(“last - modified”,这个美元->getResponse()->获取当前日期(美元的时间戳));
此日期可以是页面中使用的数据的最后一次更新的实际日期,从数据库或文件系统中给定。的获取当前日期()
方法sfResponse
对象将时间戳转换为格式为格式化的日期last - modified
头(RFC1123)。
添加不同的头,以允许多个缓存版本的页面
另一个HTTP 1.1报头是不同
.它定义了页面所依赖的参数,浏览器和代理使用它来构建缓存键。例如,如果页面的内容依赖于cookie,则可以设置其不同
标题如下:
不同:饼干
大多数情况下,在操作上启用缓存很困难,因为页面可能会根据cookie、用户语言或其他内容而变化。如果不介意扩展缓存的大小,请设置不同
正确的响应头。方法可以为整个应用程序执行此操作,也可以为每个操作执行此操作cache.yml
配置文件或sfResponse
相关方法如下:
这个美元->getResponse()->addVaryHttpHeader(“饼干”);这个美元->getResponse()->addVaryHttpHeader(“用户代理”);这个美元->getResponse()->addVaryHttpHeader(“接收语言”);
ob娱乐下载对于这些参数的每个值,Symfony将在缓存中存储不同版本的页面。这将增加缓存的大小,但是每当服务器接收到匹配这些头的请求时,响应都是从缓存中获取的,而不是被处理。对于只根据请求头而变化的页面,这是一个很好的性能工具。
添加缓存控制头以允许客户端缓存
到目前为止,即使添加了头文件,浏览器也会继续向服务器发送请求,即使它保存了页面的缓存版本。你可以通过添加来避免cache - control
而且到期
响应的头信息。这些头在PHP中默认是禁用的,但是symfony可以覆盖这种行为,以避免对服务器的不必要请求。ob娱乐下载
类的方法触发此行为sfResponse
对象。在一个动作中,定义一个页面应该被缓存的最大时间(以秒为单位):
这个美元->getResponse()->addCacheControlHttpHeader(“max_age = 60 ');
你也可以指定在什么条件下页面可以被缓存,这样提供商的缓存就不会保留私人数据的副本(比如银行账号):
这个美元->getResponse()->addCacheControlHttpHeader(“私人= True”);
使用cache - control
使用HTTP指令,您可以对服务器和客户端浏览器之间的各种缓存机制进行微调。有关这些指令的详细回顾,请参阅W3Ccache - control
规范。
可以通过symfony设置最后一个头文件:ob娱乐下载到期
标题:
这个美元->getResponse()->setHttpHeader(“过期”,这个美元->getResponse()->获取当前日期(美元的时间戳));
谨慎
打开的主要后果cache - control
机制是服务器日志不会显示用户发出的所有请求,而只显示实际收到的请求。如果性能变得更好,统计数据中网站的表观受欢迎程度可能会下降。
总结
缓存系统根据所选的缓存类型提供可变的性能提升。从最佳增益到最小,缓存类型如下:
- 超级缓存
- 带有布局的动作缓存
- 没有布局的动作缓存
- 模板中的片段缓存
此外,还可以缓存部分和组件。
如果在模型或会话中更改数据迫使您为了一致性而删除缓存,那么您可以使用较细的粒度来实现最佳性能——仅删除已更改的元素,并保留其他元素。
记住要格外小心地测试所有启用缓存的页面,因为如果缓存了错误的元素,或者在更新底层数据时忘记清除缓存,可能会出现新的错误。专用于缓存测试的登台环境在这方面非常有用。
最后,使用symfony的高级缓存调整特性充分利用HTTP 1.1协议,这将使客户机参与缓存任务,并提供更ob娱乐下载多的性能提升。
本作品在GFDL许可下获得许可。