性能问题:首次请求延迟


36

我将一个带有Minelli子主题的D7站点放在一起。在整个过程中,我尝试了不同的主题,不同的模块。在开发过程中的某个地方,我遇到了一个奇怪的性能问题,现在我真的不知道是什么主题/模块/配置导致了这个问题。

问题是,当我第一次访问该网站时,显示第一页大约需要15秒。然后,我可以在该站点周围移动,它的响应速度非常快。如果我将其放置一个小时左右,然后再返回,则第一个请求又很慢。

我已经清除了缓存,所以不应该成为问题。另外,我禁用了我不使用的主题和模块。我将网站移至新的基础架构,但问题随之而来!

我下一步要去哪里?


2
无法告诉您我也想解决多少问题。我的工作原理是,经过一个小时左右的cron运行(刷新缓存),第一个请求花费了一段时间,因为需要所有这些非缓存的数据库查询。但我只是在猜测
克莱夫(Clive)

我有同样的问题。为匿名用户启用缓存解决了问题,但我知道这不是一个好的解决方案
znat 2012年

@Kim:我想知道您是否找到问题的根源和/或好的解决方案
znat 2012年

2
有几个答案提到了穷人的cron:遇到问题的任何人都可以确认是否使用crontab触发了cron还是依靠了穷人的cron?
安迪

6
实际上,如果它是cron,则可能不仅是cron,而且还有update_cron()寻找新版本,这可能需要花费相当长的时间。尝试禁用update.module,看看是否是问题所在。
贝迪尔(Berdir)2012年

Answers:


16

我将检查三件事。

第一,如果您在生产站点上且未编辑PHP文件,则应确保已启用APC,具有足够的内存并具有较长的TTL(如果需要,您可以花一天时间或永不过期)。您也可以考虑设置apc.stat=0。该APC文档有所有你需要设置TTL的信息。为了选择内存量,您应该将apc.php文件粘贴到受保护的位置,并监视内存使用情况和流失统计信息。调整APC内存,使您的未命中率很低。最初的缓慢原因可能是因为APC已满并且正在清空(IIRC,APC在已满时转储整个缓存,而不是采用LRU或更高级的缓存策略)。

其次,确保已对MySQL进行了适当的调整。您可以使用mysqltuner调整缓冲区大小。您最初的速度缓慢可能是由于从磁盘加载表和/或查询高速缓存未命中。虽然不是很完美,但mysqltuner确实可以使您朝正确的方向前进。

第三,确保您拥有真正的Drupal cron策略。就个人而言,我将在“ admin / config / system / cron”上禁用automagic cron并设置一个crontab使其每晚运行。如果您确实确实需要对事物进行更细粒度的控制,则还可以尝试Elysia Cron。这样,您可以根据需要运行必要的任务,而正常的任务可以在一夜之间运行。您最初的速度可能是每小时进行一次Cron运行。您可以通过查看cron在“ admin / reports / dblog”上运行的时间并尝试与您的慢速进行匹配来确认这一点。


我发现几乎所有(M / L / W)AMP开发堆栈,甚至是专门针对Drupal的(如Bitnami),都经过严重调优或根本没有调优(我认为Acquia的dev堆栈是个例外)。当然,默认情况下不是为生产计算机安装mySQL。InnoDB日志文件默认为5M,并且分配的内存很小。通常,只需进行适当的调整即可使站点更加生动-只需放入my-medium.cnf或my-large.cnf就足够了。
Renee 2012年

感谢每个看到此评论并为帖子做出贡献的人,这个问题有很多好的答案。我认为这个特定的答案很好,简洁地总结了主要问题。彻底检查这三个点有助于在各种不同的机器上很好地加速Drupal站点。感谢@MPD
Clive

9

Ivanhoe123可能是正确的:Drupal 7带有默认情况下启用的“可怜的家伙”。简而言之,这意味着(一次)执行cron会在Drupal渲染页面之前运行,从而延迟了所有操作。

始终尝试在生产现场使用真正的cron作业。有关更多技术细节,请访问http://drupal.org/cron或与您的托管公司联系。

要禁用它,请转到admin / config / system / cron并选择“从不”。


我认为禁用cron并不能解决问题,更有可能将其隐藏起来以备后用。但是至少我想您可以将性能问题缩小一些;)
wiifm 2012年

1
Attiks并不是说要禁用cron;他是说要在任何用户访问站点页面时更改调用cron任务的选项。那是一个特定的选项,在Poormanscron模块中实现了Drupal 6 。更改该选项并不意味着禁用cron任务。
kiamlaluno

8

杰韦利模块提供数据库的日志记录,以检查是否有任何长时间运行的查询。

如果这样做没有帮助,请使用XHProfXDebug并找到有罪代码。XHProf(探查器)为您绘制了服务器上正在执行的所有功能的漂亮映射,并告诉您哪些消耗了最多的执行时间。另一方面,当XDebug(调试器)配置有诸如Eclipse之类的IDE(参见视频)时,它允许您深入研究正在实时执行的每个功能。探查会给你的想法是什么正在执行; 而调试器将向您展示为什么执行它。


2
是的,发生这种情况的原因可能有很多,使用XhProf通常是查找实际问题的最佳方法。
Berdir

6

仅仅从问题的角度,我立即想到了三(3)件事

  • MySQL存储引擎/ CPU
  • 数据库缓存
  • 表锁定

MySQL存储引擎

如果您不使用任何FULLTEXT搜索/索引,我强烈建议您将所有MyISAM数据转换为InnoDB。MyISAM并非旨在利用多个CPU和多个内核的优势。InnoDB已得到极大增强,可以使用多个CPU以及读/写超线程。

这是我在DBA StackExchange和此站点中关于调整MySQL的InnoDB性能方面的一些帖子。

数据库缓存

将所有MyISAM数据转换为InnoDB的另一个强有力的论据是MySQL如何缓存数据/索引。MyISAM存储引擎仅缓存索引。InnoDB缓存数据和索引。有鉴于此,您可以为InnoDB缓冲池分配足够的内存,以容纳以下其中一项(以较小者为准)

  • 所有InnoDB数据和索引(如果您有足够的RAM供操作系统使用,则理想;消除后续延迟)
  • 已安装RAM的75%(如果您拥有比该RAM更多的InnoDB数据/索引;最大程度地减少延迟)

如果您使用的是MySQL 5.1,则可以设置innodb_max_dirty_pages_pct =0。这会稍微增加磁盘I / O,但是InnoDB缓冲池将被清除得足够多,以使旧数据和索引页可以轮转而不会出现磁盘I / O激增的情况。MySQL 5.5和MySQL 5.1的InnoDB插件不需要此调整,因为它具有更好的默认缓冲池刷新机制。

如果无法使用InnoDB,则可能需要使用memcached或清漆。这使开发人员可以决定缓存的数据将在服务器RAM中保留多长时间。自然,这将需要开发上的增强,以使您的应用程序具有内存缓存/清漆意识。

表锁定

结语

您无法避免在MySQL重新启动后出现初始延迟。但是,一旦使用上述建议/信息增强了MySQL,您就不再会遇到后续的延迟。


非常有用的信息,谢谢。这些问题是否能够解决如此经常/一致地发生的问题?我见过的大多数报告都估计,网站上30-60分钟的不活动状态会导致初始页面加载再次延迟
Clive

2
@Clive对于所有MyISAM数据库,如果将数小时前加载到MyISAM密钥缓存中且长时间未使用的MyISAM索引页移出,则会发生这种情况。调用该循环出的数据将需要对MyISAM进行磁盘读取。InnoDB也可能发生相同的行为,特别是如果InnoDB缓冲区太小。由于InnoDB缓存数据和索引页面,因此将所有MyISAM转换为InnoDB并使用大型InnoDB缓冲池可以最大程度地减少甚至消除此类页面加载问题。
RolandoMySQLDBA 2012年

太好了,接下来我将基于此进行分析,听起来很有希望。再次感谢
克莱夫(Clive)

2
@Clive我想建议使用mk-query-digest或pt-query-digest进行分析。我在DBA StackExchange中
RolandoMySQLDBA 2012年

5

我将使用YSlow或Firebug等工具来确定加载页面时以及紧随其后加载页面时发生的确切情况。检查这是否是缓存问题,此外,当您以匿名用户身份然后通过身份验证用户访问页面时,请检查其功能。将此与您在Drupal中的性能设置进行比较。

如果不是缓存问题,请使用Devel的查询日志以及MySQL的日志来查看数据库正在发生的情况。此外,如果服务器上具有操作码或类似的性能增强缓存,请尝试关闭一些编号,然后再重新打开。



3

因此,我差点将Drupal丢到我的上一个项目中。

但是我必须有一个以上的原因。我还没有找到“解决所有问题”的解决方案,该解决方案在每次出现此问题时都会起作用。

Syslog和Ubuntu / Debain

我第一次遇到间歇性的15秒加载时间是在(专用,非共享)基于Debian / Ubuntu的系统上运行drupal时。禁用Syslog模块是我的解决方案。

正如@BetaRide所说,使用xDebug或其他一些PHP分析器非常有启发性。


仍然是一个问题-解决方法

至于我的其他安装,我仍然茫然。

在我的开发服务器和低流量的Drupal安装上,此问题更加明显。

作为一种解决方法,我设置了一个cron作业,每60秒加载一次网站首页,每300秒加载一次Drupal的cron脚本。这显然不是最佳选择,但是我更愿意wget或curl体验15秒的加载时间,而不是人类来访者。


3

许多人认为,此问题可能与阻止同步后台进程有关,特别是与繁重的cron作业有关

如果属实,那么gielfeldt * 正在开发大量的模块,这些模块可能会立即解决该问题,或者至少可以提供一些线索,并帮助站点构建者在其案件中诊断和治疗具体罪魁祸首。两者都用非阻塞异步HTTP或命令替换了阻塞同步进程,并且都提供了可以识别麻烦进程的相关报告:

  • 后台进程及其捆绑的模块允许Drupal的后台进程队列被异步处理,因此它们不会阻塞。这样可以解决问题。此外,在最新开发人员中捆绑的Background Process Apache Server模块中,有一个基本但正在改进的UI报告,具有可监视,解锁和检查这些过程的开始时间和进度的功能。这可以确定问题过程。
  • Ultimate Cron建立在Background Process的基础上,允许cron触发的任务具有自己的独立异步机制,每个异步机制都可以在UI中进行监视和停止。除了可以将繁重的性能降低任务与常规的低开销清理工作区分开来,它还为您提供了一个报告,其中包含方便的信息,例如每个由cron触发的任务的运行时间,上次运行的时间,当前状态,等等。这还可以消除和/或识别问题过程的障碍。

无论如何,两者都是非常有用的模块。对于这个问题,它们可以用来测试(非常合理的探测)理论,即阻塞是由同步阻塞过程或cron运行引起的。潜在地,他们可以通过异步运行而不是同步运行它们来解决问题,并且还可以潜在地提供线索,指出哪些特定进程造成了这种阻碍。(请注意,他们的文档尚在开发中……

但是,如果根本无法配置它们来提供帮助,则表明问题不仅仅在于同步后台进程。FWIW,自从使这些模块正常工作以来,我再也没有在站点上遇到过这个问题(但是-接触木头)-但是我以前在我的站点以及野外的Drupal现场都看到过。

还应了解当前正在开发的其他相关插件模块-例如,在复杂的高强度情况下,Ultimate Cron Queue Scaler允许基于阈值的节流,可能有助于减少与cron相关的性能问题。


* 没有从属关系,我只是他们的工作给人留下深刻的印象


2

由于这再次打击了我,因此我开始调查此问题。我肯定可以确认

  1. drupal_cron_run()穷人的核心计划触发的调用使我的开发机上的请求时间增加了约5秒。可以通过取消注释drupal_cron_run()in modules/system/system.module中的测试注释来测试此system_run_automated_cron()
  2. 清除所有缓存会使我的开发机上的请求时间增加约2秒。可以通过执行一次drush cc all并重新加载页面来进行测试。

这意味着将cron设置为never并通过crontab添加对cron的调用会使情况变得更好。此后立即击中一些常用页面以重新填充缓存将再次损害用户体验。

我不确定缓存。我尚未涉及该网站的默认缓存设置。我认为drupal可能会不时地重建所有缓存,可能是由cron触发的,但是我不确定这样做是如何进行的。但是7个小时的延迟几乎是我几个小时后点击页面时看到的。


1

这样的问题会让您发疯,当我遇到类似情况时,这有助于弄清楚是什么原因导致问题一次迈出一步,然后以匿名和登录用户的身份进行测试。(洋葱层法)

您提到您在玩了几个主题和自定义编码后开始注意到这个问题。我不知道您的网站及其背后的逻辑有多复杂,但是以下步骤将帮助您发现问题:

  1. 在服务器中创建一个文件夹或另一个帐户(可能会更好),在该文件夹中,将使用与站点上使用的相同版本进行全新的Drupal安装。然后,在不添加任何模块或主题的情况下,测试网站响应第一个请求和后续请求所花费的时间。如果一切正常,则可以忽略服务器配置问题,如果其行为与当前相同,则Web服务器或数据库存在配置错误。

  2. 如果步骤1的结果良好,并且服务器响应速度很快,并且后续请求也是如此,则仅将当前站点中的主题安装到全新安装站点中,然后再次进行测试。如果一切仍然快速响应,则主题不是问题,应继续执行步骤3,否则必须开始调试主题* 1。

  3. 如果在进行了第2步的测试之后,该站点仍然快速启动了当前站点中的模块,并确保在添加并启用每个模块后测试响应时间* 2。

  4. 如果在添加主题和模块之后站点仍然快速响应,则开始添加配置,创建内容类型,导入视图,设置菜单等。不要忘记在添加每个主题之后测试站点响应。

  5. 准备好设置和配置,站点仍保持快速运行,现在可以将数据转移过来。导入节点,分类术语,注释等。我知道我听起来像是一个破记录,但是在完成每个步骤之后都要进行测试。

* 1测试主题:在一个超级精心设计的主题中,此过程可能会很棘手,这里有几个要点:

  1. 如果您链接到任何外部js或CSS库,请尝试使用相同的本地副本。

  2. 在template.php文件中,检查可能具有更长或无限循环的函数,以及预处理函数和/或挂钩主题函数。

  3. 检查其他模板文件(page.tpl.php等),并查找数组和对象的原始PHP处理。

  4. 如果使用“视图”和视图模板文件,则也请检查一下。

  5. 始终仔细检查路径,优化图像,js和css文件。有时,在单个文件中使用多个代码段时,js文件的高度可能会很高。

* 2测试模块:测试模块有所不同,因为允许对PHP使用繁重的操作。这里有一些指针:

  1. 社区支持的模块(CCK,视图等)在drupal.org上有问题队列,请检查它们是否存在与您的问题有关的所有问题,以及是否有可能修复此问题的补丁。

  2. 自己的自定义编码模块,如果您编码了,就必须修复它,对吧?仔细检查您的编码,并对照api.drupal.org检查功能使用情况,您可能使用的是过大的功能,而不是挂钩。

  3. Internet共享的自定义代码模块,请按照步骤2进行操作,但是这次您还可以联系原始模块编写者,并让他/她知道问题所在。

  4. 如果您的站点是升级站点(D5-> D6-> D7),请检查迁移或升级脚本(通常在module.install文件中),您可能需要在新表配置上增加一个“索引”,以使慢速SQL查询X更快。

  5. 如果您觉得自己对该问题有洞察力,请走一会儿并进行一些完全不相关的其他活动,然后稍后再回来以重新讨论该问题。

  6. 如果您将问题指向代码的一部分,但是无法解决问题,请尝试向不知道如何编程或Drupal如何工作的人解释该部分是做什么的。准备感到惊讶。

注意:如果重建站点后所有站点都开始像计算机的最佳功能之一那样起作用,不要惊慌。


1
我只是重新安装了一个空白的drupal,没有延迟。因此,下一步是推动我的主题。但是,这将花费很多时间,因为我必须等待半个小时才能再次
看到

1
很高兴听到这似乎不是硬件或服务器配置问题。请发回您的发现。
埃米尔·奥罗尔

1

仔细检查您是否没有卸载任何模块就将其卸载。这会导致延迟,因为Drupal会尝试查找文件,但现在不存在了。

如果模块不再存在,请删除变量表中的引用。


1

诸如newrelic之类的Web APM 是跟踪性能问题的最佳工具。我曾经在网站上调用过一两行代码,这些代码做过一些奇怪的事情,在怪异的时间加载了不必要的数组,并做了其他一些几乎看不见的事情,直到我们使用APM对其进行跟踪为止。


1

有人提到GoDaddy会很慢。许多基于云的托管公司也将有此初始延迟,因为AWS之类的服务都有此延迟。自动取消对服务器的优先级设置会比较便宜,并且这些服务器将需要一到两秒钟来“唤醒”。

例如,Pagodabox的第一个字节有3-4秒的时间,直到服务器高兴地醒来。实际上,Pagodabox可以通过使服务器保持唤醒状态来获利,因此您可以支付额外的费用来“修饰”您的网站。

另外,CDN可以帮助您。您的Web /数据库服务器将不会加载已投放的缓存页面或图像。此处的好教程:http : //wimleers.com/article/easy-drupal-cdn-integration-for-fun-and-profit

还有... WebPageTest让我很高兴。http://www.webpagetest.org/免费比较使用不同的网络浏览器在地球上的加载时间。使用此功能可以获取所做的任何更改的真实结果。


这是一个很好的信息,但是问题仍然存在于我的本地计算机上的站点上,仅消耗本地资源
Clive

0

问题可能在任何地方。

  1. 确保尚未在任何主题或模块上打开调试模式。例如,在许多主题中,都有一个选项可以重新生成主题注册表。
  2. 如果您在像Godaddy这样的共享主机上运行,​​则15秒的首次请求是正常的。
  3. 使用Drush CTools导出模块将您的站点或首页转换为代码库。这将消除任何数据库调用,并且您的站点将完全从php运行。
  4. 如果仍然遇到问题,请通过打开query log和上的page timer选项来使用Devel设置admin/config/development/devel。查看两者中哪一个花费更多时间来生成整个页面。
  5. 如果没有任何作用,请重新启动服务器。
  6. 最坏的情况是安装XHProf来查看问题出在哪里。

1
你能解释#2吗?
Johnathan Elmore

0

因此,这就是我解决安装问题的方式。这不是真正的解决方案,因为我无法确定问题的确切根源(如果有),但这是一个很好的解决方法

1)汇总CSS(缓存设置)。这将延迟减少了一半

2)将cron设置为never(并在外部运行它)-注意:我遇到了“试图在cron已经运行时启动cron”的错误。我认为它正在尝试在每次启动时启动cron,但是由于失败,因此cron页面没有提及最新的尝试,而是最新的成功。

3)设置一个cron作业,每30分钟调用一次Lynx主页

所有这些都在共享托管服务器上。这不是最佳选择,但可以


0

我建议按照Boost模块(假设您使用共享主机)或Varnish的方式使用前端缓存。如果您的网站访问主要是匿名的,并且页面内容在大多数情况下是非动态的(即页面变化不大),则这将是最好的选择。

这些解决方案可在首次访问时保存渲染的页面,然后提供预渲染的html,而不需要执行完整的Drupal引导程序,页面构建和主题化过程,从而节省了大量时间,尤其是在繁忙的网站上,例如在您这样的网站上描述哪个“去睡觉”并且花太长时间才能醒来。

唯一真正的缺点是(至少对于Boost是这样),当网站内容更改时,您将需要清除缓存。如果要确保该站点已完全缓存有当前内容,则可以运行drush cc all,然后通过cron定期对整个站点进行curl或wget。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.