【问题标题】:Is PHP suitable for very large projects? Can it be transaction-safe?PHP 适合非常大的项目吗?它可以是交易安全的吗?
【发布时间】:2009-06-01 10:15:18
【问题描述】:

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

但是以前每次做PHP项目的时候,都会遇到这种不好的体验:

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

这不是交易安全的。我从来没有找到一种方法来安全地做某事,以确保它完成。如果脚本被杀死,它就会被杀死。就在一个循环的中间。它会被杀死。这从未发生在带有 java 的 tomcat 上。 Java 运行,运行,运行,如果需要很长时间。

许多时事通讯脚本试图通过将作业拆分成许多包来解决这个问题,即一次发送 100 个,然后重新加载页面(哦,伙计,真愚蠢),做下一个,然后很快。最常见的情况是挂起或执行脚本需要超过 10 秒的时间,并且您的平台已瘫痪。

但是,我听说非常大的项目使用 PHP,例如 studivz(德国的 facebook 克隆,实际上是最大的德国网站)。所以有一点希望,这种不良行为只是来自不专业的托管公司,他们只是因为他们的服务器太糟糕而杀死了 php 脚本。这件事的真相是什么?能否以这样的方式进行配置,使脚本永远不会因为它们花费更长的时间而被杀死?

【问题讨论】:

  • 当然您可以定义在 PHP 中执行脚本可能需要多长时间。在您自己的服务器上,只需将新值放入 php.ini 文件中即可。使用简单的虚拟主机解决方案,您几乎没有机会做到这一点。
  • set_time_limit(0);我拥有世界上所有的时间。

标签: php


【解决方案1】:

PHP 适合大型项目吗?

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

也就是说,您所描述的问题听起来像是您对自己的技术不够了解。无论您选择哪种技术,这对您来说都是一个问题。例如,使用数据库事务来确保原子性。并使用异步离线作业来处理长时间运行的任务(例如发送邮件列表)。

【讨论】:

    【解决方案2】:

    如果不良行为被 Zend 框架等良好的框架所涵盖,则很多。 任何需要更长 10 秒的东西都真的搞砸了,但你总是可以用 http://de3.php.net/set_time_limit 提高执行时间

    很多大型网站都是用 PHP 编写的:Facebook、Wikipedia、StudiVZ、Digg.com 等。你所说的很多东西都只是配置问题,也许你应该研究一下?

    【讨论】:

      【解决方案3】:

      您在寻找set_time_limit()ignore_user_abort() 吗?

      【讨论】:

      • ignore_user_abort 不计算脚本的最大执行时间
      • 他说的是10秒,默认的最大执行时间是30秒,所以我以为他的意思是用户停止执行的理论案例。发布更新。
      【解决方案4】:

      性能不是您可以在大部分网站完成后才加入的功能。 您必须为重负载设计网站。

      如果数据库任务通常涉及 10K 行,则不仅要准备执行时间问题,还要准备其他维护问题。

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

      【讨论】:

      • 在后台使用批处理是这样的方式。
      【解决方案5】:

      如果你确实需要在 php 中做事务,你可以这样做:

      mysql_query("BEGIN");
      
      /// do your queries here
      
      mysql_query("COMMIT");
      

      commit 命令只会完成事务。

      如果发生任何错误,您可以回滚:

      mysql_query("ROLLBACK");
      

      编辑:请注意,这仅适用于支持事务的数据库,例如 InnoDB

      【讨论】:

      • 最好指出,这只有在您使用的存储引擎真正支持事务(如 InnoDB)时才有效。
      • 是的,非常正确 - 忘记了
      • 很好,但是如果愚蠢的 PHP 服务器在第一个 sql 查询之后立即终止脚本会发生什么情况用户 B 的账号会加 10 吗?如果由于该脚本杀死 mysql_query("ROLLBACK") 永远不会被调用怎么办?那么我们就没有事务/没有回滚,对吧?
      • 回滚是隐式的。在提交提交之前不会写入更改。这就是交易的全部意义所在。
      【解决方案6】:

      您可以在 php.ini 设置中或通过 ini_set/set_time_limit 配置允许执行脚本的时间

      【讨论】:

        【解决方案7】:

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

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

        【讨论】:

          【解决方案8】:

          对于这些大型循环,例如删除相册或发送 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。

          【讨论】:

            【解决方案9】:

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

            将查询放在循环中是一个非常糟糕的主意,除非它专门设计为批量运行并将更大的集合分解成更小的部分。调整 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 节省的时间什么时候会被大型系统所需的额外规划时间浪费掉?

            【讨论】:

              【解决方案10】:

              您过去最有可能遇到数据库一致性不佳的原因是因为您使用的是 mysql 的 MyISAM 引擎(它不支持事务)。改用 InnoDB,它支持事务并执行行级锁定。 或者使用 postgreSQL。

              【讨论】:

                【解决方案11】:

                很多很多软件网站都是用 PHP 制作的。但是,您不会听说数以百万计的用 PHP 制作的网页因为被废弃而不再存在。那些页面可能因为处理 PHP 的混乱而烧掉了所有公司的钱,或者他们破产了,因为他们的软件太糟糕了以至于客户不想要它…… PHP 在启动时似乎很好,但它的扩展性不是很好。是的,有许多用 PHP 制作的大型网站,但它们只是例外,而不是常态。

                【讨论】:

                • 根据我的经验,即使是最好的工具,白痴也可能会搞砸,而优秀的工匠可以只做基础的工作。我不认为 PHP 本身可以成就或破坏任何业务。
                • 是的,但是 PHP 让你更容易搞错。 Jeff 收到了关于此 codinghorror.com/blog/archives/000940.html 的精彩博文
                猜你喜欢
                • 1970-01-01
                • 2010-11-24
                • 1970-01-01
                • 1970-01-01
                • 2011-03-20
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2023-03-14
                相关资源
                最近更新 更多