当多个用户同时请求时,PHP页面是否会中断?

时间:2012-11-06 01:45:05

标签: php wamp

例如,如果我们在服务器getProducts.php上有一个特定的php文件。多个用户同时请求时会中断吗? 例如,如果用户询问有关产品A的详细信息,而另一个用户有关产品B的详细信息,而另一个用户有关产品C等的详细信息...将被php中断吗?或者它是一个自生成的线程系统,可以对每个请求进行工作和响应?

谢谢!

2 个答案:

答案 0 :(得分:8)

这出乎意料地与PHP很少或没有任何关系。回答用户请求的不是PHP,而是 Web服务器。例如Apache,NginX,IIS等。

然后,Web服务器将调用路由到PHP实例,该实例通常独立于在该确切时刻满足的任何其他请求。并发请求的数量取决于服务器配置,体系结构和平台功能。所谓的“C10K”服务器旨在同时提供多达一万个连接。

但PHP并不是从“GET /index.php”到一堆HTML的过程中唯一的因素;任何活动页面(PHP或ASP或Python等)都可以从数据库中请求更多资源。在这种情况下会出现并发问题,每当两个用户需要获取相同的资源(数据表中的一行,整个表,一个日志文件......),某种信号量系统这使得它一次只能获得对该特定资源的“锁定”,并且所有其他人必须等待轮到他们,即使上层Web服务器能够处理数百或数千个并发连接。

性能问题更新:对于会话等内容,在 PHP中会发生同样的情况。想象一下,你有一个用户请求一个页面,该页面有代码可以产生十多个调用(图像,弹出窗口,广告,AJAX ......)。第一个请求打开一个会话,这是一堆必须保持连贯的数据。因此,当其他十个调用通过时,所有绑定到同一个会话,并且PHP无法知道这些调用中是否有任何一个想要修改会话数据 - 它没有追索权,而是{ {3}}直到第一个调用释放会话锁定,一旦调用,第二个调用将阻止第三个调用,依此类推。外卖点:如果不需要,请避免session_start()(例如,使用加密强GET令牌替换它或完全不做),或在完成修改session_commit()后立即致电_SESSION的价值,将大大提高表现。 (因此将使用更快的会话管理器,或者不使用粗锁的会话管理器:例如redis)。

例如在图像生成中:

session_start();
// This does the magic.
session_commit();
// We can still read session. We just can't write it anymore.

// That's why we needed a session.
if (!isset($_SESSION['authorized'])) {
    Header('HTTP/1.1 403 Forbidden');
    die();
}
// Here the code that generates an image *and sends* it. The session
// lock, if we hadn't committed, will *not* expire until the request
// has been processed by the *client* with network slowness. (Things
// go much better if you use the CGI interface instead of module).

在您的示例中,看到“WAMP”标记,您有一个Windows Apache服务,通过PHP从MySQL检索数据,并在产品上提供请求。

Apache服务器将接收数百个连接,激活数百个PHP模块实例(它们将共享大部分代码,因此内存占用不会灾难性地快速上升),然后所有这些实例都会询问MySQL ,“产品XYZ怎么样?”。在MySQL的说法中,他们将尝试获得READ LOCK。读锁意味着“我正在读这个东西,所以请你们都不敢在它上面写直到我完成”。但所有这些都只是阅读,所以他们都会成功 - 同时。

所以不,那将是没有停止 - 就在那时。

但是假设您还想更新产品视图的计数器。然后每个PHP实例也需要一个WRITE LOCK,这意味着,“我想写这个东西,所以在你完成之前你们都没有读过,否则你将冒险阅读半生不熟的数据,当然没有你在我这里做的时候“。

此时,表类型计数。 MyISAM表有prevent the second call from proceeding:如果更新产品A的统计信息的实例正在product_views上写,则其他实例将无法使用整个表执行任何操作。他们都会排队等候。如果表为InnoDB,则锁定位于级别 - 更新产品A的所有实例将一个接一个地排队,与更新产品B,C,D等的那些实例并行排列。因此,如果所有实例都写入不同的记录,它们将并行运行。

这就是为什么你真的想在这些情况下使用InnoDB表。

当然,如果您有“页面访问”等记录,并且他们都在更新“product-page.php”的行,那么您就会遇到瓶颈,如果流量较高的网站,如果您设计了一些其他方式来编写该信息,那么您会做得很好(许多解决方法之一是将其存储在共享内存位置;不时的一个访问它的许多实例接收到将信息保存到数据库的任务。实例仍在竞争锁定内存,但这比竞争数据库事务要快几个数量级。)

答案 1 :(得分:3)

如果您使用的是apache,那么它就是并发系统。这意味着每个请求将被并行处理,因此您的PHP脚本不会被中断。