时间到第一个字节的奇怪的情况

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

  • Ubuntu 11.10
  • Nginx 1.0.5
  • PHP 5.3.6(使用PHP-FPM,APC)
  • 清漆3.0.2

还有一些基于WordPress 3.3.1的博客。 其中之一是一个普通的博客,用默认的configuration,主题,只是“Hello World”的post,来testing服务器。 另一个是从其他服务器克隆的博客,有近10k的post和超过10k的评论。 这个博客每天有5K个独特的。

服务器在testing博客的abtesting中给出了很好的数字,但是对克隆的博客进行相同的testing是不可能的:abtesting加载服务器太多了,我必须停止这个进程,而ab进程这真的很差的结果 。

在正常操作时,htop也显示“正常”负载,但在abtesting期间正常负载较大 。

还有一件奇怪的事情发生了(对我来说最重要): 第一个字节的时间非常长 ,但之后等待网站载入速度非常快。 这可以通过tools.pingdom.com等服务轻松testing, 从而得到这个结果 。 请注意那个意思是“等待时间”的黄色区域。

为什么发生这种情况? 可能的想法:

  • 错误的PHP-FPMconfiguration
  • Linode的DNS响应时间很糟糕。 废话 – testing的博客解决DNS罚款,TTFB是太棒了
  • 糟糕的Nginxconfiguration

如果有人需要更多的信息,

  • 在这里,您已经获得了当前克隆的博客nginxconfiguration文件 ( /etc/nginx/sites-available/muycomputerpro.com
  • 在这里你已经有了my.cnf的configuration ( /etc/mysql/my.cnf )(我知道,暂时没有caching,这对TTFB过去没有任何影响)
  • 这里你已经有了当前的PHP-FPMconfiguration ( /etc/php5/fpm/pool.d/www.conf

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

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

时间第一字节

第一个字节的时间(TTFB)有多个组件:

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

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

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

比较以消除组件

除了less数例外,你的问题将在后端处理,通常归结为过度复杂/低效的代码,或configuration不佳的MySQL。

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

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

理想的testing会让你复制完整的网站,但是删除除了一篇文章和相关评论以外的所有内容。 这个testing的关键是要确定是否大量的内容是问题,或者如果你的设置(wordpress插件,主题等)的其他方面是原因。 你将基本上在相同的(新的)服务器上比较相同的站点的性能 – 加载相同的页面(相同的长度等) – 唯一的区别是总站点内容(例如有一个很好的机会,一些插件不随着内容的增加而顺利扩展)。

没有改变任何东西,你可以做一些其他的比较:

  • 从远程位置与本地进行testing – 这将有助于确定networking,延迟,dns等是否是原因
    • 你已经(有点)这样做了,大多数人认为你没有networking问题。
  • testing通过清漆(即端口80),直接对比nginx(端口8080) – 尽量不要在testing之间改变你的configuration – 只要使用正确的端口。 这会告诉你清漆的影响。 由于Varnish是一个caching层,它应该在第一个请求之后非常快地处理所有的请求 – 实质上,它应该绕过后端和生成dynamic页面所需的处理,并且快速地提供caching副本。
    • 你已经做到了这一点(虽然不是本地的),并certificate光油对你的performance有显着的积极影响。

调整你的后端

在这一点上,您应该已经发现问题或者得出结论说它存在于您的后端。 这让你Nginx,PHP或MySQL。

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

Nginx的

Nginx正在接受请求,要么提供静态内容,要么将请求转移到PHP-FPM–通常Nginx并没有太多的优化。

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

理想情况下,您的testing博客和克隆博客具有相同的configuration,在这种情况下,您已经有效地消除了Nginx的问题。

应用

在你试图识别代码中的问题的情况下(例如,一个缓慢的插件等),慢日志是开始的地方。

  • 启用MySQL慢日志和PHP-FPM慢日志运行你的基准,看看会发生什么慢。

MySQL的

  • 增加你的caching并运行mysqltuner.pl来获得一个好的起点。

PHP

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

PHP-FPM

  • 调整pm。*值 – 增加它们来处理高负载

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

高速caching

一旦你优化了每个可能的瓶颈,开始caching。

  • 你有一个opCodecaching(APC) – 确保它正在工作(它带有一个testing文件) – 检查你的caching命中率,如果可能的话,有APCcaching到内存而不是磁盘。
  • 设置你的代码caching(例如使用一个WordPress插件如W3TC)
  • 有了nginx,你可以设置FastCGIcaching – 但由于你有清漆,这是最好的避免。
  • 设置一个caching层,比如Varnish(你已经完成了) – 并确保它正在工作(例如使用varnishstat,读取达到高Hitrate )
  • 为您的网站的组件添加更多caching – 例如MemCached(如果适用)

有时候,考虑到应用程序和硬件的限制,您可能无法提高后端性能 – 但是,这是caching的重点 – 尽量减less后端的使用。

进一步阅读

  • 性能调优PHP
  • 优化PHP
  • 优化Nginx的高负载