swoole server 超時控制以及踩過的坑

在選定swoole做爲PHP微服務的底層之後,我找了好久swoole server端的超時控制,可是,swoole的官方文檔裏,沒有寫server端的超時控制(相似於php-fpm的request_terminate_timeout配置),swoole源碼裏的example寫了php

examples/process/func_timeout.phpswoole

<?php
declare(ticks = 1);
Swoole\Async::set([
    'enable_signalfd' => false,
]);

class FunctionTimeoutException extends RuntimeException
{
    
}

function test()
{
    sleep(1);
}

$serv = new Swoole\Http\Server("127.0.0.1", 9502);

$serv->set(['worker_num' => 1]);

$serv->on('WorkerStart', function($serv, $workerId) {
    pcntl_signal(SIGALRM, function () {
        Swoole\Process::alarm(-1);
        throw new FunctionTimeoutException; 
    });
});

$serv->on('Request', function($request, $response) {
    try
    {
        Swoole\Process::alarm(100 * 1000);
        test();
        Swoole\Process::alarm(-1);
        $response->end("<h1>Finish</h1>");
    }
    catch(FunctionTimeoutException $e)
    {
        $response->end("<h1>Timeout</h1>");
    }

});

$serv->start();

可是這個用法有個地方要注意,它依賴系統信號SIGALRM,而PHP處理系統信號,依賴架構

declare(ticks = 1)

並且是每個文件的頭部都要加上這句代碼,require和include都不行(後面加上once也不行)。框架

我剛開始寫基礎框架的時候,沒有注意到這一點,而後上線查看日誌的時候,發現,明明timeout設置的爲1000ms,爲毛日誌裏沒有超過1000ms的超時日誌,而後才意識每一個文件都要加上declare(ticks = 1),測下來也確實如此,雖然很噁心,可是也沒辦法。async

可是,在PHP升級到PHP 7.1 以後,就不用寫這個了微服務

http://php.net/manual/zh/migration71.new-features.php#migration71.new-features.asynchronous-signal-handlingphp-fpm

只須要在框架入口處加上ui

pcntl_async_signals(true);

或者修改php.ini.net

pcntl.async_signals = 1

這樣就完美了。日誌

更多架構、PHP、GO相關踩坑實踐技巧請關注個人公衆號:PHP架構師

相關文章
相關標籤/搜索