时间先生的第一个字节的奇怪案例

时间先生的第一个字节的奇怪案例

我在 Linode 1024 VPS 上有一个基于

  • Ubuntu 11.10
  • Nginx 1.0.5
  • PHP 5.3.6(带有 PHP-FPM、APC)
  • Varnish 3.0.2

那里有几个基于 WordPress 3.3.1 的博客。其中一个是普通博客,使用默认配置、主题和“Hello World”帖子,用于测试服务器。另一个是从其他服务器克隆的博客,有近 10k 个帖子和超过 10k 条评论。这个博客每天有大约 5000 个独立访问量。

服务器在 ab 测试中给出了良好的结果测试博客但是,对克隆的博客进行同样的测试是不可能的:ab 测试对服务器的负载太大,我不得不停止该过程,无论如何这都会使 ab 显示这真是糟糕的结果

在以下情况下,htop 也会显示“正常”负载:普通手术, 但异常大负载在腹部测试期间。

还有另一件奇怪的事情发生了(对我来说最重要的):第一个字节的时间非常高,但等待一段时间后,网站加载速度非常快。可以使用 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

答案1

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

这绝不是全面的,甚至不接近全面的,这只是一个起点。

第一个字节的时间

第一个字节的时间 (TTFB) 有多个组成部分:

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

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

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

消除组件的比较

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

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

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

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

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

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

调整后端

到此时,您应该已经找到问题,或者得出结论,问题出在您的后端。剩下的就是 Nginx、PHP 或 MySQL。

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

Nginx

Nginx 只是接受请求并提供静态内容或将请求转移到 PHP-FPM - Nginx 通常没有太多可优化的地方。

  • 设置 worker = 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 缓存到内存而不是磁盘。
  • 设置代码进行缓存(例如使用 Wordpress 插件,如 W3TC)
  • 使用 nginx 您可以设置 FastCGI 缓存 - 但由于您有 Varnish,最好避免这样做。
  • 设置缓存层,例如 Varnish(您已经完成) - 并确保它正常工作(例如使用 varnishstat,阅读实现高命中率
  • 为网站组件添加更多缓存 - 例如 MemCached(如果适用)

有时,考虑到应用程序和硬件的限制,您可能无法大幅提高后端性能 - 然而,这就是缓存的意义所在 - 尽量减少后端的使用。

进一步阅读

相关内容