我正在学习PHP和Laravel。我工作的公司有一个用纯PHP构建的Web应用程序。我注意到,在执行诸如从大型CSV文件执行数据库更新(CPU和内存密集型)之类的事情时,几乎没有其他任何事情可以通过Web应用程序完成。例如,更新某些人帐户的东西是微不足道的,而不是CPU和内存密集型。基本上做前者将系统搞定,直到完成。查看Linux服务器上的TOP
,显示CPU使用率为99%,内存使用率相当高。
无论如何,这真的不是一个类似于系统的企业,只是少数用户用来管理用户使用的Python框架中编写的另一个Web应用程序的用户。但它让我想到了基于PHP的企业系统的方法是什么?
显然,单个用户无法执行密集型任务,直到系统完成为止。我想现实世界中有大量的例子,PHP处理非常复杂的内存密集型任务,而其他用户则无法察觉。
编辑:当我说"砖砌系统"我的意思是服务器本身,因此管理PHP Web应用程序和客户端Python Web应用程序都不会响应请求。
答案 0 :(得分:3)
在企业系统中,首先要处理的是冗余。一切都必须是多余的。对于基于PHP的应用程序,设置是至关重要的。
如果我们谈论网站,这些是步骤
DNS已更新,因此可解析多个IP。这样,将哪些IP返回给浏览器或者DNS池中的一个服务器首先死亡是无关紧要的。亚马逊的Route 53是我们使用的东西。它太棒了。
接下来是网络服务器。当IP被“命中”时,请求进入Web服务器。我们使用nginx
(因为nginx
是 - 你猜对了 - 太棒了)。由于DNS池中有多个IP地址,因此可以使用多个Web服务器。同样,哪个Web服务器将处理客户端的请求 - 胜利的冗余是无关紧要的。
nginx
可以提供静态内容,也可以在满足规则时将请求传递给PHP。我们使用php-fpm
。每个nginx
服务器将HTTP请求代理到php-fpm
个节点的集群。在常规语言中 - 它选择服务于PHP的计算机集群中的另一台计算机。与哪个PHP节点处理请求无关 - 胜利的冗余。
PHP现在做了一些工作,连接到数据库,并且 - 你猜对了 - 它“说话”了一组数据库。数据库是同步的,有关于这个主题的全书,所以我不会详细介绍。同样,与哪个db获取查询无关 - 胜利的冗余(实际上有很多方法可以解决这个问题)。
数据库服务器优化用于他们正在进行的工作类型 - 这意味着他们已针对读取或写入进行了优化。数据库或任何类型的存储解决方案都不是无限的黑洞,您可以像这样填写。你必须仔细选择服务器将要做什么 - 它会写吗?它会被用于阅读吗?它会写多少份?它会读多少次?工作量增加的计划是什么?基本上,您需要优化数据库服务器 - 您肯定不能使用默认的MySQL配置。如果您有大量工作负载可能会使数据库负担过重,您可以使用排队机制来整理多个插入并在单个事务中刷新它们 - 该方法利用硬盘的带宽并将其交换为I / O(基本上,这意味着它很好并且工作得很快。
所以,你去吧。这是一个简短的概述,您将如何在PHP中处理企业级别的内容。每件作品都应该是冗余的,可水平扩展,并针对其正在进行的工作类型进行优化。
你绝对不希望你的应用程序挂起或在有人搞砸了什么时变得无法使用。
答案 1 :(得分:2)
不应在网络请求上进行高要求的流程。
例如,您应该使用队列 这样,你允许文件上传并创建一个队列进程来提供服务,然后请求完成,并在服务器上启动进程后一刻,但用户得到了请求。
然后您可以考虑配置CPU优先级较低的队列,或者可以在数据处理之间添加休眠时间,从而允许CPU为其他进程提供服务。
或者您可以在上传文件后记录该文件,并将控制台作业配置为每分钟检查是否有待处理的待处理数据,然后处理批处理并允许下一批处理在下一分钟检查,保持当前行在某处处理。
但是,再次尝试避免在Web请求上执行那些冗长的过程,使用Web请求获取信息,然后单独触发该过程。
Laravel非常支持框架中的控制台作业或队列。
答案 2 :(得分:1)
我打赌我的所有Quatloos你已经为长时间运行的请求打开了一个开放会话来进行数据库插入,阻止后续请求打开会话。你需要做的是:
<?php
session_start();
/* pre-game stuff that depends on $_SESSION */
session_write_close();
/* long-running stuff that doesn't need to update $_SESSION */
或者更好的是,如果可能的话,只是跳过打开此任务的会话。
附录: