如果您的网站需要 cookie 等,ab 有点烦人,ab 太简单了。
基本上,根据我修复几个内爆 PHP 网站的经验,它通常是这样的:
1) 人们使用 MySQL
你完全可以使用 MySQL、facebook 和 flickr 来做到这一点(mysql 粉丝喜欢这些)如果你知道这些问题是:
- 如果你有一个非只读的 MyISAM 表和任何超过 100 us(甚至选择)的查询,你就死定了
在我修复的一个站点上,这个人租用了一台双四核服务器,因为“他的站点需要电源”。我查看了他的站点,查看了我以前拥有超过 100K 成员的站点和一个在 Via C7 微型半比萨盒服务器上运行的洪流跟踪器,我告诉他,您的站点在我地下室的 Celeron 300 上运行良好,这甚至有点矫枉过正,我可以以你至强的一半价格租给你,哈哈。
事实证明,这家伙是一个优秀的开发人员和一个真正的好人,但他对 MySQL 很烂,所以他的网站有典型的 Search Query From Hell 可以杀死任何网站:
- 每秒 10 次来自地狱的搜索查询(他的非法warez 网站上有大约 30 万会员)
- 来自地狱的搜索查询大约需要 0.1 - 0.2 秒
- 对同一个 MyISAM 表进行少量并发更新以增加趣味
=> 所有查询的总序列化(MyISAM 写锁)。1 个核心 100%,7 个核心空闲,loadavg > 1000(是的,他使用的是 apache),页面时间 > 30 秒,工作正常。
修复很简单:从地狱优化搜索查询,修复下面的点 2),切换到 InnoDB,切换到 lighttpd。loadavg 降至 0.02
2) 更新
没有人对页面计数器感兴趣。每次页面查看的问题 1 更新,你已经死了。添加一些 MyISAM 以获得更多效果。也是 InnoDB 的杀手锏,不是关于锁定,而是关于同步磁盘 IO 等待。
3) 全文
- 由于锁定,MyISAM 不能用于读写表。
- MyISAM 与 ramdisk 一样可靠(事实上,更少:您需要操作系统崩溃来损坏 ramdisk,损坏 MyISAM 表只需要 MySQL 崩溃或只是同时命中太多,您会得到“未知表引擎错误”,这个我看过很多次)
- FULLTEXT 在 InnoDB 上不可用
- FULLTEXT 索引中的任何插入都会触发几乎完整的索引重建(当我插入论坛帖子时,它正在重建 400 MB 的索引)
==> 如果您需要全文索引、性能和可靠性,请使用 Sphinx 或 Xapian。
我没有尝试过 Sphinx(人们对它说好话),但 Xapian 很快就愉快地搜索了 4GB 的文本。
4)人们使用apache。
这很好地结合了上述几点。
与像 lighttpd 这样的 CPU 使用率无法检测到的适当服务器不同(糟糕的 Via C7 服务于每秒 100 次 HTTP 命中,而 lighttpd 使用的 CPU 不到 1%),apache 会杀死你的机器。
当 MySQL 开始死掉(它很容易死掉)时,客户端开始用力按 F5,很快你就有大约 1000 个 apache 进程,每个进程都有一个 PHP 解释器,每个 PHP 解释器都有一个空闲的 MySQL 连接,等待 MyISAM 锁,除了一个,它正在对您的页面查看计数器进行一些微不足道的更新,但这需要一些时间,因为由于 1000 个 apache 和 1000 个 php 和 1000 个 mysql 进程,服务器已经进入午餐交换。
Lighttpd 对静态页面不使用 cpu。lighttpd 使您的 CPU 饱和的唯一方法是,如果您使用 apachebench 以 20K 请求/秒的速度猛烈攻击它。然后 Lighttpd 与几个对话,比如 10 个 php-fcgi 后端(每个核心 2-4 个很好),它们与几个 MySQL 连接对话。结果,一切都快了很多,当过载时,它会优雅地降级,而不是爆炸性地降级。
要解决最初的问题,您肯定想要分析您的 SQL 查询。将查询日志添加到您的 PHP 应用程序,它显示(仅对您)、查询列表和它们所花费的时间,以及从 PHP 脚本开始到结束的时间(页眉/页脚包含是一个好地方这)。
对于一个复杂的页面(不包括搜索),您期望大约 3 毫秒 MySQL 和 3 毫秒 PHP,这是一个很好的目标。你当然需要一个 PHP 编译的代码缓存。