Mr. Time To First Byte 的奇怪案例

jav*_*pas 15 nginx varnish wordpress php-fpm

我有一个基于 Linode 1024 VPS 的网络服务器

  • Ubuntu 11.10
  • nginx 1.0.5
  • PHP 5.3.6(带有 PHP-FPM、APC)
  • 清漆 3.0.2

还有一些基于 WordPress 3.3.1 的博客。其中之一是一个简单的博客,带有默认配置、主题和“Hello World”帖子,用于测试服务器。另一个是从其他服务器克隆的博客,有近 10k 个帖子和超过 10k 条评论。这个博客每天有大约 5k 个唯一身份。

服务器在测试博客的 ab 测试上给出了很好的数字,但与克隆博客相同的测试是不可能的:ab 测试负载服务器太多,我不得不停止该过程,这无论如何使 ab 显示这真是糟糕的结果

htop 在正常操作时也显示“正常”负载,但在 ab 测试期间显示正常的大负载

还有一件奇怪的事情发生了(对我来说最重要):第一个字节的时间非常高,但在那之后等待网站加载速度非常快。这可以使用 tools.pingdom.com 等服务轻松测试,从而得出此结果。请注意表示“等待时间”的黄色区域。

为什么会这样?可能的想法:

  • 错误的 PHP-FPM 配置
  • Linode DNS 响应时间很糟糕。废话-测试博客解析DNS很好,TTFB很棒
  • 错误的 Nginx 配置

如果有人需要更多信息,

  • 在这里,您已获得当前克隆的博客nginx 配置文件 ( /etc/nginx/sites-available/muycomputerpro.com )
  • 在这里,你已经得到了当前的my.cnf配置/etc/mysql/my.cnf)(我知道,暂时不缓存,这不会对过去的TTFB差异)
  • 这里你有当前的 PHP-FPM 配置/etc/php5/fpm/pool.d/www.conf

cyb*_*x86 25

首先,这不是一个答案,而是一种诊断方法。

这绝不是全面的 - 甚至任何接近的东西,它只是一个起点。

到第一个字节的时间

首字节时间 (TTFB) 有许多组成部分:

  • DNS 查找:查找域的 IP 地址(可能的改进:更多/分布式/响应式 DNS 服务器)
  • 连接时间:打开一个到服务器的套接字,协商连接(典型值应该在“ping”时间左右 - 通常需要往返 - keepalive 应该有助于后续请求)
  • 等待:在发送第一个字节之前需要进行初始处理(这是您应该改进的地方 - 这对于动态内容最重要。

当您查看 ApacheBench 输出时,您还会看到:

  • 处理:这是等待 + 完成内容传输的总和(如果传输时间明显长于预期下载接收到的数据量,则正在发生进一步的处理(在接收到第一个字节之后)(例如页面是刷新可用内容)

消除组件的比较

除了少数例外,您的问题将出在后端处理中,这通常归结为过于复杂/低效的代码,或配置不当的 MySQL。

解决这个问题的一个好方法是通过一系列的比较来消除设置的各个方面。一个好的比较应该尽可能保持不变,以帮助缩小问题的范围。目前,您提供了以下比较:

  1. 在旧服务器和新服务器上运行的相同(克隆)站点:
    • 区别:服务器
    • 结果:旧服务器速度快;新服务器很慢
    • 注意:这里你需要的是量化这些服务器之间的差异——包括使用的堆栈(Nginx 等)和硬件(旧服务器是否更快,因为它是一台更强大的机器?)
    • 结论:代码可能能够在正确的设置下快速运行
  2. 新服务器上的测试站点与完整站点
    • 区别:内容、主题、插件等
    • 结果:测试站点快,全站点慢
    • 注意:理论上,这个测试应该可以帮助你消除设置的很多方面——DNS、网络,甚至你的 nginx/php/mysql 设置——但是,它不是很“公平”。
    • 结论:额外的内容对性能有显着影响

理想的测试是让您复制整个站点,然后删除除一篇文章和相关评论之外的所有内容。此测试的目的是最终确定大量内容是否是问题,或者您设置的其他方面(wordpress 插件、主题等)是否是原因。您基本上会比较相同站点在相同(新)服务器上的性能 - 加载相同页面(相同长度等) - 唯一的区别是总站点内容(例如,某些插件很可能没有随着内容的增加,可以很好地扩展)。

在不更改任何内容的情况下,您还可以进行一些其他比较:

  • 从远程位置与本地进行测试 - 这将有助于确定网络、延迟、dns 等是否是原因
    • 您已经(有些)这样做了,并且大多得出结论,您没有网络问题。
  • 通过 Varnish(即端口 80)与 nginx 直接(端口 8080)进行测试 - 尽量不要在测试之间更改配置 - 只需使用正确的端口。这将向您展示清漆的影响。由于 Varnish 是一个缓存层,它应该非常快速地为第一个请求之后的所有请求提供服务——本质上,它应该绕过后端和生成动态页面所需的处理,并非常快速地为缓存副本提供服务。
    • 您已经这样做了(尽管不是在本地)并证明了 Varnish 对您的表现有显着的积极影响。

调整你的后端

到目前为止,您应该已经找到了问题,或者得出结论,它出在您的后端。剩下的就是 Nginx、PHP 或 MySQL。

(我应该在这里提到,知道你的瓶颈是 CPU、RAM 还是 I/O 总是很方便的 - 在、、、、 等之间sar,你应该能够对此得出一些结论。)topiostatvmstatfree

nginx

Nginx 只是接受请求并提供静态内容或将请求转移到 PHP-FPM - 通常用 Nginx 优化并不多。

  • 设置工人 = # CPU 核心
  • 启用keepalive(值10-15就好)
  • 禁用不需要的日志记录
  • 如果需要,增加缓冲区大小
  • 避免 if 语句(尽可能使用静态名称而不是正则表达式,消除不需要的扩展)

理想情况下,您的测试博客和克隆博客具有相同的配置,在这种情况下,您已经有效地消除了 Nginx 作为问题。

应用

如果您试图识别代码中的问题(例如慢速插件等),慢速日志就是开始的地方。

  • 启用 MySQL 慢日志和 PHP-FPM 慢日志运行您的基准测试,看看会出现什么慢。

MySQL

  • 增加缓存并运行mysqltuner.pl以获得一个好的起点。

PHP

  • 禁用不需要的扩展,
  • 禁用 register_globals、magic_quotes_*、expose_php、register_argc_argv、always_populate_raw_post_data
  • 增加 memory_limit
  • open_basedir 和 safe_mode 具有显着的性能影响,但也可以提供额外的防御层。使用和不使用它们进行测试,以确定它们对性能的影响是否可以容忍。

PHP-FPM

  • 调整 pm.* 值 - 增加它们以处理高负载

值得注意的是,您的 htop 结果显示 php-fpm 消耗了大部分 CPU - 您的问题似乎与此直接相关。

缓存

一旦优化了每个可能的瓶颈,就开始缓存。

  • 你已经有一个 opCode 缓存 (APC) - 确保它正在工作(它带有一个测试文件) - 检查你的缓存命中率,如果可能的话,将 APC 缓存到内存而不是磁盘。
  • 将代码设置为缓存(例如,使用 W3TC 等 Wordpress 插件)
  • 使用 nginx,您可以设置 FastCGI 缓存 - 但由于您有 Varnish,最好避免这种情况。
  • 设置缓存层,例如 Varnish(您已经完成) - 并确保它正常工作(例如使用 varnishstat,阅读Achieving a high Hitrate
  • 为站点的组件添加更多缓存 - 例如 MemCached(如果适用)

有时,考虑到您的应用程序和硬件的限制,您可能无法将后端性能提高那么多——然而,这就是缓存的重点——以最大限度地减少后端的使用。

进一步阅读

  • 这是要分析的要点的绝妙总结。非常感谢您的评论,我将尝试对所有这些建议进行大量测试 - 其中一些,正如您所说,已经很清楚了 - 看看我是否能最终检测到问题。最好的问候,cyberx86。 (2认同)