業務初始化

有時我們需要在進程啟動後做一些業務初始化,這個初始化在進程生命週期只執行一次,例如進程啟動後設置一個定時器,或者初始化資料庫連接等。下面我們將對此進行講解。

原理

根據 執行流程 中的說明,webman 在進程啟動後會加載 config/bootstrap.php(包括 config/plugin/*/*/bootstrap.php)中設置的類,並執行類的 start 方法。我們在 start 方法中可以加入業務碼,即可完成進程啟動後的業務初始化操作。

流程

假設我們要做一個定時器,用於定時上報當前進程的內存佔用,這個類取名為 MemReport

執行命令

執行命令 php webman make:bootstrap MemReport 生成初始化文件 app/bootstrap/MemReport.php

提示
如果你的 webman 沒有安裝 webman/console,執行命令 composer require webman/console 安裝

編輯初始化文件

編輯 app/bootstrap/MemReport.php,內容類似如下:

<?php

namespace app\bootstrap;

use Webman\Bootstrap;

class MemReport implements Bootstrap
{
    public static function start($worker)
    {
        // 是否是命令行環境?
        $is_console = !$worker;
        if ($is_console) {
            // 如果你不想命令行環境執行這個初始化,則在這裡直接返回
            return;
        }

        // 每隔10秒執行一次
        \Workerman\Timer::add(10, function () {
            // 為了方便演示,這裡使用輸出代替上報過程
            echo memory_get_usage() . "\n";
        });

    }

}

提示
在使用命令行時,框架也會執行 config/bootstrap.php 配置的 start 方法,我們可以通過 $worker 是否是 null 來判斷是否是命令行環境,從而決定是否執行業務初始化碼。

配置隨進程啟動

打開 config/bootstrap.phpMemReport 類加入到啟動項中。

return [
    // ...這裡省略了其它配置...

    app\bootstrap\MemReport::class,
];

這樣我們就完成了一個業務初始化流程。

補充說明

自定義進程 啟動後也會執行 config/bootstrap.php 配置的 start 方法,我們可以通過 $worker->name 來判斷當前進程是什麼進程,進一步可以通過 $worker->id 判斷是幾號進程,然後決定是否在該進程執行你的業務初始化碼,例如我們只需要在 webman 的 0 號進程執行,則 MemReport.php 內容類似如下:

<?php

namespace app\bootstrap;

use Webman\Bootstrap;

class MemReport implements Bootstrap
{
    public static function start($worker)
    {
        // 是否是命令行環境?
        $is_console = !$worker;
        if ($is_console) {
            // 如果你不想命令行環境執行這個初始化,則在這裡直接返回
            return;
        }

        // 只在 webman 的 0 號進程執行
        if ($worker->name != 'webman' && $worker->id != 0) {
            return;
        }

        // 每隔10秒執行一次
        \Workerman\Timer::add(10, function () {
            // 為了方便演示,這裡使用輸出代替上報過程
            echo memory_get_usage() . "\n";
        });

    }

}