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

Ala*_*eep 0 php wamp

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

谢谢!

LSe*_*rni 8

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

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

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

性能问题的更新:PHP 内部会话等事情也是如此.想象一下,你有一个用户请求一个页面,该页面有代码可以产生十多个调用(图像,弹出窗口,广告,AJAX ......).第一个请求打开一个会话,这是一堆必须保持连贯的数据.因此,当其他十个呼叫到来时,所有呼叫都绑定到同一个会话,并且PHP无法知道这些呼叫中是否有任何一个想要修改会话数据 - 它没有办法,而是阻止第二个呼叫继续进行直到第一次调用已释放会话锁定,一旦调用,第二次调用将阻止第三次调用,依此类推.外卖点:避免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).
Run Code Online (Sandbox Code Playgroud)

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

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

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

但是假设您还想更新产品视图的计数器.然后,每个PHP实例也需要一个WRITE LOCK,这意味着,"我想这件事情上写,所以没有你读的,直到我完成了,否则你会冒险阅读半生不熟的数据,当然,你们没有在这儿我正在努力".

此时,表类型计数.MyISAM表具有表锁定:如果实例更新产品A的统计信息正在写入product_views,则没有其他实例可以对该整个表执行任何操作.他们都会排队等候.如果是表InnoDB,则锁定在行级别 - 更新产品A的所有实例将一个接一个地排队,与更新产品B,C,D等的那些实例并行排列.因此,如果所有实例都写入不同的记录,它们将并行运行.

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

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