laravel 使用异步队列,context带的上下文造成反序列化出问题

2025年5月8日17:03:44
如果你是单个应用,异步递交任务,是在应用内部使用,一般不会发生这样的问题

但是现在app项目是 app是一个应用,admin是一个应用,app吧为了接口性能吧异步任务丢给admin去执行,如果两个应用的。就会出现部分使用

   Context::add('laravel_unique_job_key', 4444);
   Context::addHidden('eeee', 333333);

   $tokenInfo = new TokenInfo();
   Context::add('tokenInfo', $tokenInfo);

如果 增加的 储存在上下文的value部分有对象的值的时候,比如 TokenInfo的在发送 dispatchJob($job);
就会吧 Context里面 datahidden部分会带入 payload

{
    "displayName": "App\\Jobs\\Job",
    "job": "Illuminate\\Queue\\CallQueuedHandler@call",
    "maxTries": 3,
    "maxExceptions": null,
    "failOnTimeout": false,
    "backoff": null,
    "timeout": null,
    "retryUntil": null,
    "data": {
        "commandName": "App\\Jobs\\Job",
        "command": "O:27:\"App\\Jobs\\Job\":1:{s:7:\"orderId\";i:221;}"
    },
    "illuminate:log:context": {
        "data": {
            "tokenInfo": "O:40:\"App\\Http\\TokenInfo\":2:{s:4:\"uuid\";s:0:\"\";s:2:\"id\";i:0;}",
            "zx": "i:11111;"
        },
        "hidden": {
            "eeee": "i:333333;"
        }
    }
}

如果admin 没有 TokenInfo的对象就会报错,

RuntimeException: Value is incomplete class: {"__PHP_Incomplete_Class_Name":"App\\Http\\TokenInfo","uuid":"","id":0} 

解决方案:
1,在上游分发异步任务的时候,就不要有 Context 相关的使用 对象类型的数据
2,在下游执行任务的项目,吧存储的对象也复制一份
3,自己封装一个分发方法


if (!function_exists('dispatchJob')) {
    function dispatchJob(mixed $job)
    {
        //需要排除的key,这些key可能会影响队列的部分功能,需要先排除
        $excludeKey = ['laravel_unique_job_cache_store', 'laravel_unique_job_key'];

        $stay = $all = Context::all();
        $stayHidden = $allHidden = Context::allHidden();

        // 判断是否有上下文,如果没有直接 分发job
        if (empty($all) && empty($allHidden)) {
            dispatch($job);
        } else {
            //先 forget 所有比不需要的key,dispatch 之后在还给 Context

            //需要删除的 context key
            $filterKey = Arr::except($all, $excludeKey);
            $filterHiddenKey = Arr::except($allHidden, $excludeKey);

            $keys = array_keys($filterKey);
            $hiddenKeys = array_keys($filterHiddenKey);

            // 删除不必要的key
            if (!empty($keys)) {
                foreach ($keys as $key) {
                    Context::forget($key);
                }
            }
            // 删除不必要的隐藏key
            if (!empty($hiddenKeys)) {
                foreach ($hiddenKeys as $hiddenKey) {
                    Context::forgetHidden($hiddenKey);
                }
            }
            //分发任务
            dispatch($job);
            //归还上下文
            if (!empty($keys)) {
                foreach ($keys as $key) {
                    Context::add($key, $all[$key]);
                }
            }

            if (!empty($hiddenKeys)) {
                foreach ($hiddenKeys as $hiddenKey) {
                    Context::addHidden($hiddenKey, $allHidden[$hiddenKey]);
                }
            }
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值