PHP适用于非常大的项目吗?它可以是交易安全的吗?

时间:2009-06-01 10:15:18

标签: php

这个问题可能看起来很奇怪。

但是每次我做过PHP项目时,都会遇到这种糟糕的经历:

脚本在10秒后取消运行。这导致非常糟糕的数据库不一致(删除循环的错误示例:用户即将删除相册。相册对象从数据库中删除,然后删除照片的一半,脚本被杀死就在那里,并且剩下10,000张照片,没有参考)。

这不是交易安全的。我从来没有找到办法安全地,以确保完成。如果脚本被杀死,它就会被杀死。就在循环中间。它刚刚被杀死了。这从来没有发生在使用java的tomcat上。如果需要很长时间,Java就会运行并运行和运行。

很多时事通讯 - 脚本尝试通过将工作分成很多包来解决这个问题,即一次发送100个,然后重新启动页面(噢,真的很蠢),做下一个,以及等等。最常见的事情是挂起或脚本需要的时间超过10秒,而您的平台也会陷入困境。

然而,我听说非常大的项目使用PHP像studivz(德国的facebook克隆,实际上是最大的德国网站)。所以有一种希望,这种不良行为只是来自不专业的托管公司,因为他们的服务器非常糟糕。这有什么道理?是否可以通过这种方式进行配置,脚本永远不会因为它们需要更长的时间而被杀死?

11 个答案:

答案 0 :(得分:14)

  

PHP适用于非常大的项目吗?

每当我看到这样的问题时,我都会感到有点不安。 非常大意味着什么?对你来说可能很大,对我来说可能很小,反之亦然。这甚至假设我们使用相同的指标。您是否正在测量构建项目的时间,完成项目的生命周期,涉及的资金,使用它的人数,构建/维护项目的开发人员数量等等。

那就是说,你所描述的问题听起来像你不知道你的技术是否足够好。无论您选择哪种技术,这对您来说都是一个问题。例如,使用数据库事务来确保原子性。并使用异步脱机作业来处理长时间运行的任务(例如调度邮件列表)。

答案 1 :(得分:6)

如果在Zend Framework等良好的框架中涵盖了不良行为,那么很多。 任何花费10秒钟的时间都会搞砸,但你总是可以用http://de3.php.net/set_time_limit

来提高执行时间

许多大型网站都是用PHP编写的:Facebook,维基百科,StudiVZ,Digg.com等等。很多你正在谈论的事情只是配置事情,也许你应该研究一下?

答案 2 :(得分:4)

您是否在寻找set_time_limit()ignore_user_abort()

答案 3 :(得分:3)

在大部分网站完成后,性能不是您可以投入的功能。 您必须设计重载的站点。

如果数据库任务通常涉及10K行,那么您不仅应该准备好执行时间问题,还应该准备其他维护问题。

  • 最糟糕的情况:制作一致性工具来检查并修复这些错误。
  • 更好:不要在图像上删除图像,只需标记它们并让后台服务来处理昂贵的操作。
  • 最佳:您可以使用作业队列服务并将此作业添加到队列中。

答案 4 :(得分:2)

如果你确实需要在php中进行交易,你可以这样做:

mysql_query("BEGIN");

/// do your queries here

mysql_query("COMMIT");

commit命令只会完成事务。

如果发生任何错误,您只需回滚:

mysql_query("ROLLBACK");

编辑:注意这只有在您使用支持交易的数据库时才有效,例如InnoDB

答案 5 :(得分:1)

您可以在php.ini设置中或通过ini_set / set_time_limit

配置执行脚本所需的时间

答案 6 :(得分:1)

而不是studivz(德国Facebook克隆),你可以看看完全是PHP的实际Facebook。或者Digg。或许多雅虎网站。或许多其他人。

ignore_user_abort可能就是你要找的东西,但你也可以在计划维护工作方面添加另一层。它们基本上以指定的间隔运行并执行各种操作以确保您的数据/文件系统处于您想要的状态...删除旧的/未链接的文件只是您可以执行的许多操作之一。

答案 7 :(得分:0)

对于删除相册或发送1000封电子邮件等大型循环,您需要查找ignore_user_abort和set_time_limit。
像这样:

ignore_user_abort(true); //users leaves webpage will not kill script
set_time_limit(0); //script can take as long as it wants
for(i=0;i<10000;i++)
 costly_very_important_operation();

但请注意,这可能会永远运行脚本:

ignore_user_abort(true); //users leaves webpage will not kill script
set_time_limit(0); //script can take as long as it wants
while(true)
  do_something();

除非重新启动服务器,否则该脚本永远不会消亡。

因此,最好永远不要将time_limit设置为0。

答案 8 :(得分:0)

从技术上讲,没有编程语言是事务安全的,它是需要事务安全的数据库。因此,如果脚本/代码运行死亡或断开连接,无论出于何种原因,事务都将被回滚。

将查询置于循环中是一个非常糟糕的主意,除非它专门设计为批量运行并将更大的集合分成更小的部分。调整PHP定时器和限制通常是一个停止间隙解决方案,如果使用Web启动脚本,您仍然依赖于客户端浏览器。

如果我有一个需要通过浏览器启动的漫长过程,我会将该过程从浏览器和Web服务器“断开”,以便在脚本运行时将控制权返回给用户。如果需要,从命令行运行的PHP脚本可以运行几个小时。然后,您可以使用AJAX或重新加载页面来检查长时间运行的脚本的进度。

这段代码存在安全问题,但是要将一个进程与在Apache之类的东西下运行的PHP“断开连接”:

exec("nohup /usr/bin/php -f /path/to/script.php > /dev/null 2>&1 &");

但这与PHP适用于大型项目或交易安全无关。 PHP可用于大型项目,但由于默认情况下没有代码在命中之间保持“驻留”,如果设计不正确,它可能会变慢。此外,由于没有名称空间支持,如果您有一个大型开发团队,则需要提前计划。

基于Java的系统可以花几分钟时间来启动,初始化和加载所有默认对象。但这对PHP来说是不可接受的。 PHP将为更大的系统进行更多规划。问题是,使用PHP节省的时间是否会因大型系统所需的额外计划时间而浪费?

答案 9 :(得分:0)

您过去经常遇到错误的数据库一致性的原因是因为您使用MyISAM引擎进行mysql(不支持事务)。使用InnoDB,它支持事务并执行行级锁定。 或者使用postgreSQL。

答案 10 :(得分:-1)

许多软件站点都是用PHP制作的。但是,你不会听到数百万用PHP制作的网页因为被遗弃而不再存在。这些页面可能已经烧毁了所有公司的资金来处理PHP混乱,或者可能它们已经破产,因为它们的软件非常糟糕,客户不想要它... PHP在启动时看起来很擅长,但它不能很好地扩展。是的,有许多用PHP制作的大型网站,但它们是例外情况,而不是常态。