2017-10-12 61 views
0

我有一个很奇怪的问题。 我有一个在Apache2.4下的ubuntu服务器上运行的网站。 该网站是用PHP编写的,并使用MySQL作为数据库。 我已经实现了“文件存储”作为longblobs在MySQL数据库中的小文件。Apache2服务器/网站在下载过程中停止响应

当我想从MySQL数据库下载一个blob /文件时,我打开一个到数据库的PDO连接。

$sql = $pdoData->prepare("SELECT * FROM fileblob WHERE ID = ?"); 
$sql->execute(array($blobID)); 
$row = $sql->fetch(); 
$content = $row['data']; 

通过“echo $ content”然后我将文件传输到浏览器。 所有这些工作完美无瑕。然而。在下载过程中,整个站点停止响应,每个新请求都会超时。 下载继续正常。

当下载剩余4MB时,网站会重新开始运行,但速度很慢。完成后,该网站已完全恢复正常。

MySQL数据库使用一个InnoDB后台,有一个最大的500个并发连接等

在下载的时候,都只有6打开SQL连接。 Apache的磁盘使用率最高为20%左右,CPU使用率低于10% Apache也设置为处理1k个并发连接(10个线程,最多有100个子项)。服务器通过无法计量的1Gbps线路连接。 我想不出任何硬件瓶颈。

我错过了什么? 我很高兴回答您的任何问题......

+0

什么是你的输出缓冲设置?你在脚本中使用PHP会话吗? – CBroe

+0

@CBroe是的,我正在逐字地使用PHP会话。输出缓冲区设置为4096 – user3829915

+0

_“输出缓冲区设置为4096”_ - 这可以解释为什么你看到的效果在4MB左右变化...尝试禁用它的这个请求/脚本的一部分。此外,一旦完成会话,请使用session_write_close - 否则,会话数据文件上的文件锁定也会使并发请求“挂起”。 – CBroe

回答

0

当您使用PHP的默认基于文件的会话机制时,PHP会在访问该特定会话的任何脚本正在运行时锁定会话数据文件。

因此,当您的下载正在运行时,会话数据文件始终保持打开状态,并且任何其他脚本都无法访问同一会话 - 它们只需等待,直到文件锁再次释放。

为了防止发生这种情况,可以使用session_write_close。它告诉PHP当前脚本是通过操作会话数据完成的,因此会话内容可以立即写入数据文件,并释放文件锁定,以便其他脚本可以再次访问它。

(你显然需要与在这一点上你的会话数据操作完成的。你不能在同一个脚本再次更改会议内容之后)

相关问题