我们运行一个元搜索引擎(价格比较),每次搜索都会在各个网站上产生大量实时搜索,并在我们的网站上显示合并和排序的搜索结果。
我们在 Linux Debian 服务器上以相当简单的设置使用 PHP/MySQL/Apache,但并行搜索多个站点的后台处理由 Tomcat 和 Java servlet 处理。然而,由于此设置 (Tomcat) 存在一些问题,我正在研究后台搜索的新方法。
一种看起来很有希望的方法也非常简单:从主搜索页面,每个单独的搜索脚本都使用 exec() 作为 PHP CLI 运行:
exec("nohup /usr/bin/php search.php '$params' &> /dev/null &");
在末尾使用 & 符号可将 PHP CLI 脚本直接发送到后台,主页无需等待即可继续。每次搜索大约有 20 个脚本在运行。
它似乎表现得足够好,但是当我使用 Apache Benchmark 运行并发请求的压力测试时,问题开始显现。MySQL 报告了此错误:
无法通过套接字“/var/run/mysqld/mysqld.sock”连接到本地 MySQL 服务器 (11)
这似乎是“连接过多”的变体,但它无助于提高 my.cnf 中的限制。但真正让我困惑的是,即使我调用一个不执行任何操作的小虚拟脚本,并且肯定不访问 MySQL,这些错误也会出现。因此,看起来即使不使用 MySQL,仅运行 PHP CLI 也会增加负载。
在我的测试中,最多有大约 700 个 PHP 实例在运行,并且 CPU 和内存负载比使用 Tomcat 调用 PHP 脚本时要低,因此从这个角度来看它看起来是可行的。
有人知道 MySQL 问题吗?当然,我愿意接受有关如何处理后台任务的新想法!
问候,马丁
答案1
马丁,
我当然不是这方面的专家,但我想到几件事。
我认为无论你是否在脚本中使用 mysql,php 都会加载对 mysql 的支持,但除非你正在使用,否则它不应该启动连接持久连接.我不认为 cli 脚本会从 Apache 子进程继承 mysql 连接,但是显然它必须基于您的测试。
你可能还会遇到文件过多mysql 的限制。还有人提到内存/资源耗尽是导致 mysql 错误的原因。您说它显示的负载比您的旧设置要少,但可能太多了吗?当这些脚本运行时,是否有机会使用 GUI(mysql 管理员)启动与 mysql 服务器的连接?如果是这样,您可能会看到它耗尽资源……
从数据库的角度来看,将 20 个搜索仅放在一个脚本中可能比生成多个脚本更有效。这样您就可以使用一个 mysql 连接进行所有 20 个搜索,并应相应地增加您的连接容量。换句话说,Web Script ---- 在后台生成 -----> CLI 脚本,该脚本循环遍历您的所有搜索。
不知道您的代码,也不知道您到底在做什么,这只是一个猜测,作为编码修复。
祝你好运
答案2
我想说的是,工作岗位的产生有点太简单了,而且肯定会导致资源匮乏的情况。
为了避免这种情况,我会使用某种形式的队列 - 通过列出所需内容的数据库表,然后定期检查,或者使用作业队列系统,例如 Gearman 或 Beanstalkd。您将一条消息放入队列 - 您想要搜索的内容 - 以及一个已经在运行的后台任务,该任务会在作业进入时拾取它们,并且它具有执行相应任务的能力,并通过数据库或某些内存系统(如 Memcached)将信息传回。前端系统可以刷新(或使用 Ajax)回调并查看是否已找到任何信息,并在适当时显示它。
这样就将前端和后端分开了,避免了必须关闭脚本打开的所有连接(请参阅执行)
答案3
抱歉回复晚了。我得了流感。
感谢您的反馈。有很多事情需要考虑!
我做了更多的实验,使用 wget 而不是 CLI 脚本来调用脚本,此外还让 Lighttpd 在端口 81 上提供这些特殊的搜索脚本 - 以减轻主 Apache 服务器的负担。
到目前为止,它看起来很有希望,但是当我做了更多的测试之后,我可能会再问一次。
编辑:我是原始发帖人,不知道为什么它看起来像其他人的帖子。也许与我的 OpenID 有关...