Serwer przed aplikacjami które mają embedded server

0

Uczę się o web serwerach i próbuję zrozumieć po co apka webowa ma w sobie web serwer skoro przed nią też "stoi" web serwer (jak na obrazku poniżej). Biorę za przykład aplikację w Spring (ale jeśli macie jakiś lepszy/prostszy przykład to chętnie dam się pokierować) https://docs.spring.io/spring-boot/docs/3.2.5/reference/html/howto.html#howto.webserver

Each Spring Boot web application includes an embedded web server

I znalazłem sobie takie repo (koreańskie 🇰🇷... chodziło o dobry rysunek) https://github.com/wjdrbs96/SpringBoot-Docker-Nginx i tam jest taki obrazek image

gdzie widzimy:

  • na wejściu jest nginx który sam jest web serwerem (i nad strzałkami widać "Reverse proxy" chociaż ja nie potrafię w tym repo odnaleźć potwierdzenia że faktycznie taką rolę pełni)
  • który prowadzi (routuje? proxuje?) do dwóch instancji tej samej apki w Spring, gdzie Spring sam inicjalizuje wewnętrzny "embedded server" (zdaje się że domyślnie jest to Tomcat)

No i nie mogę zrozumieć - czy każda kolejna instancja apki będzie miała kolejny web serwer w sobie? Zawsze tak to się robi? Nie powoduje to niepotrzebnego mnożenia web serwerów? Czy da się to zrobić inaczej (np. z tylko 1 web serwerem)?

0

To się nazywa tak zwany data parallelism model.

Nginx działa tutaj jako load balancer, może także serwować statyczne strony zcachowane dla lepszej efektywności, czyli po prostu frontend czy jakieś pliki, a te pody/kontenery robią za backend, spring aplikacja czyli rest api zazwyczaj, jeśli to są inne usługi to przekierowuje się je pod inny adres.
Jeśli to są te same usługi wtedy mamy właśnie data parallelism, często to się używa, jeśli masz duże modele AI, albo po prostu serwery backend nie wyrabiają, można dodać replikę tej samej aplikacji.

Wtedy w nginx definiujesz sobie regułę load balancingu najprostsza to round robin, są też inne i bardziej zaawansowane sposoby balancingu już na poziomie serwera DNS, wtedy np. trafiasz do najbliższego serwera, potem trafia się load balancer w serwerze, a ten mając reguły http, i może ci dodawać jakieś headery do zapytań, a także przekierowuje patrząc pod jakie adresy url uderzasz.

W taki sposób możesz także mieć jeden serwer z jednym ip adresem, a wewnątrz mieć np. 10-20 serwerów, jeden adres ip, ale każdy ma inny url adres, i regułami napisanym pod http możesz przekierowywać zapytania do danych serwerów czy sieci dockera wewnątrz usługi czyli do wirtualnych sieci, odesparowanych od siebie dla bezpieczeństwa, w których pracują twoje kontenery.
Oczywiście nginx się akurat nie używa do tego akurat tylko jakichś lepszych hardware loadbalancerów.

0

Możesz wytłumaczyć o co chodzi ci z tym

data parallelism model

w kontekście mojego pytania? Nie czaję a internet w tym kontekście nie podpowiada.

0

Nie wiem, czy dobrze rozumiem pytanie 😅 ale spróbuję.

Może być wiele różnych powodów, dla których "z przodu" (pod adresem dostępnym z internetu) stawia się nginxa.
Szczegóły to chyba temat na osobną dyskusję. Strzelam, że nginx ma w gdzieś w dokumentacji podstronę "why use nginx".

Skoro już ktoś podjął decyzję, że z przodu w osobnym kontenerze będzie nginx, a z tyłu w osobnych kontenerach będą instancje apki, to jakoś te kontenery muszą się komunikować.
Gdyby kontenery apki nie miały serwera HTTP, to w jaki sposób nginx miałby uzyskać od nich odpowiedź, którą potem odeśle do przeglądarki?

0

Gdyby kontenery apki nie miały serwera HTTP, to w jaki sposób nginx miałby uzyskać od nich odpowiedź, którą potem odeśle do przeglądarki?

@Pafnucy no, w dockerze faktycznie jest problem. I to taki dosyć critical rzekłbym. Poprzez postawienie publicznego webservera przed kontenerem de facto ujawniamy światu adres owego kontenera. Dockera się nie stosuje. Po prostu.

W Kubernetes tego problemu nie ma.

0
mustang_ex napisał(a):

Gdyby kontenery apki nie miały serwera HTTP, to w jaki sposób nginx miałby uzyskać od nich odpowiedź, którą potem odeśle do przeglądarki?

@Pafnucy no, w dockerze faktycznie jest problem. I to taki dosyć critical rzekłbym. Poprzez postawienie publicznego webservera przed kontenerem de facto ujawniamy światu adres owego kontenera. Dockera się nie stosuje. Po prostu.

Możesz rozwinąć temat tego critical i publicznego webservera? Do tej pory wydawało mi się, że do kontenera podpinasz 2 sieci (internal, external) nginx gada z appką w kontenerze po internalu, a na świat wystawia external. A jak masz jakieś wydumane scenariusze sieciowe, to chyba możesz dodać sobie tyle vethów, ile potrzebujesz.

0
marian pazdzioch napisał(a):

Możesz wytłumaczyć o co chodzi ci z tym

data parallelism model

w kontekście mojego pytania? Nie czaję a internet w tym kontekście nie podpowiada.

Data parallelism bardziej pochodzi z AI/ML działki, gdzie mamy model sieci i on tam ma bardzo dużo danych do przetworzenia, żeby nauczyć model jak jeden odpalimy to on tam wykonuje zadanie w jakimś czasie, można kilka na raz uruchomić, a później po każdym wyliczeniu gradientu go akumulować i synchronicznie czy asynchronicznie uaktualniać modele na różnych maszynach, tak żeby miały aktualny model globalny.
Czyli ogólnie mówiąc masz kilka replik tego samego programu uruchomione, jeśli jakiś program nie jest wielordzeniowy tylko używa jednego rdzenia, a masz 8 rdzeni to możesz albo użyć aplikacji, która dobrze wykorzysta całe zasoby jednego urządzenia lub uruchomić kilka i rozłożyć obciążenie czy ilość pracy, a jak masz więcej niż jedno urządzenie czyli jakiś cluster to też są sposoby, żeby różne obliczenia na różnych maszynach wykonać i potem je zescalować, zmergować w jakimś punkcie lub na każdej maszynie zrobić replikę czyli uruchomić ten sam program czy mikrousługę.

W kontekście twojego pytania, ten przykład co dałeś tam gościu odpala hello world w springu, nginx robi za load balancer, to oba aplikacje spring robią to samo, tylko połączenia z ngixem są rozrzucane pomiędzy jeden i drugą aplikację spring równomiernie.
Sam nginx na 2 rdzeniach może utrzymać do 100k requestów na sekundę, a jakieś microserwisy mogą np. dawać radę po 1-10k requestów na sekundę i po ileś użytkowników za nim opóźnienia będą nieakceptowane dla komfortowego korzystania z aplikacji, bo wykonują więcej pracy i możesz zrobić kilka takich instancji żeby zmniejszych ich obciążenie.
Zależy też czy to jest cluster i te kontenery na innych maszynach czy na tej samej, bo możesz nie mieć wystarczajacej ilości rdzeni, żeby było optymalne trzymanie takiej ilości kontenerów.
Taki nodejs to głównie pracuje na jednym rdzeniu, a reszta wykonuje zadania w tle, ale też może mieć zapchany event loop na tyle, że czasem bardziej będzie opłacać się użyć większej ilości replik, ale takie rzeczy dopiero dowiesz się na benchmarkach bo oczami nie wyliczysz czy na tej samej maszynie będzie opłacać się uruchomić więcej czy po prostu jeśli aplikacja dobrze wykorzystuje wszystkie rdzenie to i tak nie ma zasobów w systemie więcej, żeby robić kopie, bo będą musiały się podzieli.

Można też zrobić nginxa jako router, czyli jeśli ktoś bije pod adres www.example.pl/api/ to wtedy rzucasz go do serwera spring:8080, a jak ktoś zrobi www.example.pl/weather/ to dajesz go do innego mikroserwisu np. spring:8081, który np. zapewnia dostęp do danych pogodowych czy czegoś innego.

Jak masz model AI co długo przetwarza dane to możesz mieć jakąś queue kafkę, gdzie np. spring wrzuca zadania, te są odbierane przez subskrybujące repliki tego samego modelu, tyle że na innych maszynach i jak skończą to wrzucają na inny topik i spring po przetworzeniu po jakimś czasie może zwrócić informację użytkownikowi o wykonaniu zadania.

0

wydumane scenariusze sieciowe

@yarel wcale nie wydumane. Standardowe rzekłbym.

Przykład? Masz apkę (tematyka dowolna), która to apka ma jakąś tam interację z userem, to apkę robisz w kontenerze Kubernetesowym, stawiasz przed nią proxy i odcinasz apce bezpośrednią komunikację in/out. W proxy robisz przekieroanie z portu 443 na port wejścia web kontenera i tyle w temacie.

Natomiast docker ma proxowanie utrudnione/wydumane.

0

W sumie to ten klip, choć mówi o pythonowej web apce, wyjaśnia po co ten ngnix

1 użytkowników online, w tym zalogowanych: 0, gości: 1