Показаны сообщения с ярлыком nginx. Показать все сообщения
Показаны сообщения с ярлыком nginx. Показать все сообщения

понедельник, 8 июля 2013 г.

Балансировка HTTP запросов NGINX'ом

    Про то как балансировать нагрузку nginx'ом написано множество статей - поэтому я не буду повторяться и рассказывать про директивы upstream и proxy_pass. Расскажу о таком тонком нюансе поведения, который порой ускользает от внимания  даже опытных сисадминов, а именно  об эффекте дублирования запросов.  
     Дело в том что мало кто задумывается - а что происходит с HTTP запросом, если он, по какой-либо причине не обрабатывается бэкэндом ?  Дожен ли он передаваться следующему бэкэену описанному в директиве upstream или же нужно просто возвращать 5xx ошибку ?  По умолчанию nginx пытается отправить этот запрос следующему бэкэнду и если он его обрабатывает - то пользователь вообще никогда не узнает что при обработке его запроса возникли какие-либо трудности. Казалось бы - вот она - отказоустойчивая система, мечта всех программистов...  
       Но не тут то было.... Описанное выше поведение идеально при отдаче контента,  когда нам нужно во что бы то ни стало показать пльзователю запрошенную страницу.  Но представьте что это POST запрос, который выполняет какое-либо важное, с точи зрения приложения, действие. Например оформление заказа в интернет магазине.  Представим себе ситуацию когда обработка подобного запроса завершается по таймауту или просто ошибкой. Nginx как честный балансировщик направляет этот запрос к следующему бэкэнду. Но что это означает с точки зрения приложения ? С точки зрения приложения запрос просто сдуплировался, был оди запрос - а стало два. Если при  обработке этого POST запроса не используются данные из сессии - то можно сказать что мы  легко отделались - ситуация более менее предсказуемая. 
      В слуае отсутствия уникального ключа данные дублируются - я думаю практически все когда-нибуть сталкивались с этим. К примеру не вовремя оставленный комментарий может задвоится. Этим грешат даже очень хорошо тестируемые системы типа вконтакта. 
      Если этим POST запросом оказался к примеру запрос на регистрацию пользователя, при котором как минимум одно поле должно быть уникальным - будь то email или логин - то один из запросов закончится успешно, второй завершится ошибкой - с сообщением вида "email/login должен быть уникальным". При этом пользователь на самом деле был создан. Естественно что такое поведение системы не вызовет восторга у клиентов.
      Если же при обработке POST запроса(как в первом примере с отправкой заказа) используется некоторое состояние приложения, хранящееся в сессии(список товаров в корзине пользователя) - то мы в полной жопе. Что в этом случае может случится - зависит от очень многих факторов - и это в свою очередь,  порождает очень широкий спектр глюков. Начиная от полной потери заказа до дублирования заказа. Разработчики в таких ситуациях как правило винят интернет эксплорер... якобы кнопка не всегда блокируется и пользователи умудряются отправить заказ два раза... QA разводят руками - воспроизвети это не возможно. В общем боротся с этими глюками можно очень долго... и про то что в этом может быть виновен  nginx - мы задумываемся в последнюю очередь.
           Что это исправить, нужно отключить передачу POST запросов следующему backend серверу с помощью директивы proxy_next_upstream 
       

воскресенье, 13 мая 2012 г.

Балансировка HTTP запросов

Сегодня восполнил свой пробел в области балансировки HTTP траффика. Оказывается что кроме round robin DNS, Nginx и HAProxy еще существует такая замечательная вещь как LVS. Для себя решил что нужно будет обязательно попробовать LVS как только переедем на собственные сервера.
Настройка LVS на русском языке - очень полезная статья про установку LVS на хабре
Practical Load Balancing by Peter Membrey, Eelco Plugge, and Dawid House   - книжка про балансировку нагрузки написанная на очень простом языке. Довольно многословная книжка, даже для специалиста среднего уровня - пол книжки можно пропустить. Не понимаю зачем  требовалось объяснять основы TCP/IP и HTTP в книге, посвященной балансировки нагрузки. Мне всегда казалось что люди занимающиеся балансировкой нагрузки - четко представляют себе как работают данные протоколы.  Но если пропустить весь словесный понос - то можно дочитать до подробного описания установки LVS и кое-какую информацию по оптимизации Nginx.

Пока гуглил на тему влияния worker_cpu_affinity на производительность Nginx наткнулся на http://tengine.taobao.org/ - китайский форк Nginx в котором привязка воркеров к процессорам делается автоматически.