Swoole进程中调用tp6内置类方法

背景

这个古怪的需求来自于懒~, 懒得重新写一套属于 swoole 的方法了

当然在进程中直接复用 Db 类方法,验证类方法也是很容易的。

示例

这里以日志方法 log 为例:

<?php
ini_set("display_errors", "On");
ini_set("error_reporting", "E_ALL");

use Swoole\Process;
use Swoole\Coroutine;

$pool = new Process\Pool(2);
// $pool->set(['enable_coroutine' => true]);

// 加载 autoload 
require __DIR__ . '/../vendor/autoload.php';

$pool->on('WorkerStart', function (Process\Pool $pool, $workerId) {
    /** 当前是 Worker 进程 */
    static $running = true;
    Process::signal(SIGTERM, function () use (&$running) {
        $running = false;
        echo "TERM\n";
    });
    echo("[Worker #{$workerId}] WorkerStart, pid: " . posix_getpid() . "\n");
    while ($running) {
        // Coroutine::sleep(1);
        // echo "sleep 5\n";
        // sleep(5);
        // require __DIR__ . '/../vendor/autoload.php';
        var_dump('====');
        try {

            // 这里来启用ThinkPhp并调用
            $app = new \think\App();
            $app->debug(true);
            $app->http->run(); // 使用run方法来启动框架,参见tp6的index.php入口文件
            $app->log->write("test log...");
        } catch (\Exception $e){
            echo $e->getMessage() . PHP_EOL;
            echo $e->getTraceAsString() . PHP_EOL;
        }
        echo "sleep 5\n";
        sleep(5);
    }
});
$pool->on('WorkerStop', function (\Swoole\Process\Pool $pool, $workerId) {
    echo("[Worker #{$workerId}] WorkerStop\n");
});
$pool->start();

当然,改完后的内存占用还是有牺牲的。

2022-12-06 15:25:04 #usedMemory:1.277M==========>>
2022-12-06 15:25:06 #usedMemory:1.277M==========>>
2022-12-06 15:25:07 #usedMemory:1.277M==========>>
2022-12-06 15:25:07 #usedMemory:1.277M==========>>
2022-12-06 15:25:09 #usedMemory:1.277M==========>>
2022-12-06 15:25:11 #usedMemory:1.277M==========>>
2022-12-06 15:25:12 #usedMemory:1.277M==========>>
2022-12-06 15:25:13 #usedMemory:1.277M==========>>
2022-12-06 15:25:14 #usedMemory:1.277M==========>>
2022-12-06 15:25:15 #usedMemory:1.277M==========>>


---- before vs after ----

2022-12-06 15:48:42 #usedMemory:4.843M==========>>
2022-12-06 15:48:43 #usedMemory:1.554M==========>>
2022-12-06 15:48:54 #usedMemory:1.593M==========>>
2022-12-06 15:48:57 #usedMemory:4.843M==========>>
2022-12-06 15:49:00 #usedMemory:1.593M==========>>
2022-12-06 15:49:06 #usedMemory:1.554M==========>>
2022-12-06 15:49:07 #usedMemory:1.554M==========>>
2022-12-06 15:49:09 #usedMemory:1.593M==========>>
2022-12-06 15:49:13 #usedMemory:4.883M==========>>
2022-12-06 15:49:14 #usedMemory:1.554M==========>>

参考:
让Swoole完美支持ThinkPHP5_jeremyke07的博客-CSDN博客_thinkphp5 使用swoole
让swoole完美支持ThinkPHP6.0_丁丁丁梦涛的博客-CSDN博客

后续

今天看日志,发现 swoole 加载 thinkphp6 后存在内存泄漏问题,一开始 1.xM,到后来13.xM。

应该是程序有问题,看了下可能导致 swoole 内存泄漏的问题,详见:编程须知 | Swoole4 文档

初步判断这个问题应该是 thinkphp6 在初始化时有一些静态变量(或全局变量)导致,我们修改代码为闭包形式载入,避免每次初始化时静态变量累积导致的内存泄漏问题。

ini_set("display_errors", "On");
ini_set("error_reporting", "E_ALL");

use Swoole\Process;
use Swoole\Coroutine;

$pool = new Process\Pool(2);
// $pool->set(['enable_coroutine' => true]);

require __DIR__ . './../vendor/autoload.php';
$thinkApp = new \think\App(); // 在外部初始化,以闭包形式传入多进程

$pool->on('WorkerStart', function (Process\Pool $pool, $workerId)
 use ($thinkApp)
 {
    /** 当前是 Worker 进程 */
    static $running = true;
    Process::signal(SIGTERM, function () use (&$running) {
        $running = false;
        echo "TERM\n";
    });
    echo("[Worker #{$workerId}] WorkerStart, pid: " . posix_getpid() . "\n");
    while ($running) {
        // Coroutine::sleep(1);
        // echo "sleep 5\n";
        // sleep(5);
        // require __DIR__ . '/../vendor/autoload.php';
        var_dump('====');
        try {
            // $thinkApp = new \think\App();
            // $thinkApp->debug(true);
            $thinkApp->http->run();
            // $thinkApp->log->write("test onWorkerStart");
        } catch (\Exception $e){
            echo $e->getMessage() . PHP_EOL;
            echo $e->getTraceAsString() . PHP_EOL;
        }
        echo "sleep 1\n";
        sleep(1);

        $usedMemory = memory_get_usage();
        $usedMemory = round($usedMemory / 1024 / 1024, 3);
        echo date('Y-m-d H:i:s') . " #usedMemory:{$usedMemory} M==========>>\n";
    }
});

$pool->on('WorkerStop', function (\Swoole\Process\Pool $pool, $workerId) {
    echo("[Worker #{$workerId}] WorkerStop\n");
});
$pool->start();

ok,修改完后观察一段时间,一直稳定在 1.5M左右~

Author: thinkwei

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注