Неизвестная ошибка команды Redis

Я использую Redis в качестве хранилища сеансов на своем веб-сайте (Laravel 4.2). Иногда я получаю следующие ошибки. Я предполагаю, что символ ">" сломал команды 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;
    }

person Farid Movsumov    schedule 24.04.2016    source источник
comment
Неправильная интерполяция строк?   -  person angelcool.net    schedule 24.04.2016
comment
@Ферид Мовсумов, проблема решена?   -  person Nick    schedule 27.04.2016
comment
@mnv, к сожалению, проблема все еще существует.   -  person Farid Movsumov    schedule 27.04.2016
comment
У меня была такая же проблема сегодня. Возможно, это и ваш случай: github.com/nrk/predis/issues/328   -  person Nick    schedule 27.04.2016
comment
@mnv спасибо за информацию, но это другая проблема   -  person Farid Movsumov    schedule 28.04.2016
comment
Можете ли вы показать свой точный код, где используется Redis?   -  person DhruvPathak    schedule 11.05.2016
comment
@DhruvPathak Я добавил пример кода. Надеюсь, это поможет.   -  person Farid Movsumov    schedule 11.05.2016
comment
@FeridMovsumov Просто дикая догадка, но вы пытались ->render() просмотреть, прежде чем передать его в Redis? Просто вместо $view попробуйте поставить $view->render()   -  person Giedrius Kiršys    schedule 11.05.2016
comment
@GiedriusKiršys работает так же, как рендеринг. Потому что toString вызывает render. Он хранит отрендеренный html   -  person Farid Movsumov    schedule 11.05.2016
comment
@FeridMovsumov Понятно. Может быть, обходным путем было бы преобразовать специальные символы в объекты html, а затем, при их извлечении, выполнить обратный процесс? Я говорю о htmlspecialchars и htmlspecialchars_decode   -  person Giedrius Kiršys    schedule 11.05.2016
comment
Я думаю, вы должны serialize($view) или закодировать его каким-либо другим способом и десериализовать/декодировать его при извлечении.   -  person Leentje    schedule 13.05.2016
comment
@GiedriusKiršys Я попробую это решение.   -  person Farid Movsumov    schedule 13.05.2016
comment
@GiedriusKiršys ваше решение решает мою проблему. Пожалуйста, напишите это как ответ, и я приму его   -  person Farid Movsumov    schedule 15.05.2016
comment
@FeridMovsumov Хорошо, готово. Спасибо, рад помочь.   -  person Giedrius Kiršys    schedule 15.05.2016


Ответы (2)


Итак, в общем, что я могу сказать из вашего журнала ошибок: Redis не любит специальные символы, такие как < и >, поэтому вам нужно их кодировать.

Используйте htmlspecialchars для кодирования и htmlspecialchars_decode для декодирования данных при извлечении.

person Giedrius Kiršys    schedule 15.05.2016

что-то не так с вашим клиентом Redis. Вы не можете воспроизвести это, потому что ошибка возникает не в вашем коде, а в TCP-соединении между клиентом и сервером Redis.

Я бы предложил обновить вопрос и указать, какой клиентский модуль Redis вы используете. Это предис?

Если вы используете Unix, попробуйте скомпилировать и установить phpredis. это php-модуль, и у меня никогда не было с ним проблем.


Воспроизведение через телнет

Сделайте telnet host port и следуйте инструкциям:

Обычный запрос GET a будет выглядеть так:

*2
$3
get
$1
a
$-1

Теперь подумайте об этом - попросите gem a:

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

Протокол действителен, но гем команды недействителен.

Теперь подумайте об этом:

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

Вот ваша ошибка. Действительный протокол, недопустимая команда.

В качестве альтернативы рассмотрите это:

*2
$3
get
$1
<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.

person Nick    schedule 10.05.2016
comment
спасибо за -1. Еще раз - что-то не так с библиотекой Redis. Я отредактирую, как вы можете воспроизвести ошибку с помощью telnet. - person Nick; 11.05.2016
comment
Спасибо за ваш ответ @Nick, но как я могу решить эту проблему? - person Farid Movsumov; 11.05.2016
comment
Я буду искать эту ошибку внутри клиента predis. Я сообщу вам результат. - person Farid Movsumov; 11.05.2016
comment
установите phpredis хотя бы для проверки, ссылка github.com/phpredis/phpredis - это поддерживается на 100% в Laravel, потому что это де-факто стандарт для подключения к Redis. - person Nick; 11.05.2016