PHP 程序跑在 Windows 服务上

起因

项目在window上后台运行Workerman,避免命令行窗口给别人关闭,并且系统重启时自动运行项目。我一开始想的是用计划任务来做,但是总监建议用服务或第三方软件来控制,所以开启了探索之路。

运行环境

  • php:workerman3.5

  • 服务器:Windows Server2008

过程

搜索了php的扩展,发现有一个扩展:win32service,可以利用此扩展生成一个运行php的服务,可以避免命令行窗口给别人关闭,同样可以系统重启自动运行,于是开始了摸索之路,原本以为会很顺利的,但是并没有....

代码实现

从网上搜了个代码来使用,自己改了下..

class WinService
{
    //服务名称
    private $name = 'forWorkerman3';
    //定义服务名称
    private $info_name = "forWorkerman3";
    //定义php.exe存放路径
    private $path = "E:\php\php-7.2.1-nts\php.exe";
    //定义所要执行的程序
    private $params = "E:\phpwork\process\start.php";

    public function install()
    {
        /* 注册服务  */
        $server = win32_create_service(array(
            'service' => $this->name,
            'display' => $this->info_name,
            'path' => $this->path,
            'params' => $this->params,
        ));

        if ($server !== true) {
            return "安装失败" . "\t 错误代码:" . dechex($server);
        }

        return '服务创建成功!';

    }

    /* 移除服务 */
    public function uninstall()
    {
        $removeService = win32_delete_service($this->name);
        $log = '';
        switch ($removeService) {
            case 1060:
                $log = '服务不存在';
                break;
            case 1072:
                $log = '服务无法卸载 ';
                break;
            case 0:
                $log = "服务卸载成功";
                break;
            default    :
                break;
        }
        return $log;
    }

    public function restart()
    {
        /* 重启服务 */
        $svcStatus = win32_query_service_status($this->name);

        if ($svcStatus == 1060) {
            return "服务[" . $this->name . "]未被安装,请先安装";

        }
        if ($svcStatus['CurrentState'] == 1) {
            return $this->start();
        }

        $stop = win32_stop_service($this->name);
        if ($stop != 0) {
            return "服务正在执行,请重试! ";
        } else {
            return $this->start();
        }
    }

    public function start()
    {
        $start = win32_start_service($this->name);
        if ($start != 0) {
            return " 服务正在运行中! ";
        }
        return " 服务已启动! ";

    }

    public function stop()
    {
        $stop = win32_stop_service($this->name);
        if ($stop != 0) {
            return "服务未启动";
        }
        return "服务已停止";

    }
}

$service = new WinService();

if (php_sapi_name() !== 'cli') {
    trigger_error("脚本只能运行在cli模式下");
    exit();
}
$log = '';
switch ($argv[1]) {
    case "install" :
        $log = $service->install();
        break;
    case "uninstall" :
        $log = $service->uninstall();
        break;
    case "start":
        $log = $service->start();
        break;
    case "stop":
        $log = $service->stop();
        break;
    case "restart":
        $log = $service->restart();
        break;
    default:
        var_dump("无事发生...");
}
echo $log;

结果

然而是我太年轻了,运行普通的php程序是没有任何问题的,但是运行workerman却无法正常运行。实际上测试到的结果是,在开启服务的期间,workerman实际上是运行成功了,但是却无法一直保持着服务开启的状态。找了许久的解决方法也没找到,所以就放弃了。

意外收获

在网上搜解决保持服务开启的解决方案时候,意外发现有软件可以帮我生成一个服务,这个软件就是Nssm。下载好之后用命令行运行nssm.exe install <服务名称>

NSSM 生成 Windows 服务

这个界面就是这个软件的gui了。按照自己的需求打开

NSSM 生成 Windows 服务

选择自己要运行的文件

NSSM 生成 Windows 服务

点击install service即可安装成服务了

如果要卸载服务运行nssm.exe remove <服务名称>

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!