Балансировка нагрузки nginx

Thank you for reading this post, don't forget to subscribe!

NGINX пред­ла­га­ет два раз­лич­ных спо­со­ба про­вер­ки жиз­не­спо­соб­но­сти: пас­сив­ной, доступ­ной в вер­сии с откры­тым исход­ным кодом, и актив­ной, доступ­ной толь­ко в NGINX Plus. Актив­ные про­вер­ки жиз­не­спо­соб­но­сти через регу­ляр­ные про­ме­жут­ки вре­ме­ни будут выпол­нять под­клю­че­ние или запрос к име­ю­ще­му­ся сер­ве­ру вос­хо­дя­ще­го пото­ка и могут полу­чать под­твер­жде­ние того что такой запрос вер­ный. Пас­сив­ные про­вер­ки жиз­не­спо­соб­но­сти выпол­ня­ют мони­то­ринг име­ю­ще­го­ся под­клю­че­ния к вос­хо­дя­ще­му сер­ве­ру или откли­ка от него толь­ко по мере того как кли­ен­ты выпол­ня­ют такие запро­сы или под­клю­че­ния. Вы може­те поже­лать исполь­зо­вать пас­сив­ные про­вер­ки жиз­не­спо­соб­но­сти для сни­же­ния нагруз­ки на свои сер­ве­ры вос­хо­дя­ще­го пото­ка, но вы так­же може­те поже­лать при­ме­нять актив­ные про­вер­ки жиз­не­спо­соб­но­сти для выяв­ле­ния отка­за неко­го сер­ве­ра вос­хо­дя­ще­го пото­ка преж­де чем полу­чит отказ обслу­жи­ва­е­мый им клиент.

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

Зада­ча

Вам тре­бу­ет­ся рас­пре­де­лить нагруз­ку меж­ду дву­мя или более сер­ве­ра­ми HTTP.

Реше­ние

Для выпол­не­ния балан­си­ров­ки по сер­ве­рам HTTP вос­поль­зуй­тесь моду­лем HTTP NGINX при­ме­нив блок upstream:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Дан­ная настрой­ка выпол­ня­ет балан­си­ров­ку нагруз­ки по двум сер­ве­рам HTTP с пор­том 80. Зна­че­ние пара­мет­ра weight инструк­ти­ру­ет NGIN о необ­хо­ди­мо­сти пере­да­вать в два раза боль­ше под­клю­че­ний на вто­рой сер­вер, при­чём зна­че­ни­ем по умол­ча­нию для weight явля­ет­ся 1.

Модуль HTTP upstream кон­тро­ли­ру­ет пара­мет­ры балан­си­ров­ки для HTTP. Этот модуль опре­де­ля­ет некий пул полу­ча­те­лей - любые соче­та­ния соке­тов Unix, IP адре­сов и запи­сей DNS или их сме­ше­ния. Этот модуль upstream так­же опре­де­ля­ет как назна­чать любые инди­ви­ду­аль­ные запро­сы всем сер­ве­рам вос­хо­дя­ще­го потока.

Каж­дый полу­ча­тель в вос­хо­дя­щем пото­ке опре­де­ля­ет­ся в пуле вос­хо­дя­ще­го пото­ка соот­вет­ству­ю­щей дирек­ти­вой server. Эта дирек­ти­ва server предо­став­ля­ет некий сокет Unix, IP адрес или какой- то FQDN, сов­мест­но с неким чис­лом необя­за­тель­ных пара­мет­ров. Дан­ные необя­за­тель­ные пара­мет­ры дают допол­ни­тель­ное управ­ле­ние име­ю­щи­ми­ся марш­ру­та­ми или запро­са­ми. Эти пара­мет­ры содер­жат зна­че­ние веса соот­вет­ству­ю­ще­го сер­ве­ра в сво­ём алго­рит­ме балан­си­ров­ки; будет ли пре­бы­вать дан­ные сер­вер в режи­ме ожи­да­ния (standby), доступ­ным или не доступ­ным; а так­же как опре­де­лять что сер­вер недо­сту­пен. NGINX Plus опре­де­ля­ет целый ряд про­чих удоб­ных пара­мет­ров, таких как огра­ни­че­ние на под­клю­че­ние к дан­но­му сер­ве­ру, рас­ши­рен­ный кон­троль раз­ре­ше­ния DNS, а так­же воз­мож­ность мед­лен­но­го нара­щи­ва­ния чис­ла под­клю­че­ний к неко­му сер­ве­ру после его запуска.

Балансировка нагрузки TCP

Зада­ча

Вам тре­бу­ет­ся выпол­нить балан­си­ров­ку нагруз­ки меж­ду дву­мя или более сер­ве­ра­ми TCP.

Реше­ние

Для балан­си­ров­ки нагруз­ки по сер­ве­рам TCP вос­поль­зуй­тесь моду­лем steam NGINX при­ме­нив блок upstream:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Соот­вет­ству­ю­щий блок server в дан­ном при­ме­ре инструк­ти­ру­ет NGINX выпол­нять ожи­да­ние по пор­ту TCP 3306 и выпол­нять балан­си­ров­ку нагруз­ки меж­ду дву­мя репли­ка­ми на чте­ние базы дан­ных MySQL и при­во­дит в спис­ке дру­гой в каче­стве резерв­ной копии, в кото­рый будет пере­да­вать­ся обмен если ука­зан­ные пер­вич­ные будут оста­нов­ле­ны. Эти настрой­ки не будут добав­лять­ся в пап­ку conf.d, посколь­ку эта пап­ка вло­же­на в http block; вме­сто это­го вам сле­ду­ет создать иную пап­ку с назва­ни­ем stream.conf.d, открыть блок stream в соот­вет­ству­ю­щем фай­ле nginx.conf и вло­жить эту новую пап­ку для настрой­ки stream.

Балан­си­ров­ка нагруз­ки TCP опре­де­ля­ет­ся соот­вет­ству­ю­щим моду­лем NGINX stream. Этот модуль stream, как и обсуж­дав­ший­ся модуль HTTP, поз­во­ля­ет вам опре­де­лять пулы сер­ве­ров вос­хо­дя­ще­го пото­ка и настра­и­вать некий ожи­да­ю­щий сер­вер. При настрой­ке неко­го сер­ве­ра на ожи­да­ние (listen) опре­де­лён­но­го пор­та, вы долж­ны опре­де­лить то зна­че­ние пор­та, по кото­ро­му выпол­ня­ет­ся ожи­да­ние, или, что не обя­за­тель­но, некий адрес и порт. Здесь может быть опре­де­лён полу­ча­тель, при­чём либо это будет обрат­ный посред­ник (прок­си) на дру­гой адрес, либо некий вос­хо­дя­щий пул ресурсов.

Такой вос­хо­дя­щий поток для балан­си­ров­ки нагруз­ки TCP во мно­гом ана­ло­ги­чен вос­хо­дя­ще­му пото­ку для HTTP, в том что он опре­де­ля­ет вос­хо­дя­щие ресур­сы как сер­ве­ры, настра­и­ва­е­мые соке­та­ми Unix, IP , либо пол­но­стью опре­де­лён­ным име­нем доме­на (FQDN, fully qualified domain name), а так­же веса сер­ве­ра, мак­си­маль­но­го чис­ла под­клю­че­ний, реша­те­лей DNS, и пери­о­дов выво­да в рабо­чий режим; а так­же того, акти­вен ли сер­вер, отклю­чён ли, либо пре­бы­ва­ет в режи­ме резерв­ной копии.

NGINX Plus пред­ла­га­ет для балан­си­ров­ки нагруз­ки TCP даже допол­ни­тель­ные свой­ства. Такие пред­ла­га­е­мые NGINX Plus рас­ши­рен­ные свой­ства могут быть пред­став­ле­ны на про­тя­же­нии дан­ной кни­ги. Про­вер­ки жиз­не­спо­соб­но­сти для всех балан­си­ро­вок нагруз­ки будут обсуж­де­ны в этой гла­ве позднее.

Балансировка нагрузки UDP

Зада­ча

Вам тре­бу­ет­ся рас­пре­де­лить балан­си­ров­ку нагруз­ки меж­ду дву­мя или более сер­ве­ра­ми UDP.

Реше­ние

Для балан­си­ров­ки нагруз­ки по сер­ве­рам UDP вос­поль­зуй­тесь моду­лем steam NGINX при­ме­нив блок upstream, опре­де­ля­е­мый как udp:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Этот раз­дел настра­и­ва­ет балан­си­ров­ку нагруз­ки меж­ду дву­мя сер­ве­ра­ми NTP (Network Time Protocol) вос­хо­дя­ще­го пото­ка, кото­рые при­ме­ня­ют про­то­кол UDP. Опре­де­ле­ние балан­си­ров­ки нагруз­ки UDP явля­ет­ся при­ме­ром исполь­зо­ва­ния пара­мет­ра udp в соот­вет­ству­ю­щей дирек­ти­ве listen.

Если соот­вет­ству­ю­щая служ­ба поверх вашей балан­си­ров­ки нагруз­ки тре­бу­ет обрат­ной отправ­ки мно­же­ства паке­тов и далее меж­ду кли­ен­том и сер­ве­ром, вы може­те опре­де­лить соот­вет­ству­ю­щий пара­метр reuseport. При­ме­ра­ми тако­го типа служб явля­ют­ся OpenVPN, Voice over Internet Protocol (VoIP), реше­ния вир­ту­аль­ных рабо­чих мест и DTLS (Datagram Transport Layer Security). Ниже при­во­дит­ся при­мер исполь­зо­ва­ния NGINX для обра­бот­ки соеди­не­ний Open VPN и их посред­ни­че­ства (прок­си) для запу­щен­ной локаль­но служ­бы Open VPN:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Вы може­те спро­сить, "Зачем мне при­ме­нять некую балан­си­ров­ку нагруз­ки, когда я могу иметь в запи­си DNS A или SRV мно­же­ства хостов?" Ответ состо­ит в том, что это не про­сто аль­тер­на­тив­ные алго­рит­мы балан­си­ров­ки, кото­ры­ми мы можем осу­ществ­лять балан­си­ров­ку, но мы так­же можем выпол­нять балан­си­ров­ку и поверх самих сер­ве­ров DNS. Служ­бы UDP состав­ля­ют мно­же­ство тех служб, от кото­рых мы зави­сим в сете­вых систе­мах, таких как DNS, NTP и VoIP. Балан­си­ров­ка нагруз­ки UDP может быть не рас­про­стра­не­на для неко­то­рых из них, но про­сто полез­на в общем мире масштабирования.

В точ­но­сти так же как это име­ет место и для TCP, вы може­те обна­ру­жить балан­си­ров­ку нагруз­ки UDP в моду­ле stream, при­чём в целом она настра­и­ва­ет­ся так же. Основ­ное отли­чие состо­ит в том, что соот­вет­ству­ю­щая дирек­ти­ва listen опре­де­ля­ет что её сокет открыт для рабо­ты с дей­та­грам­ма­ми. При рабо­те с дей­та­грам­ма­ми име­ют­ся некие иные дирек­ти­вы, кото­рые могут при­ме­нять­ся когда они не укла­ды­ва­ют­ся в TCP, такие как дирек­ти­ва proxy_response, кото­рая зада­ёт для NGINX сколь­ко ожи­да­е­мых откли­ков может быть отправ­ле­но от её сер­ве­ра вос­хо­дя­ще­го пото­ка. По умол­ча­нию оно не огра­ни­че­но до тех пор пока не дости­га­ет­ся пре­дел proxy_timeout.

Уста­нав­ли­ва­е­мый пара­метр reuseport инструк­ти­ру­ет NGINX о необ­хо­ди­мо­сти созда­ния неко­го инди­ви­ду­аль­но­го пор­та ожи­да­ния для каж­до­го про­цес­са испол­ни­те­ля. Это дела­ет воз­мож­ным для име­ю­ще­го­ся ядра рас­пре­де­лять вхо­дя­щие под­клю­че­ния меж­ду про­цес­са­ми испол­ни­те­лей для обра­бот­ки мно­же­ства паке­тов, отправ­ля­е­мых меж­ду кли­ен­том и сер­ве­ром. Дан­ная функ­ци­о­наль­ность reuseport рабо­та­ет толь­ко в ядрах Linux 3.9 и выше, DragonFly BSD, а так­же FreeBSD 12 и выше.

Методы балансировки нагрузки

Зада­ча

Кару­сель­ный (round- robin) метод балан­си­ров­ки не соот­вет­ству­ет ваше­му вари­ан­ту при­ме­не­ния по той при­чине что у вас име­ют­ся неод­но­род­ные рабо­чие нагруз­ки или пулы серверов.

Реше­ние

Вос­поль­зуй­тесь одним из таких мето­дов балан­си­ров­ки нагруз­ки NGINX как мето­дов наи­мень­ших под­клю­че­ний (least connections), наи­мень­ше­го вре­ме­ни (least time), обще­го хэши­ро­ва­ния (generic hash), хэши­ро­ва­ния IP (IP hash), или слу­чай­но­го (random):

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Этот при­мер настра­и­ва­ет зна­че­ни­ем алго­рит­ма балан­си­ров­ки нагруз­ки для сво­е­го пула сер­ве­ров вос­хо­дя­ще­го пото­ка метод наи­мень­ших под­клю­че­ний (least connections). Все алго­рит­мы балан­си­ров­ки нагруз­ки, за исклю­че­ни­ем обще­го хэши­ро­ва­ния, слу­чай­но­го и наи­мень­ше­го вре­ме­ни рабо­ты явля­ют­ся обособ­лен­ны­ми дирек­ти­ва­ми, как и в дан­ном при­ме­ре. Зна­че­ния пара­мет­ров для этих дирек­тив пояс­ня­ют­ся в иду­щем далее обсуждении.

Не все обслу­жи­ва­ния запро­сов или паке­тов несут рав­ные веса. Исхо­дя из это­го, кару­сель­ный метод, или даже взве­шен­ный кару­сель­ный метод, при­ме­няв­ший­ся в преды­ду­щих при­ме­рах, не будут соот­вет­ство­вать всем при­ло­же­ния или пото­кам обме­на. Допол­ни­тель­но к воз­мож­но­сти выбо­ра таких алго­рит­мов или мето­дов балан­си­ров­ки нагруз­ки вы так­же може­те и настра­и­вать их. Для пулов вос­хо­дя­щих пото­ков HTTP, TCP и UDP доступ­ны сле­ду­ю­щие мето­ды балан­си­ров­ки нагрузки:

Кару­сель­ный
Это уста­нав­ли­ва­е­мый по умол­ча­нию метод балан­си­ров­ки нагруз­ки, кото­рый рас­пре­де­ля­ет запро­сы в поряд­ке сво­е­го спис­ка сер­ве­ров в соот­вет­ству­ю­щем вос­хо­дя­щем пуле. Для неко­го взве­шен­но­го кару­сель­но­го мето­да вы так­же може­те при­ни­мать во вни­ма­ние вес, кото­рый может при­ме­нять­ся когда раз­нят­ся ёмко­сти соот­вет­ству­ю­щих сер­ве­ров вос­хо­дя­ще­го пото­ка. Чем боль­ше цело­чис­лен­ное зна­че­ние для тако­го веса, тем более пред­по­чти­те­лен будет этот сер­вер в дан­ном кару­сель­ном мето­де. Соот­вет­ству­ю­щий алго­ритм, сто­я­щий за весом это про­сто ста­ти­сти­че­ская веро­ят­ность неко­го взве­шен­но­го среднего.
Наи­мень­шее подключение
Дан­ный метод балан­си­ру­ет нагруз­ку высту­пая посред­ни­ком для теку­ще­го запро­са к тому сер­ве­ру вос­хо­дя­ще­го пото­ка, кото­рый име­ет наи­мень­шее чис­ло откры­тых под­клю­че­ний. Метод наи­мень­ших под­клю­че­ний, так же как и кару­сель­ный, при­ни­ма­ет во вни­ма­ние веса при опре­де­ле­нии того в какой из сер­ве­ров отправ­лять дан­ное под­клю­че­ние. Эта дирек­ти­ва име­ет назва­ние least_conn.
Наи­мень­шее время
Доступ­ный толь­ко в NGINX PLUS, метод наи­мень­ше­го вре­ме­ни явля­ет­ся род­ствен­ным мето­ду наи­мень­ших под­клю­че­ний в том, что он высту­па­ет посред­ни­ком для того сер­ве­ра, у кото­ро­го наи­мень­шее чис­ло под­клю­че­ний, но при этом пред­по­чте­ние отда­ёт­ся сер­ве­ру с наи­мень­шим зна­че­ни­ем сред­не­го вре­ме­ни обра­бот­ки запро­сов. Дан­ный метод один из самых иску­шён­ных алго­рит­мов балан­си­ров­ки нагруз­ки и соот­вет­ству­ет потреб­но­стям веб при­ло­же­ний с высо­кой про­из­во­ди­тель­но­стью. Дан­ный алго­ритм допол­ни­тель­но оце­ни­ва­ет наи­мень­шее вре­мя соеди­не­ния, посколь­ку некое мень­шее чис­ло под­клю­че­ний не обя­за­тель­но озна­ча­ет самый быст­рый отклик. Для дан­ной дирек­ти­вы необ­хо­ди­мо опре­де­лять пара­метр header или last_byte. Когда опре­де­лён header, исполь­зу­ет­ся вре­мя на полу­че­ния откли­ка от заго­лов­ка. Когда опре­де­лён last_byte, при­ме­ня­ет­ся зна­че­ние вре­ме­ни для полу­че­ния пол­но­го откли­ка. Назва­ни­ем этой дирек­ти­вы явля­ет­ся least_time.
Общее хэши­ро­ва­ние
Сам адми­ни­стра­тор опре­де­ля­ет некий хэш для задан­но­го тек­ста, пере­мен­ных запро­са или вре­ме­ни испол­не­ния, либо и того и дру­го­го. NGINX рас­пре­де­ля­ет име­ю­щу­ю­ся нагруз­ку по всем сер­ве­рам предо­став­ляя некий хэш для зна­че­ния теку­ще­го запро­са и раз­ме­щая его в сер­ве­рах вос­хо­дя­ще­го пото­ка. Дан­ный метод очень поле­зен когда вам тре­бу­ет­ся боль­ше кон­тро­ля над тем куда отправ­ля­ют­ся запро­сы или для опре­де­ле­ния того какой из сер­ве­ров вос­хо­дя­ще­го пото­ка будет ско­рее все­го кэши­ро­вать эти дан­ные. Обра­ти­те вни­ма­ние, что при добав­ле­нии или уда­ле­нии сер­ве­ра из пула хэши­ро­ван­ные запро­сы будут пере­рас­пре­де­лять­ся. Этот алго­ритм име­ет некий необя­за­тель­ный пара­метр, consistent, для мини­ми­за­ции эффек­та пере­рас­пре­де­ле­ния. Эта дирек­ти­ва име­ет назва­ние hash.
Слу­чай­ное
Этот метод при­ме­ня­ет­ся что­бы пред­пи­сать NGINX для выбо­ра слу­чай­ным обра­зом сер­ве­ра из опре­де­лён­ной груп­пы, при­ни­мая во вни­ма­ние веса сер­ве­ров. Не обя­за­тель­ный пара­метр two [method] ука­зы­ва­ет NGINX на необ­хо­ди­мость слу­чай­ным обра­зом выби­рать два сер­ве­ра, а затем при­ме­нять предо­став­ля­е­мый им метод балан­си­ров­ки нагруз­ки для балан­си­ро­ва­ния меж­ду эти­ми дву­мя. Если two пере­да­ёт­ся без како­го бы то ни было мето­да, по умол­ча­нию при­ме­ня­ет­ся least_conn. Зна­че­ни­ем име­ни для слу­чай­ной балан­си­ров­ки нагруз­ки явля­ет­ся random.
Хэши­ро­ва­ние IP
Этот метод рабо­та­ет толь­ко для HTTP. Хэш IP при­ме­ня­ет зна­че­ние адре­са IP кли­ен­та в каче­стве само­го хеши­ро­ва­ния. Слег­ка отли­ча­ясь от при­ме­не­ния соот­вет­ству­ю­щей уда­лён­ной пере­мен­ной в неком общем хэши­ро­ва­нии, дан­ный алго­ритм исполь­зу­ет пер­вые три окте­та неко­го IPv4 адре­са либо весь адрес IPv6 цели­ком. Этот метод гаран­ти­ру­ет что кли­ен­ты выстав­ля­ют­ся посред­ни­ком на один и тот же сер­вер вос­хо­дя­ще­го пото­ка пока досту­пен этот самый сер­вер, что очень полез­но в том слу­чае, когда име­ет зна­че­ние состо­я­ние сеан­са и оно не обра­ба­ты­ва­ет­ся общей памя­тью дан­но­го при­ло­же­ния. Этот метод так­же учи­ты­ва­ет зна­че­ние пара­мет­ра weight при рас­пре­де­ле­нии зна­че­ния хэша. Име­нем дирек­ти­вы явля­ет­ся ip_hash.

Клейкие куки

Зада­ча

Вам тре­бу­ет­ся при­вя­зы­вать неко­го кли­ен­та ниже­сто­я­ще­го кли­ен­та с каким- то сер­ве­ром вос­хо­дя­ще­го уров­ня при помо­щи NGINX Plus.

Реше­ние

Вос­поль­зуй­тесь дирек­ти­вой sticky cookie (клей­ких куки) NGINX Plus для созда­ния и отсле­жи­ва­ния куки:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Дан­ная кон­фи­гу­ра­ция созда­ёт и отсле­жи­ва­ет некий куки, кото­рый свя­зы­ва­ет под­ле­жа­ще­го кли­ен­та с сер­ве­ром верх­не­го уров­ня. В дан­ном при­ме­ре этот куки, име­ну­е­мый как affinity, уста­нав­ли­ва­ет­ся для example.com, со сро­ком исте­че­ния дей­ствия в один час, при­чём не может потреб­лять­ся сто­ро­ной кли­ен­та, может отправ­лять­ся исклю­чи­тель­но через HTTPS и дей­ству­ет для всех путей.

При­ме­не­ние пара­мет­ра cookie в соот­вет­ству­ю­щей дирек­ти­ве sticky созда­ёт некий куки при самом пер­вом запро­се, кото­рый содер­жит инфор­ма­цию отно­си­тель­но тре­бу­е­мо­го сер­ве­ра верх­не­го уров­ня. NGINX Plus отсле­жи­ва­ет такой куки, что поз­во­ля­ет ему про­дол­жать отправ­лять после­ду­ю­щие запро­сы в тот же самый сер­вер. Самый пер­вый пози­ци­он­ный пара­метр в самом пара­мет­ре cookie явля­ет­ся необ­хо­ди­мым име­нем под­ле­жа­ще­го созда­нию и отсле­жи­ва­нию куки. Про­чие пара­мет­ры пред­ла­га­ют допол­ни­тель­ную инфор­ма­цию кон­тро­ля за про­смот­ром соот­вет­ству­ю­ще­го исполь­зо­ва­ния, напри­мер, вре­ме­ни исте­че­ния, доме­на, пути, и того может ли этот куки потреб­лять­ся сто­ро­ной кли­ен­та и может ли он пере­да­вать­ся по не без­опас­ным протоколам.

Обучения наклейкам NGINX Plus

Зада­ча

Вам тре­бу­ет­ся свя­зать неко­го под­ле­жа­ще­го кли­ен­та с каким- то вос­хо­дя­щим сер­ве­ром при помо­щи уже име­ю­ще­го­ся в NGINX Plus куки.

Реше­ние

Для обна­ру­же­ния и отсле­жи­ва­ния куки, кото­рый создан соот­вет­ству­ю­щим сер­ве­ром верх­не­го уров­ня вос­поль­зуй­тесь дирек­ти­вой sticky learn:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Дан­ный при­мер инструк­ти­ру­ет NGINX отыс­ки­вать и отсле­жи­вать сеан­сы, про­смат­ри­вая куки с име­нем COOKIENAME в заго­лов­ках откли­ка, и опре­де­лять суще­ству­ю­щие сеан­сы нахо­дя тот же самый куки в заго­лов­ках запро­сов. Такое род­ство (affinity) сеас­нов хра­нит­ся в раз­де­ля­е­мой зоне памя­ти в 2 МБ, что поз­во­ля­ет отсле­жи­вать при­бли­зи­тель­но 16 000 сеан­сов. Само назва­ние куки все­гда будет опре­де­лять­ся при­ло­же­ни­ем. Внут­ри соот­вет­ству­ю­ще­го при­ло­же­ния или настро­ек сер­ве­ра при­ло­же­ния обыч­но при­ме­ня­ют­ся назва­ния, подоб­ные jsessionid или phpsessionid.

Когда некое при­ло­же­ние созда­ёт свой соб­ствен­ный куки состо­я­ния сеан­са, NGINX Plus спо­со­бен отыс­ки­вать его в откли­ках запро­сов и отсле­жи­вать их. Такой тип отсле­жи­ва­ния куки осу­ществ­ля­ет­ся когда сама дирек­ти­ва sticky снаб­жа­ет­ся соот­вет­ству­ю­щим пара­мет­ром learn. Сов­мест­ная память для отсле­жи­ва­ния куки опре­де­ля­ет­ся зна­че­ни­ем пара­мет­ра zone с неким назва­ни­ем и раз­ме­ром. NGINX Plus направ­ля­ет поиск куки в соот­вет­ству­ю­щем откли­ке от сво­е­го сер­ве­ра верх­не­го уров­ня через опре­де­ле­ние над­ле­жа­ще­го пара­мет­ра create и отыс­ки­ва­ет пред­ва­ри­тель­но заре­ги­стри­ро­ван­ное род­ство сер­ве­ра при помо­щи зна­че­ния пара­мет­ра lookup. Сами зна­че­ния таких пара­мет­ров явля­ют­ся выстав­ля­е­мы­ми моду­лем HTTP переменными.

Наклейки маршрутов

Зада­ча

Вам необ­хо­дим более точ­ный кон­троль NGINX Plus над тем как выпол­ня­ет­ся марш­ру­ти­за­ция ваших посто­ян­ных сеан­сов к соот­вет­ству­ю­ще­му сер­ве­ру верх­не­го уровня.

Реше­ние

Для при­ме­не­ния пере­мен­ных отно­си­тель­но необ­хо­ди­мо­го запро­са на марш­рут вос­поль­зуй­тесь дирек­ти­вой sticky с соот­вет­ству­ю­щим пара­мет­ром route:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Этот при­мер выпол­ня­ет попыт­ку выде­ле­ния неко­го иден­ти­фи­ка­то­ра сеан­са Java, при­чём вна­ча­ле из неко­го куки, уста­нав­ли­вая соот­вет­ствие само­го иден­ти­фи­ка­то­ра сеан­са Java некой пере­мен­ной при помо­щи само­го пер­во­го бло­ка map, а далее про­смат­ри­вая посту­па­ю­щий URI запро­са на пред­мет пара­мет­ра с назва­ни­ем jsessionid, уста­нав­ли­вая соот­вет­ствие полу­чен­но­го зна­че­ния пере­мен­ной при помо­щи вто­ро­го бло­ка map. Такая дирек­ти­ва sticky с пара­мет­ром route пере­да­ёт любое чис­ло пере­мен­ных. Для необ­хо­ди­мо­го марш­ру­та при­ме­ня­ет­ся самый пер­вый нену­ле­вое или не пустое зна­че­ние. Если при­ме­ня­ет­ся некий куки jsessionid, такой запрос направ­ля­ет­ся в backend1; если исполь­зу­ет­ся некий пара­метр URI, соот­вет­ству­ю­щий запрос будет отправ­лен в backend2. Хотя этот при­мер осно­вы­ва­ет­ся на зна­че­нии иден­ти­фи­ка­то­ра сеан­са Java, то же самое при­ме­ни­мо и к про­чим тех­но­ло­ги­ям сеан­сов, таким как phpsessionid, либо любой иной, кото­рая обес­пе­чи­ва­ет выра­бот­ку уни­каль­но­го иден­ти­фи­ка­то­ра сеан­са для ваше­го приложения.

Порой вы жела­е­те направ­лять обмен в какой- то опре­де­лён­ный сер­вер имея несколь­ко более тон­кий кон­троль. Для дости­же­ния дан­ной цели создан пара­метр route в дирек­ти­ве sticky. Наклей­ка на марш­ру­те предо­став­ля­ет вам луч­шее управ­ле­ние, реаль­ное отсле­жи­ва­ние и свя­зы­ва­е­мость в про­ти­во­по­лож­ность алго­рит­му балан­си­ров­ки нагруз­ки с общим хэши­ро­ва­ни­ем. Такой кли­ент вна­ча­ле направ­ля­ет­ся в сер­вер верх­не­го уров­ня на осно­ве задан­но­го марш­ру­та, а затем после­ду­ю­щие запро­сы будут обра­ба­ты­вать полу­ча­е­мую в куки или URI инфор­ма­цию о марш­ру­те. Наклей­ки марш­ру­тов полу­ча­ют целый ряд вычис­ля­е­мых пози­ци­он­ных пара­мет­ров. Самая пер­вая не пустая пере­мен­ная при­ме­ня­ет­ся в каче­стве марш­ру­та к сер­ве­ру. Для выбо­роч­но­го раз­бо­ра пере­мен­ных и охра­не­ния их в каче­стве про­чих пере­мен­ных могут при­ме­нять­ся бло­ки map. В конеч­ном счё­те дирек­ти­ва sticky route созда­ёт некий сеанс внут­ри зоны сов­мест­ной памя­ти NGINX Plus для отсле­жи­ва­ния любых иден­ти­фи­ка­то­ров сеан­са поль­зо­ва­те­ля, кото­рые вы опре­де­ля­е­те для над­ле­жа­ще­го сер­ве­ра верх­не­го уров­ня, непре­рыв­но достав­ляя запро­сы с таким иден­ти­фи­ка­то­ром сеан­са в тот же самый сер­вер верх­не­го уров­ня, что и самый пер­вый запрос.

Осушение соединения

Зада­ча

Вам тре­бу­ет­ся акку­рат­но уда­лить сер­ве­ры для работ по сопро­вож­де­нию или по иным при­чи­нам и при этом про­дол­жать обслу­жи­ва­ние сеан­сов при помо­щи NGINX Plus.

Реше­ние

Через API NGINX Plus вос­поль­зуй­тесь пара­мет­ром drain,  что­бы про­ин­струк­ти­ро­вать NGINX о необ­хо­ди­мо­сти пре­кра­ще­ния отправ­ки новых под­клю­че­ний, кото­рые ещё пока не отслеживаются:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Преж­де чем уда­лять из име­ю­ще­го­ся пула некий сер­вер, в кото­ром локаль­но хра­нит­ся состо­я­ние сеан­са, сле­ду­ет осу­шить под­клю­че­ния и сеан­сы. Осу­ше­ние соеди­не­ний это про­цесс, кото­рый поз­во­ля­ет есте­ствен­ным обра­зом завер­шать­ся сеан­сам сер­ве­ра по исте­че­нию вре­ме­ни преж­де чем уда­лять сам сер­вер из соот­вет­ству­ю­ще­го пула вос­хо­дя­ще­го пото­ка. Вы може­те настро­ить осу­ше­ние для како­го- то кон­крет­но­го сер­ве­ра доба­вив пара­метр drain в соот­вет­ству­ю­щую дирек­ти­ву server. Когда пара­метр drain уста­нов­лен, NGINX Plus пре­кра­ща­ет отправ­ку новых сеан­сов в этот сер­вер, но поз­во­ля­ет теку­щим сеан­сам про­дол­жать своё обслу­жи­ва­ние на про­тя­же­нии вре­ме­ни жиз­ни их сеан­сов. Вы може­те вклю­чать такую настрой­ку добав­ляя соот­вет­ству­ю­щий пара­метр drain в дирек­ти­ву к сер­ве­ру вос­хо­дя­ще­го потока.

Пассивные проверки жизнеспособности

Зада­ча

Вам тре­бу­ет­ся выпол­нить пас­сив­ную про­вер­ку состо­я­ния жиз­не­спо­соб­но­сти сер­ве­ров вос­хо­дя­ще­го потока.

Реше­ние

Вос­поль­зуй­тесь про­вер­ка­ми жиз­не­спо­соб­но­сти NGINX для балан­си­ров­ки нагруз­ки что­бы убе­дить­ся что при­ме­ня­ют­ся толь­ко жиз­не­спо­соб­ные сер­ве­ры вос­хо­дя­ще­го потока:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Дан­ная настро­ка осу­ществ­ля­ет пас­сив­ный мони­то­ринг жиз­не­спо­соб­но­сти сво­е­го вос­хо­дя­ще­го пото­ка, назна­чая зна­че­ние max_fails дирек­ти­вы в три, а fail_timeout на три секун­ды. Дан­ные пара­мет­ры дирек­ти­вы рабо­та­ют одним и тем же спо­со­бом как для сер­ве­ров пото­ков, так и для сер­ве­ров HTTP.

Обсуж­де­ние

Пас­сив­ные про­вер­ки жиз­не­спо­соб­но­сти доступ­ны в вер­сии NGINX с Откры­тым исход­ным кодом. Пас­сив­ный мони­то­ринг выяв­ля­ет отка­зав­шие или завер­шён­ные по тайм- ауту под­клю­че­ния по мере их пере­да­чи через NGINX в каче­стве запро­сов неко­го кли­ен­та. Пас­сив­ные про­вер­ки жиз­не­спо­соб­но­сти вклю­че­ны по умол­ча­нию; упо­мя­ну­тые здесь пара­мет­ры поз­во­ля­ют вам под­стра­и­вать их пове­де­ние. Мони­то­ринг жиз­не­спо­соб­но­сти важен во всех типах балан­си­ров­ки нагру­зок, при­чём не толь­ко с точ­ки зре­ния вза­и­мо­дей­ствия поль­зо­ва­те­ля, но так­же и для обес­пе­че­ния непре­рыв­но­сти биз­не­са. NGINX выпол­ня­ет пас­сив­ный мони­то­ринг сер­ве­ров HTTP, TCP и UDP вос­хо­дя­ще­го пото­ка что­бы гаран­ти­ро­вать их жиз­не­спо­соб­ность и работу.

Активные проверки жизнеспособности NGINX Plus

Зада­ча

Вам тре­бу­ет­ся в NGINX Plus выпол­нять актив­ную про­вер­ку жиз­не­спо­соб­но­сти сер­ве­ров вос­хо­дя­ще­го потока.

Реше­ние

Для HTTP вос­поль­зуй­тесь в бло­ке место­по­ло­же­ния дирек­ти­вой health_check:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Дан­ная про­вер­ка жиз­не­спо­соб­но­сти для сер­ве­ров HTTP кон­тро­ли­ру­ет состо­я­ние жиз­не­спо­соб­но­сти име­ю­щих­ся сер­ве­ров вос­хо­дя­ще­го пото­ка выпол­няя каж­дые две секун­ды некий запрос HTTP к URI'/'. Что­бы рас­смат­ри­вать­ся жиз­не­спо­соб­ны­ми, соот­вет­ству­ю­щие сер­ве­ры вос­хо­дя­ще­го пото­ка долж­ны прой­ти пять после­до­ва­тель­ных про­ве­рок жиз­не­спо­соб­но­сти. Они рас­смат­ри­ва­ют­ся как не жиз­не­спо­соб­ные когда отка­зы­ва­ют две после­до­ва­тель­ные про­вер­ки. Соот­вет­ству­ю­щий отклик от тако­го сер­ве­ра верх­не­го уров­ня дол­жен соот­вет­ство­вать тому опре­де­ля­е­мо­му бло­ку соот­вет­ствия, кото­рый зада­ёт зна­че­ние кода состо­я­ния рав­ным 200, а зна­че­ние заго­лов­ка Content-Type как 'text/html' и стро­ку "Welcome to nginx!" в каче­стве зна­че­ния тела откли­ка. Сам HTTP match block име­ет три дирек­ти­вы: состо­я­ния, заго­лов­ка и тела. Все эти три дирек­ти­вы так­же име­ют фла­ги сравнения.

Про­вер­ки для служб TCP/UDP очень похожи:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

В дан­ном при­ме­ре некий сер­вер TCP настро­ен на ожи­да­ние по пор­ту 1234 и для выпол­не­ния посред­ни­че­ства к неко­му набо­ру сер­ве­ров вос­хо­дя­ще­го пото­ка, для кото­ро­го он и выпол­ня­ет актив­ные про­вер­ки жиз­не­спо­соб­но­сти. Соот­вет­ству­ю­щая дирек­ти­ва health_check полу­ча­ет все те же пара­мет­ры, что и HTTP, за исклю­че­ни­ем uri, а зна­че­ние вер­сии пото­ка име­ет пара­метр для пере­клю­че­ния прот­ко­ла про­вер­ки на udp. В дан­ном при­ме­ре зна­че­ние интер­ва­ла уста­нов­ле­но на 10 секунд, тре­бу­ют­ся два про­хо­да для того что­бы он рас­смат­ри­вал­ся как жиз­не­спо­соб­ный и три отка­за что­бы при­н­мать его не жиз­не­спо­соб­ным. Такая актив­ная про­вер­ка пото­ка так­же спо­соб­на удо­сто­ве­рять полу­ча­е­мый отклик от сво­е­го сер­ве­ра верх­не­го уров­ня. Тем не менее, соот­вет­ству­ю­щий блок match для сер­ве­ров пото­ка име­ет толь­ко два пара­мет­ра: send и expect. Зна­че­ни­ем дирек­ти­вы send явля­ют­ся под­ле­жа­щие отправ­ке сырые дан­ные, в то вре­мя как expect пред­став­ля­ет собой точ­ный отклик или некое регу­ляр­ное выра­же­ние для про­вер­ки соответствия.

Актив­ные про­вер­ки жиз­не­спо­соб­но­сти NGINX Plus непре­рыв­но выпол­ня­ют запро­сы к соот­вет­ству­ю­щим сер­ве­рам источ­ни­ков для кон­тро­ля их жиз­не­спо­соб­но­сти. Такие про­вер­ки жиз­не­спо­соб­но­сти спо­соб­ны про­ве­рять не толь­ко зна­че­ние кода откли­ка. В NGINX Plus актив­ные про­вер­ки жиз­не­спо­соб­но­сти HTTP осу­ществ­ля­ют мони­то­ринг на осно­ве неко­го чис­ла при­ем­ле­мых кри­те­ри­ев соот­вет­ству­ю­ще­го откли­ка от само­го сер­ве­ра верх­не­го уров­ня. Вы може­те настра­и­вать мони­то­ринг актив­ных про­ве­рок жиз­не­спо­соб­но­сти на то насколь­ко часто про­ве­ря­ют­ся сер­ве­ры вос­хо­дя­ще­го пото­ка, сколь­ко раз сер­вер обя­зан прой­ти такую про­вер­ку что­бы рас­смат­ри­вать его жиз­не­спо­соб­ным, сколь­ко раз он может отка­зы­вать преж­де чем будет рас­смат­ри­вать­ся как не жиз­не­спо­соб­ный и что сле­ду­ет рас­смат­ри­вать зна­че­ни­ем ожи­да­е­мо­го резуль­та­та. Зна­че­ние пара­мет­ра match ука­зы­ва­ет на некий блок соот­вет­ствия, кото­рый опре­де­ля­ет зна­че­ние при­ем­ле­мо­го кри­те­рия для полу­ча­е­мо­го откли­ка. Зна­че­ние бло­ка соот­вет­ствия так­же опре­де­ля­ет те дан­ные, кото­рые отправ­ля­ют­ся в опра­ши­ва­е­мый сер­вер верх­не­го уров­ня при исполь­зо­ва­нии зна­че­ния кон­тек­ста пото­ка для TCP/ UDP. Эти свой­ства поз­во­ля­ют NGINX гаран­ти­ро­вать жиз­не­спо­соб­ность сер­ве­ров вос­хо­дя­ще­го пото­ка на про­тя­же­нии все­го времени.

Медленный запуск

Зада­ча

Ваше при­ло­же­ние нуж­да­ет­ся в про­гре­ве преж­де чем начать при­ни­мать пол­ную про­мыш­лен­ную нагрузку.

Реше­ние

Для посте­пен­но­го уве­ли­че­ния обще­го чис­ла под­клю­че­ний со вре­ме­нем после того как некий сер­вер был пред­став­лен в сво­ём пуле вос­хо­дя­щей балан­си­ров­ки нагруз­ки, вос­поль­зуй­тесь пара­мет­ром slow_start в соот­вет­ству­ю­щей дирек­ти­ве server:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Дан­ная настрой­ка дирек­ти­вы server будет замед­лен­но про­гре­вать обмен к сер­ве­рам вос­хо­дя­ще­го пото­ка после их пред­став­ле­ния в дан­ном пуле. server1 будет мед­лен­но нара­щи­вать своё чис­ло под­клю­че­ний на про­тя­же­нии 20 секунд, а server2 в тече­нии 15 секунд.

Мед­лен­ный запуск явля­ет­ся кон­цеп­ци­ей мед­лен­но­го нара­щи­ва­ния обще­го чис­ла запро­сов для посред­ни­че­ской пере­да­чи в некий сер­вер на про­тя­же­нии како­го- то про­ме­жут­ка вре­ме­ни. Мед­лен­ный старт дела­ет воз­мож­ным для при­ло­же­ния выпол­нять про­грев, запол­няя его кэши, ини­ци­и­руя под­клю­че­ния к базе дан­ных без того что­бы ока­зать­ся пере­пол­нен­ным под­клю­че­ни­я­ми сра­зу после его запус­ка. Это свой­ство всту­па­ет в дей­ствие когда некий сер­вер, испы­тав­ший отказ при про­вер­ках жиз­не­спо­соб­но­сти, начи­на­ет про­хо­дить их сно­ва и воз­вра­ща­ет­ся в свой пул балан­си­ров­ки нагрузки.

Проверки жизнеспособности TCP

Зада­ча

Вам тре­бу­ет­ся про­ве­рить свой сер­вер TCP вос­хо­дя­ще­го пото­ка на жиз­не­спо­соб­ность и уда­лять не жиз­не­спо­соб­ные сер­ве­ры из их пула.

Реше­ние

Для некой актив­ной про­вер­ки вос­поль­зуй­тесь дирек­ти­вой health_check в над­ле­жа­щем бло­ке server:

[codesyntax lang="php" blockstate="collapsed"]

[/codesyntax]

Дан­ный при­мер выпол­ня­ет актив­ный мони­то­ринг сер­ве­ров сво­е­го вос­хо­дя­ще­го пото­ка. Под­ле­жа­щий отсле­жи­ва­нию сер­вер вос­хо­дя­ще­го пото­ка рас­смат­ри­ва­ет­ся как не жиз­не­спо­соб­ный если он отка­зы­ва­ет в откли­ке для трёх или более ини­ци­и­ро­ван­ных NGINX под­клю­че­ний TCP. NGINX выпол­ня­ет дан­ную про­вер­ку каж­дые 10 секунд. Опре­де­лён­ный сер­вер будет рас­смат­ри­вать­ся как жиз­не­спо­соб­ный толь­ко после про­хо­да двух про­ве­рок на жизнеспособность.

Про­вер­ка жиз­не­спо­соб­но­сти TCP может под­твер­ждать­ся со сто­ро­ны NGINX Plus пас­сив­но или актив­но. Пас­сив­ный мони­то­ринг жиз­не­спо­соб­но­сти осу­ществ­ля­ет­ся путём реги­стра­ции вза­и­мо­дей­ствия меж­ду име­ю­щим­ся кли­ен­том и его сер­ве­ром верх­не­го уров­ня. Когда такой сер­вер вос­хо­дя­ще­го пото­ка при­во­дит к тайм- ауту или откло­ня­ет под­клю­че­ния, пас­сив­ная про­вер­ка жиз­не­спо­соб­но­сти будет счи­тать такой сер­вер не жиз­не­спо­соб­ным. Актив­ные про­вер­ки жиз­не­спо­соб­но­сти будут ини­ци­и­ро­вать свои соб­ствен­ные настра­и­ва­е­мые про­вер­ки для опре­де­ле­ния жиз­не­спо­соб­но­сти. Актив­ные про­вер­ки жиз­не­спо­соб­но­сти не толь­ко кон­тро­ли­ру­ют некое под­клю­че­ние к сво­е­му сер­ве­ру вос­хо­дя­ще­го пото­ка, но так­же могут ожи­дать некий задан­ный отклик.