Балансировка с помощью Nginx Upstream

Несколько трюков по распределению нагрузки между бекенд-серверами, используя nginx upstream.

У меня есть два бекенд-сервера и фронтенд сервер, где крутится Nginx. Для распеределения запросов между бекендами раньше мы использовали uwsgi fastrouter, но он делит весь трафик в равных пропорциях, что не всегда удобно.

Сейчас я сделал другую схему.

Для распределения запросов между бекенд-серверами, я использую nginx upstream. Вот как это работает в самом базовом виде:

upstream backend {
    server 10.0.0.3:5010;
    server 10.0.0.4:5010;
}

...

location / {
    include uwsgi_params;
    uwsgi_pass backend;
    add_header X-Upstream $upstream_addr;
}

У меня есть два сервера - 10.0.0.3 и 10.0.0.4. При таком конфиге запросы будут распределяться между ними поровну.

Чем хорош Nginx, так это тем, что он автоматически перестает отправлять запросы на один из серверов, если тот перестает принимать запросы. Это полезно, например, при деплое, когда один из серверов перезагружается после установки нового кода.

Трюки

Допустим, на 10.0.0.4 я выложил новую версию кода с экспериментальной фичей.

Очень легко можно дать туда 10% трафика и посмотреть по логам, все ли хорошо, перед тем, как давать использовать код всем пользователям:

upstream backend {
    server 10.0.0.3 weight=9;
    server 10.0.0.4 weight=1;
}

9 запросов пойдут на стрый код, 1 на новый.

Еще одна фишка, которую я реально использую - backup.

upstream backend {
    server 10.0.0.3 backup;
    server 10.0.0.4;
}

При такой настройке все 100% запросов идут по-умолчанию на 10.0.0.4. Там выложен самый новый код. Если я туда задеплою что-то, что все сломает, то запросы автоматически пойдут на 10.0.0.3, где лежит стабильная версия кода, чуть более старая.

Так у меня получается экспериментальный сервер, на котором можно играться с настройками, перезагружать его, деплоить что-то и чувствовать себя в безопасности.

Рекомендую.