Jak skonfigurować globalne równoważenie obciążenia za pomocą Digital Ocean DNS i Nginx?

UPDATE: Zobacz odpowiedź, którą podałem poniżej, aby znaleźć rozwiązanie, które ostatecznie skonfigurowałem na AWS.

Obecnie eksperymentuję z metodologiami, jak najlepiej zaimplementować globalną warstwę równoważącą obciążenie dla moich serwerów aplikacji na Digital Ocean i jest kilka elementów, które muszę jeszcze złożyć.

Cel

Zaoferuj wysoce dostępną usługę moim użytkownikom, trasując wszystkie połączenia do najbliższego "klastra" serwerów w SFO, NYC, LON, a w końcu Singapur.

Dodatkowo chciałbym w końcu zautomatyzować konserwację tego, pisząc demona, który może monitorować, skalować i leczyć każdy z serwerów w systemie. Albo połączę różne usługi, aby osiągnąć te same cele automatyzacji. Najpierw muszę wymyślić, jak to zrobić ręcznie.

Stos

  1. Ubuntu 14.04
  2. Nginx 1.4.6
  3. węzeł.js
  4. MongoDB z Compose.io (dawniej MongoHQ)

Globalny Podział Domen

Gdy już wszystko ustawię, moja domena będzie wyglądać mniej więcej tak:

**GLOBAL**
global-balancing-1.myapp.com
global-balancing-2.myapp.com
global-balancing-3.myapp.com

**NYC**
nyc-load-balancing-1.myapp.com
nyc-load-balancing-2.myapp.com
nyc-load-balancing-3.myapp.com

nyc-app-1.myapp.com
nyc-app-2.myapp.com
nyc-app-3.myapp.com

nyc-api-1.myapp.com
nyc-api-2.myapp.com
nyc-api-3.myapp.com

**SFO**
sfo-load-balancing-1.myapp.com
sfo-load-balancing-2.myapp.com
sfo-load-balancing-3.myapp.com

sfo-app-1.myapp.com
sfo-app-2.myapp.com
sfo-app-3.myapp.com

sfo-api-1.myapp.com
sfo-api-2.myapp.com
sfo-api-3.myapp.com

**LON**
lon-load-balancing-1.myapp.com
lon-load-balancing-2.myapp.com
lon-load-balancing-3.myapp.com

lon-app-1.myapp.com
lon-app-2.myapp.com
lon-app-3.myapp.com

lon-api-1.myapp.com
lon-api-2.myapp.com
lon-api-3.myapp.com

I wtedy, jeśli jest jakieś obciążenie na danej warstwie, w danym regionie, mogę po prostu zakręcić nową kropelkę, aby pomóc: nyc-app-4.myapp.com, lon-load-balancing-5.myapp.com, itd ...

Aktualna Metodologia Pracy

  • A (minimum) trio serwerów global-balancing odbiera cały ruch. Serwery te są DNS Round-Robin zbalansowane jak pokazano w to (szczerze mówiąc mylące) artykuł: jak skonfigurować DNS Round-Robin Load Balancing .

  • Korzystanie z nginx GeoIP Moduł i Dane MaxMind GeoIP pochodzenie danego wniosku jest ustalane na podstawie $geoip_city_continent_code.

  • Następnie warstwa global-balancing kieruje żądanie do serweraleast connected na warstwie load-balancing odpowiedniej klaster: nyc-load-balancing-1, sfo-load-balancing-3, lon-load-balancing-2, itd.. Warstwa ta jest również (minimum) trójką kropelki.

  • Na regional load-balancing layer następnie kieruje żądanie do least connected serwer w warstwie app lub api: nyc-app-2, sfo-api-1, lon-api-3, etc ...

Szczegóły dotyczące kung-fu Nginx można znaleźć w tym samouczku: Konfiguracja Nginx z Gslb / Reverse Proxy na AWS . Więcej ogólnych informacji na temat równoważenia obciążenia Nginx jest dostępnych tutaj oraz tutaj .

Pytania

Where do a I put the global-balancing serwery?

Wydaje mi się dziwne, że umieściłem je wszystkie w jednym miejscu, albo rozłożyłem tę warstwę na całym świecie. Powiedzmy, że umieściłem je wszystkie w Nowym Jorku. Wtedy ktoś z Francji uderzy w moją domenę. Wniosek trafiłby z Francji do Nowego Jorku, a następnie został skierowany z powrotem do LON. Albo jeśli umieściłem po jednym w SFO, NYC i LON, to czy nadal nie jest możliwe, że użytkownik z Toronto (Parkdale, represent) może wysłać żądanie, które kończy się na Lon tylko po to, aby zostać przekierowanym z powrotem do NYC?

Czy kolejne żądania są kierowane do tego samego adresu IP?

Jak w przypadku, gdy użytkownik z Toronto wyśle żądanie, które warstwa global-balancing określi, że powinna iść do NYC, czy następne żądanie z tego źródła trafi bezpośrednio do NYC, czy nadal ma szczęście, że trafi ono na najbliższy serwer global-balancing (w tym przypadku NYC).

A co z sesjami?

Skonfigurowałem Nginx, aby używać dyrektywy ip_hash;, aby skierować user to the same app or api endpoint (proces węzłowy, w moim przypadku), ale w jaki sposób globalne równoważenie wpłynie na to, jeśli w ogóle?

Jakieś przykłady DNS?

Nie jestem do końca ekspertem DNS (obecnie próbuję dowiedzieć się, dlaczego moje rekordy CNAME nie są rozwiązywane), ale szybko się uczę, gdy dostarczę solidny przykład. Czy ktoś już wcześniej przeszedł ten proces i może podać próbkę tego, jak wyglądają rekordy DNS dla udanej konfiguracji?

Co? O SSL / TLS?

Czy potrzebuję certyfikatu dla każdego serwera, czy tylko dla trzech serwerów, skoro to jedyna publiczna Brama? Jeśli przeczytasz to wszystko, nagradzaj się babeczką. Z góry dziękuję za pomoc.
Author: AJB, 2014-09-05

4 answers

Cel: zaoferowanie wysoce dostępnej usługi moim użytkownikom poprzez przekierowanie wszystkich połączeń do najbliższego "klastra" serwerów w SFO, NYC, LON i ostatecznie Singapurze.

Warstwa global-balancing następnie kieruje żądanie do podłączony serwer...

Jeśli dobrze odczytuję Twoją konfigurację, w rzeczywistości zastępujesz swoje globalne balancery do balancerów w każdym regionie. To nie spełnia celu przekierowania użytkowników do najbliższego region.

Są trzy sposoby, które znam, aby uzyskać to, czego szukasz:

  1. 30x Redirect
    twoje globalne balancery otrzymują żądanie HTTP, a następnie przekierowują je do grupy serwerów w regionie, z którego żądanie pochodzi, lub w jego pobliżu, na podstawie adresu IP. To brzmi jak to, co chciałeś ustawić. Ta metoda ma skutki uboczne dla niektórych aplikacji, a także wydłuża czas potrzebny użytkownikowi na uzyskanie danych, ponieważ dodajesz tonę nad głową. Ma to sens tylko wtedy, gdy zasoby, do których przekierowujesz, są bardzo duże, a lokalny klaster regionalny będzie w stanie służyć znacznie wydajniej.

  2. Anycast (korzystając z routingu BGP)
    to jest to, co dużych graczy jak Akamai używać dla ich CDN. Zasadniczo w Internecie znajduje się wiele serwerów z dokładnie tym samym routowalnym adresem IP. Załóżmy, że mam serwery w kilku regionach i mają adres IP 192.0.2.1. Jeśli jestem w USA i próbuję połączyć się z 192.0.2.1, a ktoś jest w Europie, który próbuje połączyć się z 192.0.2.1, prawdopodobnie zostaniemy przekierowani do najbliższego serwera. Wykorzystuje to własny routing Internetu, aby znaleźć najlepszą ścieżkę (w oparciu o warunki sieciowe) dla ruchu. Niestety, nie można po prostu użyć tej metody. Potrzebujesz własnego numeru AS i fizycznego sprzętu. Jeśli znajdziesz dostawcę VPS, który pozwala Ci mieć kawałek ich bloku Anycast, pozwól mi wiem!

  3. Geo-DNS
    niektórzy dostawcy DNS dostarczają usługę często sprzedawaną jako "Geo-DNS". Mają kilka serwerów DNS hostowanych na adresach anycast, które mogą kierować ruch do najbliższych serwerów. Jeśli klient zapyta o Europejski serwer DNS, powinien zwrócić adres serwerów regionu europejskiego, a nie Niektórych w innych regionach. Istnieje wiele odmian usług Geo DNS. Inni po prostu utrzymują bazę danych geo-IP i zwracają serwer dla regionu, który ich zdaniem jest bliżej, podobnie jak metoda przekierowania, ale dla DNS, zanim żądanie HTTP zostanie kiedykolwiek wykonane. Jest to zwykle dobra opcja, za cenę i łatwość użycia.

Czy kolejne żądania są kierowane na ten sam adres IP?

Wiele load balancerów ma opcję "stickiness", która mówi, że żądania z tego samego adresu sieciowego powinny być kierowane do tego samego serwera końcowego (pod warunkiem, że serwer końcowy jest nadal uruchomiony).

A co z sesje?

Właśnie dlatego chciałbyś mieć taką lepkość. Jeśli chodzi o dane sesji, będziesz musiał znaleźć sposób, aby wszystkie serwery były aktualne. Realistycznie, nie zawsze jest to gwarantowane. To, jak sobie z tym poradzisz, zależy od twojej aplikacji. Czy możesz zachować instancję Redis lub cokolwiek innego, aby wszystkie twoje serwery mogły niezawodnie trafić z całego świata? Czy naprawdę potrzebujesz danych z sesji w każdym regionie? Czy możesz mieć swoje główne serwery aplikacji radzenie sobie z danymi sesji w jednym miejscu?

Jakieś przykłady DNS?

Wyślij osobne pytania do tych. "Udana konfiguracja" każdego wygląda inaczej.

A co z SSL / TLS?

Jeśli proxyujesz dane, tylko twoje globalne balancery muszą obsługiwać HTTPS. Jeśli przekierowujesz, wszystkie serwery muszą się tym zająć.

 18
Author: Brad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-05 03:25:43

Rozwiązanie Robocze

W ciągu ostatnich kilku miesięcy miałem dziką jazdę, rozpracowując całą konfigurację Global-HA. Tony zabawy i w końcu zadomowiłem się z platformą, która działa bardzo dobrze i nie jest podobna do tej opisanej w powyższym pytaniu.

Nadal planuję napisać to w formie samouczka, ale czasu jest mało, ponieważ udaję się do ostatniego sprintu, aby uruchomić moją aplikację na początku przyszłego roku, więc oto krótki zarys działającego sprzętu, który skończyłem z.


Przegląd

W końcu przeniosłem całe moje rozmieszczenie do AWS. Uwielbiam Digital Ocean, ale szczera rzeczywistość jest taka, że AWS jest o lata świetlne przed nimi (i wszystkimi, naprawdę), jeśli chodzi o usługi oferowane pod jednym dachem. Moje miesięczne wydatki nieznacznie wzrosły, ale gdy już skończyłem poprawiać i usprawniać, znalazłem rozwiązanie, które kosztuje około 75 USD / miesiąc na region dla najbardziej podstawowego wdrożenia(2 instancje za ELB). I Nowy region można rozwinąć i wdrożyć w ciągu około 30 minut.


Global Balancing

Szybko przekonałem się (dzięki odpowiedzi @Brad powyżej), że próba rozkręcenia własnej globalnej warstwy DNS balancing jest szalona. To było cholernie zabawne zastanawianie się, jak taka warstwa działa, ale bez wsiadania do samolotu i skrobania kostek instalując sprzęt wart miliony dolarów na całym świecie, nie było możliwe, aby toczyć moje własne.

Kiedy w końcu zorientowałem się, czego szukam, znalazłem mojego nowego najlepszego przyjaciela: AWS Route 53 . Oferuje solidną sieć DNS z około 50-nieparzystymi węzłami globalnie i możliwość wykonywania naprawdę fajnych sztuczek routingu, takich jak routing oparty na lokalizacji, routing oparty na opóźnieniach (co jest dość niesamowite) i AWS Alias rejestruje, że "automagicznie" przekierowuje ruch do innych usług AWS, których będziesz używać (jak ELB do równoważenia obciążenia).

I skończyło się na użyciu latency-based routing, który kieruje ruch globalny do najbliższego Regionalnego Elastic Load Balancer, który ma grupę automatycznego skalowania dołączoną do niego w danym regionie.

Zostawię ci zadanie domowe na innych dostawcach: www.f5.com, www.dyn.com, www.akamai.com, www.dnsmadeeasy.com. W zależności od twoich potrzeb, może być lepsze rozwiązanie dla ciebie, ale to działa bardzo dobrze dla mnie.


Dostarczanie Treści Sieć

Route 53 integruje się z AWS Cloudfront bardzo ładnie. Skonfigurowałem wiadro S3, którego używam do przechowywania wszystkich statycznych plików multimedialnych, które moi użytkownicy będą przesyłać, i skonfigurowałem dystrybucję Cloudfront do źródła z mojego wiadra S3 media.myapp.com. Są inni dostawcy CDN, więc zrób zakupy. Ale Cloudfront dostaje całkiem dobre recenzje i jest szybki do konfiguracji.


Równoważenie obciążenia i zakończenie SSL

Obecnie używam AWS Elastic Load Balancer do równoważenia obciążenia w instancjach aplikacji, które żyją w grupie Auto-skalowania . Żądanie jest najpierw odbierane przez ELB, w którym to momencie protokół SSL jest zakończony, a żądanie jest przekazywane do instancji w grupie automatycznego skalowania.

Uwaga: jedno wielkie zastrzeżenie dla ELB jest takie, że, jak na ironię, nie radzi sobie zbyt dobrze z masywnymi kolcami. Samo uruchomienie zdarzenia skalowania może potrwać do 15 minut, tworzenie 500 / timeouts w międzyczasie. Stały, stały wzrost ruchu jest podobno obsługiwany całkiem dobrze, ale jeśli zostaniesz uderzony kolcem, może cię zawieść. Jeśli wiesz, że zostaniesz trafiony, możesz "zadzwonić do przodu", a AWS rozgrzeje Ci ELB, co jest dość śmieszne i anty-wzorzec do istoty AWS, ale wyobrażam sobie, że albo nad tym pracują, albo ignorują, bo to nie jest tak duży problem. Zawsze możesz spin up your own HAProxy lub Nginx warstwa równoważąca obciążenie, jeśli ELB nie działa dla Ciebie.


Grupa Auto-Skalowania

Każdy region ma ASG, który jest zaprogramowany do skalowania, gdy obciążenie przechodzi określoną metrykę:

IF CPU > 90% FOR 5 MINUTES: SCALEUP
IF CPU < 70% FOR 5 MINUTES: SCALEDN
[7]}jeszcze nie przetestowałem combo ELB/ASG. To trochę w dół mojej listy zadań do zrobienia, ale wiem, że jest wiele innych osób korzystających z tej konfiguracji i nie wydaje się, aby mieć żadnych poważnych problemów z wydajnością.

Konfiguracja dla GRUPA Auto-skalowania jest moim zdaniem trochę zawiła. W rzeczywistości jest to proces trzyetapowy:

  1. Utwórz AMI skonfigurowane do swoich potrzeb.
  2. Utwórz konfigurację startową, która używa AMI, które utworzyłeś.
  3. Utwórz grupę automatycznego skalowania, która używa utworzonej konfiguracji uruchamiania, aby określić, jaki AMI i typ wystąpienia mają zostać uruchomione dla danego zdarzenia SCALEUP.

Aby obsłużyć konfigurację i wdrażanie aplikacji po uruchomieniu dowolnej instancji, należy użyć "User Data" pole do wprowadzania skryptu, który zostanie uruchomiony po uruchomieniu danej instancji. Jest to prawdopodobnie najgorsza nomenklatura w historii czasu. Jak" dane użytkownika " opisuje skrypt startowy tylko autor wie. Tak czy siak, to tam przyklejasz skrypt, który obsługuje wszystkie Twoje apt-get, mkdirs, klony git itp.


Instances & Internal Balancing

Dodałem również dodatkową "wewnętrzną warstwę równoważącą" za pomocą Nginx, która pozwala mi "flat-pack" wszystkie moje węzły.aplikacje js (app.myapp.com, api.myapp.com, mobile.myapp.com, www.myapp.com, etc.myapp.com) w każdym przypadku. Gdy instancja otrzymuje żądanie przekazane do niej z ELB, nginx obsługuje przekierowanie żądania do właściwego węzła.port js dla dowolnej aplikacji. Coś jak kontener dla biednych ludzi. Ma to dodatkową zaletę, że za każdym razem, gdy jedna z moich aplikacji musi rozmawiać z drugą (np. gdy app. musi wysłać żądanie do api.), odbywa się to za pośrednictwem localhost:XXXX, a nie za pomocą wyjść przez sieć AWS, albo przez sam internet.

Ta konfiguracja maksymalizuje również wykorzystanie moich zasobów, eliminując każdą bezczynną infrastrukturę, jeśli warstwa aplikacji, którą hostuje, odbiera lekki ruch. To również eliminuje potrzebę posiadania i ELB/ASG combo dla każdej aplikacji, oszczędzając więcej gotówki.

Nie ma gotchas ani zastrzeżeń, które napotkałem przy użyciu tego rodzaju konfiguracji, ale jest jedna praca, która musi być na miejscu w odniesieniu do kontroli zdrowia (zobacz poniżej).

Jest też dobra korzyść w tym, że wszystkie instancje mają rolę IAM, co oznacza, że {122]}Twoje kredy AWS są "pieczone" dla każdej instancji {35]} po urodzeniu i dostępne za pośrednictwem VAR-ów ENV. A AWS "automagicznie" obraca Twoje kredy za Ciebie. Bardzo bezpieczne, bardzo fajne.


Kontrole Zdrowia

Jeśli przechodzisz trasę powyższej konfiguracji, pakując wszystkie aplikacje na jednym pudełku i uruchamiając wewnętrzny load-balancer, musisz utworzyć mała użyteczność do obsługi kontroli zdrowia ELB . To, co zrobiłem, to stworzenie dodatkowej aplikacji o nazwie ping.myapp.com. a potem skonfigurowałem ELB Health Checks, aby wysyłać wszelkie kontrole zdrowia do portu, na którym działa moja aplikacja ping, w ten sposób: {]}

Ping Protocol: HTTP
Ping Port:     XXXX
Ping Path:     /ping

To wysyła wszystkie kontrole zdrowia do mojego małego pomocnika ping, który z kolei uderza localhost:XXXX/ping we wszystkich aplikacjach znajdujących się na instancji. Jeśli wszystkie zwrócą odpowiedź 200, moja aplikacja ping zwróci odpowiedź 200 na ocenę stanu ELB i instancje mogą żyć przez kolejne 30 sekund.

Uwaga: nie używaj automatycznej kontroli stanu skalowania, jeśli używasz ELB. Skorzystaj z kontroli zdrowia ELB. To trochę mylące, myślałem, że to to samo, nie są. Masz możliwość włączenia jednego lub drugiego. Idź z ELB.


Warstwa Danych

Jedna rzecz, która jest rażąco nieobecna w mojej konfiguracji, to warstwa danych. Używam Compose.io jako Mój dostawca zarządzanej warstwy danych wdrażam na AWS, więc mam bardzo małe opóźnienie między warstwami aplikacji a warstwą danych. Przeprowadziłem wstępne dochodzenie w sprawie tego, w jaki sposób rozpowszechniłbym moją warstwę danych na całym świecie i odkryłem, że jest to bardzo złożone - i bardzo drogie - więc wykopałem to z mojej listy jako problem, który nie wymaga jeszcze rozwiązania. Najgorsze jest to, że uruchomię moją warstwę danych tylko w US-East i wzmocnię sprzęt. Nie jest to najgorsza rzecz na świecie, ponieważ moje API jest ściśle dane JSON na przewodzie, więc średnia odpowiedź jest stosunkowo niewielka. Ale widzę, że staje się to wąskim gardłem na bardzo dużą, globalną skalę-jeśli kiedykolwiek tam dotrę. Jeśli ktoś ma jakiś wkład w tę warstwę, chciałbym usłyszeć, co masz do powiedzenia.


Ta-Da!

Globalna Wysoka Dostępność W Budżecie Piwa. Zajęło mi tylko 6 miesięcy, żeby to rozgryźć.

Uwielbiam słuchać każdego, kto to czyta.
 12
Author: AJB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-23 04:17:16

Możesz użyć Anycast dla swojej usługi internetowej za darmo, jeśli korzystasz z bezpłatnego planu Cloudflare.

 2
Author: miolini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-23 14:32:19

Digital Ocean obsługuje teraz Równoważenie Obciążenia samych serwerów. Jest niezwykle łatwy w konfiguracji i działa świetnie! Oszczędza konieczność dodawania niepotrzebnych komponentów, takich jak nginx (jeśli chcesz używać tylko do równoważenia obciążenia).

Mieliśmy problemy z przesyłaniem plików SSL za pomocą nginx na serwerze digital ocean, jednak od czasu aktualizacji Digital Ocean usunęliśmy nginx i teraz korzystamy z funkcji równoważenia obciążenia Digital Ocean i działa tak, jak tego potrzebujemy!

 0
Author: Sean _space,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-01 11:46:45