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架构师

相关文章
相关标签/搜索