You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Job的failed方法中访问Redis数据出现异常输出

Laravel Job failed方法中Redis命令返回异常(llen返回字符串、hgetall报类型错误)

问题场景

开发Laravel应用时,在Job的failed方法中尝试读取Redis的列表和哈希数据,出现异常:

  • 调用llen返回字符串timestamp而非预期的数字
  • 调用hgetall触发类型错误:array_values(): Argument #1 ($array) must be of type array, string given

相关代码

public function failed($exception = null): void
{
    // ...

    if (Redis::exists($this->redisFileKey)) {
        $fileCount = Redis::llen($this->redisFileKey);
        Log::info("File count: " . $fileCount);
    }

    $orderDetails = Redis::hgetall($this->redisMainDataKey);
    Log::info("Order details: " . var_export($orderDetails, true));

    // ...
}

错误日志

[2024-03-22 19:44:13] local.INFO: File count: timestamp
[2024-03-22 19:44:13] local.ERROR: array_values(): Argument #1 ($array) must be of type array, string given {"exception":"[object] (TypeError(code: 0): array_values(): Argument #1 ($array) must be of type array, string given at /var/www/html/vendor/predis/predis/src/Command/Redis/HGETALL.php:35)

已通过Redis Insight确认对应键的类型为列表和哈希。


排查与解决方案

1. 验证键名与Redis数据库一致性

  • 先打印键的实际值,确认是否指向预期的键:
    Log::info('Redis File Key: ' . $this->redisFileKey);
    Log::info('Redis Main Data Key: ' . $this->redisMainDataKey);
    
  • 检查当前Redis连接的数据库,确认与存储数据时的DB一致:
    Log::info('Current Redis DB: ' . Redis::connection()->getDb());
    
  • 用Redis CLI直接验证键的类型和值:
    # 检查键存在性与类型
    redis-cli EXISTS your_file_key
    redis-cli TYPE your_file_key
    redis-cli EXISTS your_main_data_key
    redis-cli TYPE your_main_data_key
    
    # 直接执行命令验证结果
    redis-cli LLEN your_file_key
    redis-cli HGETALL your_main_data_key
    

2. 确认Redis连接实例一致性

如果存储数据时使用了自定义Redis连接(而非默认连接),读取时必须使用相同连接:

// 存储时用自定义连接
Redis::connection('cache')->lpush($this->redisFileKey, 'data');

// failed方法中也要用相同连接读取
$fileCount = Redis::connection('cache')->llen($this->redisFileKey);

同时检查队列配置的Redis连接,确保与数据存储的Redis配置一致。

3. 排查Job属性序列化问题

Job的属性会被序列化后存入队列,可能在反序列化过程中被篡改:

  • 在handle方法和failed方法中分别打印$this->redisFileKey、$this->redisMainDataKey,对比值是否一致
  • 确保这些属性没有在构造函数之外被修改

4. 添加类型检查规避异常

在调用Redis命令前先验证键的类型,避免错误:

$fileKeyType = Redis::type($this->redisFileKey);
Log::info('File Key Type: ' . $fileKeyType);
if ($fileKeyType === 'list' && Redis::exists($this->redisFileKey)) {
    $fileCount = Redis::llen($this->redisFileKey);
    Log::info("File count: " . $fileCount);
}

$mainKeyType = Redis::type($this->redisMainDataKey);
Log::info('Main Data Key Type: ' . $mainKeyType);
if ($mainKeyType === 'hash') {
    $orderDetails = Redis::hgetall($this->redisMainDataKey);
    Log::info("Order details: " . var_export($orderDetails, true));
}

内容的提问来源于stack exchange,提问作者Rupesh Bhandari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 03:37:37