|
Навигация
|
Главная » Новости Пишем обработчик ошибок для phpredisИсточник: habrahabr habrahabr Пишем обработчик ошибок для phpredis Началось все с того, что у нас в компании решили сделать прокси/балансировщик нагрузки который бы, в зависимости от ключа, отправлял запрос на тот или иной инстанс Redis'а. Так как идеально сразу ничего не работает, то написанный на php проект, работающий с редисом(с помощью phpredis) через этот самый балансировщик, с завидной регулярности вылетал с критическими ошибками. Увы прокси не всегда правильно собирал сложные ответы сервера… Работа с Redis'ом в коде через каждых 10 строк, и оборачивать каждый вызов в try, catch не было ни малейшего желания, но и с постоянными вылетами дебажить было сильно не удобно. Тут мне и пришла в голову идея подменить объект Redis'a своим, изнутри которого я бы уже вызывал все методы настоящего объекта… Естественно дублировать все методы исходного класса сильно накладно, да и не зачем, ибо существует замечательный метод __call, к которому идет обращение, при вызове несуществующего метода объекта. На вход мы получаем имя запрашиваемого метода и массив аргументов, после чего успешно вызываем с помощью call_user_func_array, нужный метод исходного объекта. Таким образом оборачивать в try, catch нам надо лишь один вызов call_user_func_array. Итого метод __call выглядит следующим образом:
Если вылазит ошибка, мы отправляем ее на обработчик, а сами пробуем еще раз вызвать тот же метод. После 5ти неудачных вызовов перестаем мучить проксю и идем курить логи… Первый вариант класса выглядел так:
Он реконнектился при каждом вылете и "умирал" при вылете с ошибкой "protocol error", ибо именно на такие ошибки мы и охотились. Для его интеграции надо было всего то заменить на
Этот вариант прекрасно работал до поры до времени, пока один раз скрипт не вылетел при работе с multi. Так как для транзакций в phpredis выделен отдельный объект, то стало понятно что надо писать обертку еще и для него. В первую очередь был добавлен метод multi в приведенный выше класс:
Ну и написан класс для обработки ошибок в объекте транзакций, по аналогии к предыдущему: Дабы иметь возможность повторной отправки всех команд транзакции при вылете, все вызовы, кроме exec(), которая непосредственно завершает транзакцию, заносились в массив и отправлялись на сервер при вызове последней. Discard у нас в коде не используется потому в классе его отдельно не выносил. Учитывая, что иногда, хоть и крайне редко, коннект с редисом зависает даже без использования прокси, то данные обертки успешно используются и по сей день.Что такое верстка сайта. Является ли копирайтинг достойным источником дохода. ESET запускает интернет-сообщество ESET CLUB. Главная » Новости |
© 2024 Team.Furia.Ru.
Частичное копирование материалов разрешено. |