Redis "unknown command" 错误
Redis "unknown command" error
我在我的网站中使用 Redis 作为会话存储 (Laravel 4.2)。有时我会收到以下错误。我猜 ">" char 破坏了 setex 命令。
production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command '>'' in
production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command 'tml>''
production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command '</div>''
这些错误在生产服务器上很少发生,我无法重现它们。您知道为什么会出现这些错误吗?我该如何防止这些错误?
key: laravel:xxxxxxxxxxxxxxx
value: s:217:"a:4:{s:6:"_token";s:40:"xxxxxxxxxxx";s:4:"lang";s:2:"fr";s:9:"_sf2_meta";a:3:{s:1:"u";i:1461777248;s:1:"c";i:1461777248;s:1:"l";s:1:"0";}s:5:"flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}";
exception 'Predis\ServerException' with message 'ERR unknown command 'ml>'' in vendor/predis/predis/lib/Predis/Client.php:282
更新
我使用 redis 的代码示例。
public function view($username = null)
{
$username = mb_strtolower($username);
$redis = $this->getRedis();
try{
$view = $redis->get(User::getCacheKeyByUsername($username));
}catch (\Exception $exception){
$view = null;
}
if($view === null || Session::has("admin")){
$user = User::where('username', '=', $username)->where("status", 1)->first();
if (empty($user)) {
return Redirect::to(Session::get("lang") . '/all');
}
$view = View::make("view", array("user" => $user));
if(!Session::has("admin")){
try{
$redis->setex(User::getCacheKeyByUsername($username), 3600, $view);
}catch (\Exception $exception){
Log::error($exception->getMessage());
}
}
}
return $view;
}
你的redis客户端出了点问题。您无法重现它,因为错误不会发生在您的代码中,而是发生在客户端和 redis 服务器之间的 TCP 通信中。
我建议更新问题并提及您使用的是什么 Redis 客户端模块。是预兆吗?
如果您使用的是 unix,请尝试编译并安装 phpredis。它是 php 模块,我从来没有遇到过任何问题。
用 telnet 复制
执行 telnet host port
并按照说明操作:
正常请求 GET a
看起来像这样:
*2
get
a
$-1
现在考虑这个 - 要求 gem a
:
*2
gem
a
-ERR unknown command 'gem'
协议有效,但命令“gem”无效。
现在考虑一下:
*1
ml>
-ERR unknown command 'ml>'
这是你的错误。协议有效,命令无效。
或者考虑这个:
*2
get
<html>
$-1
-ERR unknown command 'ml>'
又是你的错误。无效 strlen("<html>");
为什么这是 redis 客户端错误而不是用户错误:
许多redis客户端使用PHP
magic methods
.
这意味着如果您调用 $redis->bla()
,他们会提取“bla”部分及其参数并将它们转发到 redis
服务器。
然而你做不到$redis->ml>()
。这将是语法错误。所以这是来自 redis 客户端的错误,而不是来自您的代码。
它看起来也像 HTML
的一部分。看起来你正在将 HTML
数据存储在 redis 中。我只能猜测客户端不会计算 strlen()
或 count()
并“通过 telnet 线路”发送错误信息。
好的,基本上我能从你的错误日志中说些什么:redis 不喜欢像 <
和 >
这样的特殊字符,所以你必须对它们进行编码。
检索时使用htmlspecialchars
编码,htmlspecialchars_decode
解码数据。
我在我的网站中使用 Redis 作为会话存储 (Laravel 4.2)。有时我会收到以下错误。我猜 ">" char 破坏了 setex 命令。
production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command '>'' in
production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command 'tml>''
production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command '</div>''
这些错误在生产服务器上很少发生,我无法重现它们。您知道为什么会出现这些错误吗?我该如何防止这些错误?
key: laravel:xxxxxxxxxxxxxxx
value: s:217:"a:4:{s:6:"_token";s:40:"xxxxxxxxxxx";s:4:"lang";s:2:"fr";s:9:"_sf2_meta";a:3:{s:1:"u";i:1461777248;s:1:"c";i:1461777248;s:1:"l";s:1:"0";}s:5:"flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}";
exception 'Predis\ServerException' with message 'ERR unknown command 'ml>'' in vendor/predis/predis/lib/Predis/Client.php:282
更新
我使用 redis 的代码示例。
public function view($username = null)
{
$username = mb_strtolower($username);
$redis = $this->getRedis();
try{
$view = $redis->get(User::getCacheKeyByUsername($username));
}catch (\Exception $exception){
$view = null;
}
if($view === null || Session::has("admin")){
$user = User::where('username', '=', $username)->where("status", 1)->first();
if (empty($user)) {
return Redirect::to(Session::get("lang") . '/all');
}
$view = View::make("view", array("user" => $user));
if(!Session::has("admin")){
try{
$redis->setex(User::getCacheKeyByUsername($username), 3600, $view);
}catch (\Exception $exception){
Log::error($exception->getMessage());
}
}
}
return $view;
}
你的redis客户端出了点问题。您无法重现它,因为错误不会发生在您的代码中,而是发生在客户端和 redis 服务器之间的 TCP 通信中。
我建议更新问题并提及您使用的是什么 Redis 客户端模块。是预兆吗?
如果您使用的是 unix,请尝试编译并安装 phpredis。它是 php 模块,我从来没有遇到过任何问题。
用 telnet 复制
执行 telnet host port
并按照说明操作:
正常请求 GET a
看起来像这样:
*2
get
a
$-1
现在考虑这个 - 要求 gem a
:
*2
gem
a
-ERR unknown command 'gem'
协议有效,但命令“gem”无效。
现在考虑一下:
*1
ml>
-ERR unknown command 'ml>'
这是你的错误。协议有效,命令无效。
或者考虑这个:
*2
get
<html>
$-1
-ERR unknown command 'ml>'
又是你的错误。无效 strlen("<html>");
为什么这是 redis 客户端错误而不是用户错误:
许多redis客户端使用PHP
magic methods
.
这意味着如果您调用 $redis->bla()
,他们会提取“bla”部分及其参数并将它们转发到 redis
服务器。
然而你做不到$redis->ml>()
。这将是语法错误。所以这是来自 redis 客户端的错误,而不是来自您的代码。
它看起来也像 HTML
的一部分。看起来你正在将 HTML
数据存储在 redis 中。我只能猜测客户端不会计算 strlen()
或 count()
并“通过 telnet 线路”发送错误信息。
好的,基本上我能从你的错误日志中说些什么:redis 不喜欢像 <
和 >
这样的特殊字符,所以你必须对它们进行编码。
检索时使用htmlspecialchars
编码,htmlspecialchars_decode
解码数据。