在子进程的回调里使用empty 或者isset 导致进程卡死

codeninjia
$worker->onMessage = function ($connection, $data) {
    try {
        $ret = call_user_func_array(array(SERVICE_DIR."\\".$class, $method), $param_array);
 /*这里我只要判断比如 isset($ret);进程机会卡死。走不到 下面如果我不判断直接返回的就可以。
我本地可以,本地的版本是php7.0 服务器上不行。版本是php7.15。其实这个时候返回的数据$ret 是个空数组
,*/

    StatisticClient::report($class, $method, 1, 0, '', $statistic_address);
   return $connection->send($ret);
   }
    catch (Exception $e) {
        // 发送数据给客户端,发生异常,调用失败
    $code = $e->getCode() ? $e->getCode() : 500;
        StatisticClient::report($class, $method, $success, $code, $e, $statistic_address);
        return $connection->send(array('code' => $code, 'msg' => $e->getMessage(), 'data' => $e));
    }
}

strce 打出来的信息里。比较有用的是

poll(, 1, 0) = 0 (Timeout)
sendto(23, "*3\r\n$3\r\nSET\r\n$61\r\nhooker_config_"..., 89, MSG_DONTWAIT, NULL, 0) = 89
poll(, 1, 0) = 0 (Timeout)
poll(, 1, 3000) = 1 ()
recvfrom(23, "+OK\r\n", 8192, MSG_DONTWAIT, NULL, NULL) = 5
poll(, 1, 0) = 0 (Timeout)
sendto(23, "*4\r\n$4\r\nHSET\r\n$56\r\nhooker_config"..., 121, MSG_DONTWAIT, NULL, 0) = 121
poll(, 1, 0) = 0 (Timeout)
poll(, 1, 3000) = 1 ()
recvfrom(23, ":0\r\n", 8192, MSG_DONTWAIT, NULL, NULL) = 4
3194 2 0
2个回答

six

把$ret打印出来看看是什么,估计$ret不是数组,是不是isset($ret)报错抛异常了?
存猜测。

另外如果$ret是数组的话,$connection->send($ret); 应该不行把,我记得send的数据好像必须是字符串的

  • codeninjia 2017-10-18

    打出来看了确实是个数组,至于send的话。我是用的json协议会自动转。如果我用empty判断,然后给个空数组,就不会报错了。

walkor

看strace信息是你的业务一直在操作redis,估计是业务进入了某个死循环或者大的循环导致业务卡住了。
还有看起来你的redis好像返回有点慢,看下redis负载,或者可能是其它原因导致redis返回很慢。
redis操作关键字大概是
redis->set('hooker_config_...', ...);
redis->hset('hooker_config...', ...);

  • codeninjia 2017-10-23

    谢谢回答,我在输出$ret 的时候看返回的是空数组呢,你的意思是在查询redis的时候redis其实并没有响应,所以会导致进程卡死对吗?在多问一个问题,就是我在进行压测的时候偶尔会出现,
    RedisException' with message 'read error on connection 这个错误。
    workerman和php的版本如下。谢谢
    ----------------------- WORKERMAN -----------------------------
    Workerman version:3.5.1 PHP version:5.5.33

  • walkor 2017-10-24

    read error on connection 是redis问题,和workerman无关

  • walkor 2017-10-24

    redis无响应会卡死

  • codeninjia 2017-10-25

    @1:意思是 read error on connection 这样错误是redis自己的问题。不是代码的事情可以这样理解吗

  • codeninjia 2017-10-25

    @1:还有就是如果跑在php7.1的环境下是不会报错的。现在5.5的环境下会报那个错误。

  • walkor 2017-10-26

    read error on connection应该不是业务代码的问题。php7.1的环境下是不会报错有可能是redis扩展在这个版本修复了这个问题。以上只是猜测。

  • codeninjia 2017-11-01

    @1:恩我已经升级了现在没问题了。谢谢回答。

年代过于久远,无法发表回答
🔝