Laravel更新composer后Predis报Unknown response prefix异常
问题背景
近期对Laravel项目执行小规模composer更新后,部分业务事件触发时开始出现报错,异常由v1.1.10版本的Predis抛出。
根据Predis源码逻辑,Redis协议合法响应前缀应为+、$、*、:、-,但实际返回了不符合规范的前缀值,相关异常信息如下:
异常样例
Unknown response prefix: '"'. [tcp://someurl-europe-west2.redis.production.internal:6379] Unknown response prefix: '"'. [tcp://someurl-europe-west2.redis.production.internal:6379] Unknown response prefix: '0'. [tcp://someurl-europe-west2.redis.production.internal:6379] Unknown response prefix: '3'. [tcp://someurl-europe-west2.redis.production.internal:6379] Unknown response prefix: 'e'. [tcp://someurl-europe-west2.redis.production.internal:6379] Unknown response prefix: 'e'. [tcp://someurl-europe-west2.redis.production.internal:6379] Unknown response prefix: 'e'. [tcp://someurl-europe-west2.redis.production.internal:6379] Unknown response prefix: 'R'. [tcp://someurl-europe-west2.redis.production.internal:6379]
异常调用栈
Predis\Protocol\ProtocolException Unknown response prefix: '0'. [tcp://someurl-europe-west2.redis.production.internal:6379] vendor/predis/predis/src/Connection/AbstractConnection.php:167 Predis\Connection\AbstractConnection::onProtocolError vendor/predis/predis/src/Connection/StreamConnection.php:370 Predis\Connection\StreamConnection::read vendor/predis/predis/src/Connection/AbstractConnection.php:120 Predis\Connection\AbstractConnection::readResponse vendor/predis/predis/src/Connection/AbstractConnection.php:112 Predis\Connection\AbstractConnection::executeCommand vendor/predis/predis/src/Connection/StreamConnection.php:260 Predis\Connection\StreamConnection::connect vendor/predis/predis/src/Connection/AbstractConnection.php:180 Predis\Connection\AbstractConnection::getResource vendor/predis/predis/src/Connection/StreamConnection.php:288 Predis\Connection\StreamConnection::write vendor/predis/predis/src/Connection/StreamConnection.php:394 Predis\Connection\StreamConnection::writeRequest vendor/predis/predis/src/Connection/AbstractConnection.php:110 Predis\Connection\AbstractConnection::executeCommand vendor/predis/predis/src/Client.php:331 Predis\Client::executeCommand vendor/predis/predis/src/Client.php:314 Predis\Client::__call vendor/laravel/framework/src/Illuminate/Redis/Connections/Connection.php:116 Illuminate\Redis\Connections\Connection::command vendor/laravel/framework/src/Illuminate/Redis/Connections/Connection.php:220 Illuminate\Redis\Connections\Connection::__call vendor/laravel/framework/src/Illuminate/Queue/RedisQueue.php:140 Illuminate\Queue\RedisQueue::pushRaw vendor/laravel/horizon/src/RedisQueue.php:69 Laravel\Horizon\RedisQueue::pushRaw vendor/laravel/horizon/src/RedisQueue.php:52 Laravel\Horizon\RedisQueue::Laravel\Horizon\{closure} vendor/laravel/framework/src/Illuminate/Queue/Queue.php:317 Illuminate\Queue\Queue::enqueueUsing vendor/laravel/horizon/src/RedisQueue.php:53 Laravel\Horizon\RedisQueue::push vendor/laravel/framework/src/Illuminate/Queue/Queue.php:57 Illuminate\Queue\Queue::pushOn vendor/laravel/framework/src/Illuminate/Broadcasting/BroadcastManager.php:133 Illuminate\Broadcasting\BroadcastManager::queue vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:320 Illuminate\Events\Dispatcher::broadcastEvent vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:243 Illuminate\Events\Dispatcher::dispatch vendor/laravel/framework/src/Illuminate/Foundation/helpers.php:450 event // 业务侧事件派发代码 event(OneOfOurEvents);
问题诱因
该问题是Predis v1.1.10版本的兼容性bug,和Redis服务端开启RESP3协议支持直接相关:
- composer更新后升级到Predis v1.1.10,这个版本建立连接时会默认发送
HELLO 3命令协商使用RESP3协议 - Predis v1.1.x系列本身没有完整实现RESP3协议的解析逻辑,当服务端返回RESP3格式响应时,旧版RESP2解析器无法识别新格式的响应前缀,就会抛出协议解析错误
- 日志里出现的乱序前缀(
"、0、e、R这类),本质是解析器把RESP3格式的响应内容按字节逐个当成RESP2前缀识别导致的,不是Redis服务本身返回乱码。
修复方案
任选一种即可解决问题:
- 降级Predis版本到v1.1.9,该版本不会自动发送
HELLO命令协商RESP3协议 - 升级Predis到v2.x版本,该版本完整支持RESP3协议解析
- 若使用云厂商托管Redis服务,可在Laravel的
database.phpRedis配置项中添加参数,强制使用RESP2协议:'parameters' => [ 'protocol' => '2', ],
内容的提问来源于stack exchange,提问作者Carlton
相关产品推荐
相关产品推荐

