【问题标题】:Redis "unknown command" errorRedis“未知命令”错误
【发布时间】:2016-08-18 01:51:52
【问题描述】:

我在我的网站 (Laravel 4.2) 中使用 Redis 作为会话存储。有时我会遇到以下错误。我猜 ">" 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;
    }

【问题讨论】:

  • 错误的字符串插值?
  • @Ferid Movsumov,这个问题解决了吗?
  • @mnv 不幸的是问题仍然存在。
  • 我今天遇到了同样的问题。也许你的情况也是如此:github.com/nrk/predis/issues/328
  • @FeridMovsumov 明白了。也许解决方法是将特殊字符转换为 html 实体,然后在检索它时进行反向处理?我说的是htmlspecialcharshtmlspecialchars_decode

标签: php laravel laravel-4 redis predis


【解决方案1】:

好的,基本上我可以从你的错误日志中说什么:redis 不喜欢像&lt;&gt; 这样的特殊字符,所以你必须对它们进行编码。

在检索时使用htmlspecialchars 编码和htmlspecialchars_decode 解码数据。

【讨论】:

    【解决方案2】:

    您的 redis 客户端有问题。不能复现,因为错误不是发生在你的代码中,而是在客户端和redis服务器之间的TCP通信中。

    我建议更新问题并提及您使用的是什么 redis 客户端模块。是predis吗?

    如果您使用的是 unix,请尝试编译和安装 phpredis。它是 php 模块,我从来没有遇到过任何问题。


    使用 telnet 进行复制

    telnet host port 并按照说明操作:

    普通请求GET a 如下所示:

    *2
    $3
    get
    $1
    a
    $-1
    

    现在考虑一下 - 询问gem a

    *2
    $3
    gem
    $1
    a
    -ERR unknown command 'gem'
    

    协议有效,但命令“gem”无效。

    现在考虑一下:

    *1
    $3
    ml>
    -ERR unknown command 'ml>'
    

    这是您的错误。有效的协议,无效的命令。

    或者考虑这个:

    *2
    $3
    get
    $1
    <html>
    $-1
    -ERR unknown command 'ml>'
    

    这又是你的错误。无效strlen("&lt;html&gt;");

    为什么这是redis客户端错误而不是用户错误:

    很多redis客户端使用PHPmagic methods

    这意味着如果您调用$redis-&gt;bla(),它们会提取“bla”部分及其参数并将它们转发到redis 服务器。

    但是你不能做$redis-&gt;ml&gt;()。这将是语法错误。所以这是来自 redis 客户端的错误,而不是来自您的代码。

    它看起来也像是HTML 的一部分。看起来您将 HTML 数据存储在 redis 中。我只能猜测客户端没有计算 strlen()count() 并“通过 telnet 线路”发送错误信息。

    【讨论】:

    • 感谢 -1。再一次 - redis 库出了点问题。我将编辑如何使用 telnet 重现错误。
    • 感谢@Nick 的回答,但我该如何解决这个问题?
    • 我将在 predis 客户端中搜索此错误。我会让你知道结果。
    • 安装 phpredis 至少检查一下,链接是 github.com/phpredis/phpredis - 这是 Laravel 100% 支持的,因为它是 redis 连接的事实标准。
    猜你喜欢
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 2019-01-07
    • 2020-03-25
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多