来自同一客户端的Apache并发连接

7


我有一个PHP应用程序,它收到了很多ajax调用。
我注意到当同时发生两个或更多的调用时,它们不会并发执行,第一个需要停止以便第二个执行。
我建立了一个小测试来尝试解决这个问题。我的HTML如下:

<html>
<head>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
</head>
<body>
    <a href="test.php">Test</a>
    <button>Click</button>
    <button>Click</button>
    <button>Click</button>
    <button>Click</button>
    <script type="text/javascript">
        $('button').click(function() {
            $.get("test.php");
        });
    </script>
</body>
</html>

test.php 包含以下内容:

<?php
sleep(2);
echo 'Test';
?>

因此,在开发人员工具(或firebug)控制台上执行$('button').click()后,请求同时发生,但返回答案的时间是最后一个请求2秒后而不是所有四个同时返回(2秒后)。
好吧,我尝试在其他浏览器中同时打开这个文件,并且它成功了,它被并行执行。我的意思是,在chrome上运行这个,然后在firefox中打开页面选项卡显示“测试”需要2秒,而来自chrome ajax请求的响应则在最后一个请求完成2秒后返回,因此其他浏览器请求对第一个调用没有影响(这将证明这是一个会话问题,但见下文)。
如果我为test.php打开多个选项卡,同样的情况也会发生。

我已经尝试将会话更改为memcache-People在其他问题中说,会话可能会锁定。这很有道理,但即使从文件更改到memcache,问题仍然存在(脚本没有会话,session_autostart关闭)。

我真的很关注apache的配置问题,因为第一次过了一段时间后,如果我执行脚本,则会同时执行所有4个ajax调用!我在考虑类似DoS保护之类的东西。

无论如何,任何帮助都将不胜感激!

好的,问题解决了。
最终它是一个会话锁定问题,问题是memcached也锁定了会话!
必须安装php_memcached 2.0.1,该版本在memcached.ini中有一个锁定标志,并使用该版本。问题解决了。
虽然当请求相同的url(在上面的示例中我使用了test.php 4次)时,它仍然一次执行一个。我非常确定这是正确的行为,因为同时多次请求资源没有太多意义。将我的示例更改为请求test1.php,test2.php等等,它就可以正常工作。如果更改查询字符串也可以。
谢谢你的帮助!
PS:不想太早回答自己的问题,所以这里是答案。

2
尝试将一个随机数作为查询字符串附加到您的请求中,以确保它不是缓存问题,例如 $.get("test.php?" + Date.now()); - lunixbochs
你想同时处理所有请求吗?还是想避免这种情况? - kuba
我想同时制作所有内容。我注意到测试相同的URL是错误的。然后我测试了test1.php到test4.php,问题仍然存在,但我找到了原因,并将解决方案回答。 - filaruina
2个回答

7
在我的情况下,以下函数:
session_write_close();
解决了我的问题。
我有一个主页面,会定期调用一个名为ajax.php的文件。它每隔“n”秒被调用一次。
此外,我的表单有一个按钮,可以返回通过ajax调用的报告(**reporte.php**)。这只有在用户请求(点击)时才被调用,生成结果可能需要一分钟。
大多数情况下,ajax.php需要20毫秒才能运行,但是如果 report.php 正在运行,ajax.php会被冻结,直到reporte.php完成任务。更糟糕的是,ajax.php可能会被堵塞。
reporte.php(之前的代码)
<?php
// Some PHP Code goes here.
// The rest of the PHP code (mostly, the slow part of the process).
?>

修复后的reporte.php文件

<?php
// Some PHP Code goes here.  (ideal if it is the fast part).
session_write_close(); // fix for concurrent ajax
// The rest of the PHP code (mostly, the slow part of the process).
?>

在解决方案之前(Firefox的firebug插件的截图): before 在解决方案之后: after 请注意,在解决方案之前,reporte.php和ajax.php仍在加载(而且ajax已经在多个调用中被堆积)。而在解决方案之后,reporte.php正在加载,而每个连续的ajax调用已经加载完毕。
请注意,在session_write_close()函数之后,不可能(或不建议)使用任何会话函数和值。

解决了我的问题。注意到较少密集的请求会在一秒钟后返回。进行了分析、测试,服务器代码没有问题。然后发现是同时的请求。关闭会话解决了这个问题。 - frostymarvelous

-2
HTTP 请求相互独立 - 根据定义,HTTP 协议是无状态的。每个你执行的 $.get() 都是完全独立和新的 HTTP 请求,因此你最终会得到 4 个 HTTP 请求、4 个单独的 sleep() 调用以及来自服务器的 4 个单独的输出。

你的回答离题了。 - frostymarvelous

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接