惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 三生石上(FineUI控件)
Y
Y Combinator Blog
aimingoo的专栏
aimingoo的专栏
B
Blog
小众软件
小众软件
D
DataBreaches.Net
T
The Blog of Author Tim Ferriss
L
LangChain Blog
WordPress大学
WordPress大学
罗磊的独立博客
GbyAI
GbyAI
S
SegmentFault 最新的问题
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
Tailwind CSS Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
月光博客
月光博客
IT之家
IT之家
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
雷峰网
雷峰网
美团技术团队
F
Fortinet All Blogs
Hugging Face - Blog
Hugging Face - Blog
The GitHub Blog
The GitHub Blog

博客园 - zh7314

Go 1.23 → 1.26 升级检查文档 Pimcore 版本功能对比表(Community / Professional / Enterprise) typephp的编译核心phpx原理解析 typephp的编译原理 golang多版本控制工具支持Linux/macOS/Windows dbx低性能消耗的支持window/mac/docker的数据库客户端 关于headless和低代码平台的一些思考 docker日志监控dozzle,高性能,性能消耗小 pimcore 12版本的命令 阿里云 nas服务挂了导致docker挂载目录不存,docker无法重启和停止容器 symfony+swoole性能测试 关于小米手机使用 microsoft authenticator 无法扫码成功的解决方案 fastapi的构建cms,推荐fastapi集成框架 s3rius/FastAPI-template python 现代化包管理工具uv安装和使用 博文阅读密码验证 - 博客园 laravel在cli模式下输出格式漂亮一些 laravel计划任务和异步队列任务,拆分成不同队列,减少计划任务系统压力 debug redis里面的lua脚本 laravel chunkById导出数据乱序问题 PHP 真正异步编程即将到来 首个 alpha 版本已经发布 (转) 关于his esb企业服务总线系统设计 多渠道订单,对应渠道公司的提现主体,如何设计系统 laravel 主表和从表一对一,从表是要多个选取最新的一条,性能优化 sourcetree无法获取远程所有的tag 支付宝沙盒模式商家转账经常出现 响应异常: 解包错误 hyperf 的默认创建项目部署k8s docker缺失文件 在laravel使用注解自动注册 hyperf 查看所有路由的命令 线上就医全流程医药机构接入文档接口代码-医保就医接口php-demo版本 windows lm studio 0.3.8无法下载模型,更换镜像
laravel 使用异步队列,context带的上下文造成反序列化出问题
zh7314 · 2025-05-08 · via 博客园 - zh7314

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]);
                }
            }
        }

    }
}