webman/redis-queue消费进程奇怪的参数丢失问题

ziyoren

问题描述

Error: Call to a member function getBitwiseOperators() on null in /www/vendor/illuminate/database/Query/Builder.php:998

程序代码

消费类 app/queue/redis/BuyInsurance.php

<?php

namespace app\queue\redis;

use app\model\OrderCostItems;
use app\services\yuanxingbao\YuanxingApi;
use Webman\RedisQueue\Consumer;
use Workerman\RedisQueue\UnretryableException;
use support\Log;

class BuyInsurance implements Consumer
{
    // 要消费的队列名
    public $queue = 'insurance';

    // 连接名,对应 plugin/webman/redis-queue/redis.php 里的连接`
    public $connection = 'default';

    protected $orderCostItems;

    // 消费
    public function consume($data)
    {
        try {
            $this->orderCostItems = null;
            $id = intval($data['id']);  //这里将$data['id']转成Int类型
            if ($id <= 0) {
                throw new UnretryableException('保险订单ID不合法'); // 如果$id小于等于0时抛错
            }
            $orderCost = OrderCostItems::findOne($id);  // 日志中报错的地方`#8 /www/app/queue/redis/BuyInsurance.php(30)`
            if (!$orderCost) {
                throw new UnretryableException('保险订单不存在');
            }
            if (in_array($orderCost->Order->o_status, ['退票', '待确认'])) {
                throw new UnretryableException('保险订单状态: ' . $orderCost->Order->o_status . ' 无需购买保险');
            }
            $this->orderCostItems = $orderCost->OrderCostItems;
            $requestData = null;
            $result = YuanxingApi::createOrder($data['id'], $requestData);
            logs($data['id'], 'INFO', '开始投保', ['request' => $requestData, 'response' => $result]);
            $oci = $orderCost->OrderCostItems;
            $oci->ci_response = $result;
            $oci->ci_response_time = time();
            if ($result['code'] == 0) {
                $oci->ci_request_no = $result['data']['orderPolicyNo'] ?? '';
                $oci->ci_label = OrderCostItems::LABEL_BUYING;
                logs($data['id'], 'INFO', '投保成功!('. OrderCostItems::LABEL_BUYING . ')');
            }else{
                $oci->ci_label = OrderCostItems::LABEL_FAIL;
            }
            $oci->save();
            if ($result['code'] != 0){
                throw new UnretryableException('投保失败:'.$result['msg']);
            }
        } catch (\Throwable $e) {
            throw $e;
        }
    }

    public function onConsumeFailure(\Throwable $exception, $package)
    {
        Log::error((string)$exception, $package);
        logs($package['data']['id'], 'ERROR', $exception->getMessage(), $package);
        if ($this->orderCostItems) {
            $oci = $this->orderCostItems;
            $oci->ci_label = OrderCostItems::LABEL_FAIL;
            $oci->ci_response = $package;
            $oci->ci_response_time = time();
            $oci->save();
        }
    }
}

/www/app/model/OrderCostItems.php(85)
截图

报错信息

[2025-08-18 11:39:16] default.ERROR: Error: Call to a member function getBitwiseOperators() on null in /www/vendor/illuminate/database/Query/Builder.php:998
Stack trace:
#0 /www/vendor/illuminate/database/Query/Builder.php(902): Illuminate\Database\Query\Builder->isBitwiseOperator()
#1 /www/vendor/illuminate/database/Eloquent/Builder.php(331): Illuminate\Database\Query\Builder->where()
#2 /www/vendor/illuminate/database/Eloquent/Builder.php(281): Illuminate\Database\Eloquent\Builder->where()
#3 /www/vendor/illuminate/database/Eloquent/Builder.php(538): Illuminate\Database\Eloquent\Builder->whereKey()
#4 /www/vendor/illuminate/support/Traits/ForwardsCalls.php(23): Illuminate\Database\Eloquent\Builder->find()
#5 /www/vendor/illuminate/database/Eloquent/Model.php(2496): Illuminate\Database\Eloquent\Model->forwardCallTo()
#6 /www/app/model/OrderCostItems.php(85): Illuminate\Database\Eloquent\Model->__call()
#7 /www/vendor/illuminate/database/Eloquent/Model.php(2512): app\model\OrderCostItems->findOne()
#8 /www/app/queue/redis/BuyInsurance.php(30): Illuminate\Database\Eloquent\Model::__callStatic()
#9 /www/vendor/workerman/redis-queue/src/Client.php(243): app\queue\redis\BuyInsurance->consume()
#10 /www/vendor/workerman/redis/src/Client.php(421): Workerman\RedisQueue\Client->Workerman\RedisQueue\{closure}()
#11 /www/vendor/workerman/workerman/src/Connection/TcpConnection.php(750): Workerman\Redis\Client->Workerman\Redis\{closure}()
#12 [internal function]: Workerman\Connection\TcpConnection->baseRead()
#13 /www/vendor/workerman/workerman/src/Events/Event.php(250): EventBase->loop()
#14 /www/vendor/workerman/workerman/src/Worker.php(1751): Workerman\Events\Event->run()
#15 /www/vendor/workerman/workerman/src/Worker.php(1546): Workerman\Worker::forkOneWorkerForLinux()
#16 /www/vendor/workerman/workerman/src/Worker.php(1526): Workerman\Worker::forkWorkersForLinux()
#17 /www/vendor/workerman/workerman/src/Worker.php(594): Workerman\Worker::forkWorkers()
#18 /www/vendor/workerman/webman-framework/src/support/App.php(147): Workerman\Worker::runAll()
#19 /www/start.php(5): support\App::run()
#20 {main} {"id":644645736,"time":1755488276,"delay":5,"attempts":5,"queue":"insurance","data":{"id":"48370","orderNumber":"GP20258824916716"},"max_attempts":"5","error":"Call to a member function getBitwiseOperators() on null"} []

操作系统及workerman/webman等框架组件具体版本

--------------------------------------------------------- WORKERMAN ----------------------------------------------------------
Workerman/5.1.3         PHP/8.3.15 (JIT off)          Linux/4.18.0-348.20.1.el8_5.x86_64
---------------------------------------------------------- WORKERS -----------------------------------------------------------
event-loop  proto       user        worker                                listen                 count       state
event       tcp         root        webman                                http://0.0.0.0:8787    4            [OK]
event       tcp         root        monitor                               none                   1            [OK]
event       tcp         root        plugin.webman.redis-queue.consumer    none                   8            [OK]
------------------------------------------------------------------------------------------------------------------------------
31 3 0
3个回答

ziyoren

消费类对$id进行了判断,只有正确了才会执行到30行。可是30行调用的findOne里的代码却报错
截图

  • 暂无评论
ziyoren

另外还找到一些这样的报错日志

Next Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1243 Unknown prepared statement handler (7647) given to mysqld_stmt_execute (Connection: erp, SQL: select 1) in /www/vendor/illuminate/database/Connection.php:822
Stack trace:
#0 /www/vendor/illuminate/database/Connection.php(776): Illuminate\Database\Connection->runQueryCallback()
#1 /www/vendor/illuminate/database/Connection.php(395): Illuminate\Database\Connection->run()
#2 /www/vendor/webman/database/src/DatabaseManager.php(63): Illuminate\Database\Connection->select()
#3 /www/vendor/workerman/coroutine/src/Pool.php(328): Webman\Database\DatabaseManager->Webman\Database\{closure}()
#4 /www/vendor/workerman/coroutine/src/Pool.php(312): Workerman\Coroutine\Pool->trySendHeartbeat()
#5 /www/vendor/workerman/coroutine/src/Pool.php(132): Workerman\Coroutine\Pool->checkConnections()
#6 /www/vendor/workerman/workerman/src/Events/Event.php(285): Workerman\Coroutine\Pool->Workerman\Coroutine\{closure}()
#7 /www/vendor/workerman/workerman/src/Events/Event.php(144): Workerman\Events\Event->safeCall()
#8 [internal function]: Workerman\Events\Event->Workerman\Events\{closure}()
#9 /www/vendor/workerman/workerman/src/Events/Event.php(250): EventBase->loop()
#10 /www/vendor/workerman/workerman/src/Worker.php(1751): Workerman\Events\Event->run()
#11 /www/vendor/workerman/workerman/src/Worker.php(1546): Workerman\Worker::forkOneWorkerForLinux()
#12 /www/vendor/workerman/workerman/src/Worker.php(1526): Workerman\Worker::forkWorkersForLinux()
#13 /www/vendor/workerman/workerman/src/Worker.php(594): Workerman\Worker::forkWorkers()
#14 /www/vendor/workerman/webman-framework/src/support/App.php(147): Workerman\Worker::runAll()
#15 /www/start.php(5): support\App::run()
#16 {main}
  • 暂无评论
ziyoren

截图

根据日志的时间显示,第一次执行队列任务17:00:06,5秒后17:00:11再次执行,第三次执行才成功。感觉跟SQLSTATE[HY000]: General error: 1243 Unknown prepared statement handler (7647) given to mysqld_stmt_execute (Connection: erp, SQL: select 1)这个报错有一定的关系

截图

  • 暂无评论
🔝