【问题标题】:Setting a PHP script as a Windows Service将 PHP 脚本设置为 Windows 服务
【发布时间】:2011-05-10 15:27:46
【问题描述】:

我需要将 PHP 脚本设置为 Windows 服务。

无论哪个用户登录和系统启动,我都需要它运行 - 所以听起来 Windows 服务是最好的,但很高兴听到其他建议。

(此脚本连续运行,它不是“每 5 分钟运行一次”,我可以使用计划任务管理器。)

http://support.microsoft.com/kb/251192 涵盖使用 sc.exe 程序安装您的服务。

但是根据我的阅读,我需要对 PHP 脚本进行包装,以接受来自 Windows 服务管理器的特殊命令。有人可以帮忙吗?

【问题讨论】:

    标签: php windows windows-services


    【解决方案1】:

    也许Resource Kit Tools(特别是 srvany.exe)可以在这里为您提供帮助。 MSDN:How To Create A User-Defined Service 和可能的 this hint for 2008 Server 应该可以帮助您将 any 可执行文件设置为服务。 (我已经在 Windows 2003 Server、Windows 2008 Server 和 Windows XP Professional [其他资源工具包,不过] 上成功使用了它)

    您将创建一个包含 php your-script.php 的 bat,用 srvany.exe 包装它,瞧,一旦机器加载服务,脚本就会启动。

    srvany.exe 应该处理您希望守护程序执行的那些启动/停止/重新启动调用。它会在启动时加载您的可执行文件,在停止时终止进程,在重新启动时执行两者。所以你不必担心这部分。您可能想检查 register_shutdown_function() 是否可以帮助确定您的服务进程何时被终止。

    您甚至可以定义对其他服务的依赖项(比如一些数据库或类似的)。

    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\THENAMEOFYOURSERVICE]
    "DependOnService"="DEPENDONTHIS"
    

    THENAMEOFYOURSERVICE 替换为您提供的服务名称,将DEPENDONTHIS 替换为要依赖的服务名称(例如“Postgres9.0”或其他名称)。将该文件保存到dependency.reg 并使用regedit /s dependency.reg 加载它。 (或者在资源管理器中双击它...)

    【讨论】:

    • 您好 - 感谢您的详细回答。我实际上不再需要这样做了,所以目前不会对其进行测试,但这看起来是尝试其他人的正确路径。
    • 虽然这已经很老了,但我想指出一个非常旧的 srvany.exe 的替代方案(例如,它不会对底层 php 脚本的终止做出反应):NSSM(非吸服务器管理器)它是 srvany.exe 的兼容替代品。见nssm.cc
    【解决方案2】:

    我们为此任务使用了FireDaemon,它不需要包装脚本等。不幸的是它不是免费软件。

    【讨论】:

      【解决方案3】:

      您可以通过提供不同的参数以及脚本文件作为参数在命令行上运行 php。如果您将所需的整行添加到它应该运行的服务配置中。因此,您也可以在创建服务之前试用该设备。 如果 php-script 在您的 web-route 之外,您应该将该文件夹添加到 windows 的 PATH-Variable 中。

      【讨论】:

        【解决方案4】:

        我找到了这个,但我自己没有尝试过。 PHP 实际上带有一些函数来做到这一点: http://uk.php.net/manual/en/book.win32service.php

        以下是一些示例: http://uk.php.net/manual/en/win32service.examples.php

        <?php
        if ($argv[1] == 'run') {
          win32_start_service_ctrl_dispatcher('dummyphp');
        
          while (WIN32_SERVICE_CONTROL_STOP != win32_get_last_control_message()) {
            # do your work here.
            # try not to take up more than 30 seconds before going around the loop
            # again
          }
        }
        ?>
        

        【讨论】:

        【解决方案5】:

        几天后……我找到了这个绝妙的选择!

        他构建了一个 .exe 来接收服务选项并且工作正常!

        https://superuser.com/questions/628176/php-cgi-exe-as-a-windows-service/643676#643676

        命令正确:

        sc create FOO binPath="service.exe \"C:\php\php-cgi.exe -b 127.0.0.1:9000 -c C:\php\php.ini"\" type= own start= auto error= ignore DisplayName= "FOO php"

        【讨论】:

        • OP 询问“我需要将 PHP 脚本设置为 Windows 服务。”并且您提供了如何将 php 作为服务器运行。两种不同的东西。
        【解决方案6】:

        NSSM - the Non-Sucking Service Manager也是一种解决办法,然后

        nssm install PHP php-cgi.exe -b 127.0.0.1:9000 -c C:\php\php.ini
        

        【讨论】:

          【解决方案7】:

          在 shell 中循环。

          1. 在 php 循环中添加循环计数器并在小时后退出以重新启动过程。
          2. 内存使用控制
          3. 每 100 秒重新连接到数据库

          Shell 脚本执行简单循环,每次迭代都会创建新的日志文件

          PHP 和 shell 脚本:

              ini_set('memory_limit', '300M');
              $loopCnt = 0;
              while(true) {
                  /**
                   * Maximal time limit for loop execution
                   */
                  set_time_limit(10);
                  $loopCnt ++;
                  /**
                   * each hour finishing
                   */
                  if($loopCnt > 60 * 60){
                      exit;
                  }
                  usleep(self::SLEEP_MICROSECONDS);
                  if ($loopCnt % 60 === 0) { //log every 60 seconds memory usage
                      $this->out('memory usage: '.memory_get_usage());
                      //reconnect DB to avoid timeouts and server gone away errors
                      Yii::$app->db->close();
                      Yii::$app->db->open();
                  }
                  if (memory_get_usage() > self::MEMORY_LIMIT) {
                      $this->out('memory limit reached: '.self::MEMORY_LIMIT . ' actual:  ' . memory_get_usage() . ' exit');
                      exit;
                  }
                  
                  /**
                  *  do work
                  */
          
              }
          
          }
          

          // bat文件

           set loopcount=1000000
          
           :loop
          
               echo Loop %DATE% %TIME% %loopcount%
          
               set t=%TIME: =0%
          
               php cwbouncer.php > C:\logs\cwbouncer_%DATE:~2,2%%DATE:~5,2%%DATE:~8,2%_%t:~0,2%%t:~3,2%%t:~6,2%.log
          
              set /a loopcount=loopcount-1
          
              if %loopcount%==0 goto exitloop
          
              goto loop
          
          :exitloop
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-07-04
            • 2011-06-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-01-08
            相关资源
            最近更新 更多