hyperf 3.0 中通过 async-queue 与 redis 共用连接池实现任务执行后自动更新缓存:需安装两组件、调高 redis 连接池 max_connections、在 async_queue.php 中显式指定 pool='default',job 内注入 redis 并在 handle() 中 setex 写入、failed() 中 del 清除,确保缓存强一致。

在 Hyperf 3.0 中实现异步队列任务执行后自动更新缓存,避免手动调用 Redis 删除或写入逻辑出错、遗漏,防止用户看到过期数据。
配置 async-queue 与 redis 组件共用连接池
第一步:确认已安装两个组件(缺一不可)
composer require hyperf/async-queue hyperf/redis
第二步:修改 config/autoload/redis.php,将默认连接池的 max_connections 设为 ≥10
原因:async-queue 消费进程会复用该连接池,若 max_connections 过小(如默认 10),高并发时协程争抢连接会导致超时或阻塞;设为 15~20 更稳妥。
第三步:在 config/autoload/async_queue.php 中显式指定 redis 连接池名称
将 'redis' => ['pool' => 'default'] 写入 driver 配置块内,否则 async-queue 会新建独立连接池,与缓存层物理隔离,导致事务/锁失效。
创建带缓存联动的 Job 类
方法一:继承 Job 并注入 Redis 实例
在 app/Job/UpdateUserCacheJob.php 中定义:
```php
namespace App\Job;
use Hyperf\AsyncQueue\Job;
use Hyperf\Redis\Redis;
use Hyperf\Context\ApplicationContext;
class UpdateUserCacheJob extends Job
{
public int $userId;
public function __construct(int $userId)
{
$this->userId = $userId;
}
public function handle()
{
// ① 获取 Redis 实例(必须从容器获取,不能 new)
$redis = ApplicationContext::getContainer()->get(Redis::class);
// ② 查询数据库最新数据(此处省略 ORM 调用)
$user = $this->fetchLatestUser($this->userId);
// ③ 【关键】先 setex 再 del 旧 key,避免缓存击穿
$key = "user:{$this->userId}";
$redis->setex($key, 3600, json_encode($user));
}
}
```
提交任务并触发缓存更新
在 Controller 或 Service 中调用:
```php
use App\Job\UpdateUserCacheJob;
use Hyperf\AsyncQueue\Driver\DriverFactory;
// 提交任务(立即返回,不等待执行)
DriverFactory::get('default')->push(new UpdateUserCacheJob($userId));
```
这一步操作起来很简单,直接把任务对象传进去就行。注意不要用 new UpdateUserCacheJob(...)->handle() 同步调用,否则失去异步意义,且无法享受协程池调度优势。
处理失败重试时的缓存一致性
方法二:利用 retry_seconds + 自定义 handle 失败兜底
在 Job 类中补充 failed() 方法:
```php
public function failed(Throwable $exception)
{
$redis = ApplicationContext::getContainer()->get(Redis::class);
$key = "user:{$this->userId}";
// 【关键】失败时主动删除缓存,强制下次读库
$redis->del($key);
// 记录告警日志(可选)
\Hyperf\Logger\LoggerFactory::get('job')->error(‘UpdateUserCacheJob failed’, [‘user_id’ => $this->userId, ‘error’ => $exception->getMessage()]);
}
```
Hyperf 默认会在 retry_seconds 秒后重试(配置中默认为 5),若连续失败 max_attempts 次(默认 3 次),则进入 failed 方法。此时删缓存比留脏数据更安全——用户最多慢一次,不会永久看到错误内容。
验证缓存是否被正确更新
登录 Redis CLI 执行:
redis-cli -h 127.0.0.1 -p 6379<br>get user:123
如果返回 JSON 字符串且字段与数据库一致,说明联动成功。
若返回 nil,请检查 async-queue 消费进程是否启动:php bin/hyperf.php async-queue:consume











