Kontenery aplikacji w java

0

Witam, mam takie pytanie o kontenery aplikacji w javie.
Jestem dość młodym programistą, nie pamiętam JEE. Nie pamiętam nawet monolitów.

Dlatego pytanie może dość proste - po co są kontenery aplikacji w javie jak Tomcat, Netty, Jetty etc.?
Obecnie mamy springa. A spring używa jakiegoś kontenera.

Na szybko znalezione ficzery w tomcat:

  • Specification APIs.
  • Servlet 4.0 API.
  • JavaServer Pages 2.4.
  • WebSocket 2.0.
  • Session Manager.
  • Logging.

Poza obsługą JSP nie widzę tu nic kosmicznego, czego nie można byłoby dołączyć do aplikacji jako bibliotekę.


Pytanie zostało stworzone przez kontakt z node.js i biblioteką express.js która startuje jak meserszmit.

1

Nie rozumiem pytania. Jetty czy Tomcat to jest po prostu webserwer. Można go sobie dodać jako "bibliotekę" jak bardzo chcesz (tak robi Spring Boot) ale zgodnie z taką logiką wszystko można dodać jako bibliotekę ;) Bazę danych przecież też można i wiele innych elementów też.

0

Może faktycznie moja wiedza jest za mała żeby sensownie na ten temat gadać. Chodzi mi raczej o sens istnienia czegoś takiego jako dużego komponentu

0

Chodzi ci o to czemu ktoś woli dodać sobie zależność od 1 elementu, o którym wiadomo ze działa, niż od 50 różnych i potem przez 3 tygodnie dopasowywać sobie wersje zależności żeby zadziałało? :D Faktycznie, trudno sie domyślić czemu...
A w swoich aplikacjach dodajesz sobie zależność od 1 bazy danych czy składasz sobie taką "bazę" z wielu niezwiązanych ze sobą komponentów, próbując je jakoś dopasować?

Ma to szczególnie sens kiedy i tak potrzebujesz wszystkich tych elementów.

0

@Shalom:
Jeśli wszystkich to jestem w stanie to zrozumieć. Ale dlaczego aż 50? Po co mi JSP, WebSockety i ciężki kontener, kiedy zazwyczaj używamy zwykłego RESTa do którego powinny wystarczyć servlety + serializer/deserializer. Oczywiście zdaję sobie sprawę że dzieje się tam o wiele więcej, obsługa wątków itd. Ale przed chwilą znalazłem chociażby projekcik w javie - ratpack. W main() możemy sobie w prosty sposób zadeklarować serwer który nasłuchuję na jakimś tam porcie i w bardzo deklaratywny sposób można sobie stworzyć kontroler. Leciutki i szybciutki.

Ja mam może za dużo naleciałości z .NET Core gdzie mogę zarządzać bibliotekami i tym czego używam, ale dzięki temu aplikacje są o wiele lżejsze.
Interesuje mnie powód - zarządzanie zależnościami w różnych wersjach nie wydaje mi się powodem. Co to znaczy że nie są ze sobą kompatybilne skoro realizują zupełnie inne zadania? Nasz kod może nie być z nimi kompatybilny, ale to zaleta - możemy migrować na nowszą wersję w obszarze który nas bardziej interesuje, co więcej nie musimy robić wszystkiego na raz.

Poza tym nie wiedziałem że tomcata można sobie dołączyć jako bibliotekę - myślałem że to coś w hostingu na nasze pomysły :)
Nawiasem mówiąć gdzieś na stacku przeczytałem że jeśli moja aplikacja używa serwletów to potrzebuję kontenera aplikacji (np tomcat) - ale przecież to bzdura.

Może inaczej - nie jestem w stanie pojąć czym dokładnie jest i po co jest taki kontener.

1

Pytasz Po co mi ciężka baza danych skoro ja sobie tylko chce zapisać na chwile XYZ i mogę to zrobić w mapie w pamięci. Leciutkie i szybciutkie.
Używasz tego co ci potrzeba! Jak sie okaże że potrzebujesz wszystkiego czego dostarcza taki tomcat czy jetty to użyjesz tego tomcata, zamiast składać te wszystkie funkcjonalności z kawałków.

0

Fakt można to sprowadzić do tego poziomu. Może za szybko założyłem wątek na forum - jak zacząłem myśleć o kontenerach jak o webserverach to trochę mi się rozjaśniło.
W każdym razie niesądzę żeby w 90% projektów to było w ogóle potrzebne, a ludzie używają tego wszystkiego z przyzwyczajenia marnując mnóstwo zasobów :|

Dzięki!

EDIT:
Głównym powodem dla którego używa się node w niektórych projektach jest jego lekkość - z javy można wyciągnąć coś przybliżonego jeśli chodzi o zasoby. Ja osobiście uważam że JS jest bardzo YOLO - jest jakiś nurt w javie w którym można płynąć idąc w tę stronę lekkości i zwiewności? Bo widzę że wszystko spring a to chyba nie są synonimy.

EDIT2: w/w ratpack używa netty

7

Ponieważ pamiętam jak serwery aplikacji, kontenery się tworzyły to znam odpowiedź:
"są po nic - bezużyteczne".
Z perspektywy roku 2019 (i 2015 też).

Te twory miały sens w roku 2000. Zostały stworzone, aby rozwiązać ówczesne problemy:

  • brak ram,
  • zarządzanie konfiguracją (security, sięć itp).

Odnośnie RAM
Każdy wystartowany JVM pożera trochę ramu, do tego inicjuje różnego rodzaju pule, które są niezbędne, żeby aplikacja szybko działała (baza, http, pule wątków itd).
Pod koniec lat 90tych spece it stwierdzili, że można będzie dużo RAM na serwerach oszczędzić jak te wszystkie elementy wyciągniemy jako wspólny middleware i będziemy więcej aplikacji odpalać w ramach jednego kontenera. Żeby lepiej przybliżyć, o jakich rozmiarach RAM mówimy - mój pierwszy serwer java startowałem na maszynie z 4MB RAM (megabajtach, nie gigabajtach!) i musiałem zwiększyć RAM do 8GB, bo inaczej nie działał. Wypasione serwery miały wtedy 128MB RAM :-)
W praktyce okazało się, że RAM stał się tani i 99% aplikacji jest odpalanych samodzielnie - jeden tomcat jedna aplikacja.

Odnośnie konfiguracji - zwykle nie chcemy w aplikacji zaszywać na sztywno takich rzeczy jak porty http, adresy bazy danych itp. To wszystko dzięki tomcatowi (czy innemu serwerowi) można mieć w jednym konfigu (jako XML).
I fajnie, tylko że od kilku lat spopularyzowały się kontenery typu Docker, które zapewniają to samo, a co więcej dla dowolnej technologii, a nie tylko javy. Zamiast mieć 6 rodzajów specjalistów od konfiguracji, można mieć teraz jeden typ na prawie wszystko.

Jak widać te dwie przyczyny są lekko już nieaktualne, ale to nie koniec.
Gorzej, żeby te nieaktualne problemy rozwiązać trzeba ponieść duży koszt, związany ze sposobem działania kontenerów:

W przypadku użycia kontenera Startujemy jakaś aplikację kontener ( np. tomcat), a ona dopiero czyta naszą paczkę, konfigi i startuje aplikację.
I mamy często problemy typu:

  • konflikty klas, jeśli serwer wewnętrznie korzysta z jakiś bibliotek i my chcemy z podobnych to biada jak np. je dołączymy, albo jeszcze dołączymy w innej wersji, dzieją się cuda (typowo przy klasach związanych z logowaniem (`org.apache.log4j.Logger cannot be cast to org.apache.log4j.Logger), api servletów, commonsach, parsowaniu XML itp.
  • długi czas startu - serwer startuje, a potem skanuje nasze paczki - i czyta np. 500 klas, chociaż powinien się zainteresować tylko jedną z nich..., bo tam mamy servlet,
  • deployment, zabawy z wrzucaniem paczek na serwer to ciekawa historia, pakowanie do wara, które jest sztuką, czasem serwer nie załapie zmian, czasem (praktycznie zawsze) są wycieki pamięci przy restarccie aplikacji (war) itp.
  • testowalność aplikacji opartych o kontenery jest kijowa - taki prosty test typu :
  1. załóż testową baze danych
  2. wrzuć dane
  3. wystartuj serwer z tą testową bazą
  4. odpal REST i sprawdź czy serwis zwraca zakładany rezultat
    Przy korzystaniu z servletów (i czegokolwiek co jest nakładką na nie: JSP, spring-mvc* ) jest dość trudny do wykonania, do tego długo trwa.

Problemów są mniejsze jeśli korzystamy z embedded serwera - wtedy konflikty klas są łatwiejsze do ogarnięcia, deployment odpada, a i również jakoś da się testować (choć nadal powoli).

Jakkolwiek, uważam że embedded serwery (tomcat itp) to kupa przykryta dywanem. Niby nie widać, ale jednak śmierdzi. Pod spodem nadal działa sobie stara technologia zaprojektowana pod zupełnie inny sposób używania.

W 2019 jeśli robimy klasyczny REST serwis mamy dużo technologii/ bibliotek, które nie są oparte o servlety (pierwotne źródło zła).

Panowie z technology radar, którzy są względnie konserwatywni, uznali serwery aplikacji za zbędne w 2015 :
https://www.thoughtworks.com/radar/platforms/application-servers

Wszystko to wyżej aplikuje się (nawet bardziej ) do tzw. pełnych serwerów aplikacji - Java EE.

Wersja TL;DR
Olać kontenery, korzystać z bibliotek (w ostateczności z frameworków).

Edit:

Shalom napisał(a):

Używasz tego co ci potrzeba! Jak sie okaże że potrzebujesz wszystkiego czego dostarcza taki tomcat czy jetty to użyjesz tego tomcata, zamiast składać te wszystkie funkcjonalności z kawałków.

To podejście ma wadę. Czasem chcemy dołożyć jakąś bibliotekę, która częšciowo pokrywa się z tym co zapewnia tomcat i nagle się okazuje, że tracimy tydzień na walkę z konfliktami klas//bz.apache.org/bugzilla/show_bug.cgi?id=62353

0

@jarekr000000: Jeśli olać, to faktycznie tworzysz te aplikacje w ten sposób - produkcyjnie? Obawiam się że kod łatwiej się zmienia niż mindset i jak tak sobie rozmawiam z programistami javy to wielu uważa że to co robią od X lat działa i tak się robi i tak jest ok. Ostatnio miałem dyskusję np. na temat optionali która dziwnie się skończyła bo w zasadzie wyszło na to że kotlin lepiej to rozwiązał bo dodał syntax sugar w postaci dodatkowego operatora - zwykłego nullchecka, ale ładniejszego. Z doświadczeń w C# wiem że raczej nie tędy droga choć operator spoko dopóki nulle istnieją.

Proponujesz coś w zamian springa, kontenerów aplikacji itd. Bo nie widzę nic w tym stylu. DI można zastąpić biblioteką Guice. Ale coś co pozwoli na łatwe zrobienie aplikacji restowej? Bo do poziomu serwletów wolałbym nie sięgać tak w produkcyjnym kodzie. Obsługa certyfikatów, wątków - powinna być oparta na czymś dobrze sprawdzonym. No i do tego community też jest ważne, integracja z jakimiś popularnymi rzeczami - zipkin, ELK, kafka etc.
Jak szukam czegoś sensownego to natknąłem sie na kilka jak Akka - a potem się okazało że to jeszcze większa kobyła

EDIT. I dziękuję właśnie o takie informacje potwierdzające moje wątpliwości mi chodziło haha, co nie znaczy że odpowiedź kolegi wyżej nie była pomocna.

0

Przede wszystkim o żadnych gołych servletach nie ma mowy, skoro właśnie o to chodzi, żeby servletów w ogóle nie było.
Na szybko odpowiem tak:

  • Spring webflux . Masz wszystko do rest, pozwala się przecisnąć pod okiem nieuważnych architektów, bo przecież spring 2.0 jest zatwierdzony :-), dużo bibliotek do integracji, ale jest zamieszanie bo łatwo pomylić ze zwykłym springiem,
  • akka http. Akka jest modułowa i może całość duża, ale wybierasz sobie co potrzebujesz, podobnie jak w spring, dużo bibliotek do integracji, np.: alpaka, akka jest bez sensu jak nie używasz scali.
  • ratpack- najfajniejszy imo do rest, ale mam tylko w zabawkowych aplikacjach.

Trochę ludzi używa vert.x, ale dla mnie to trochę znowu mowe wcielenie kontenera, tylko w lepszych technologiach. Za dużo walczę z architektami i kolegami, żeby się pakować w takie kobyły. Choć może (paradoksalnie) byłoby łatwiej, ludzi trudno przekonać, że nie potrzebują niczego specjalnego...

Do DI najlepiej używa się konstruktorów. Żadnych kontenerów i frameworków nie potrzebujesz.

Piszę w kotlinie. Używam Option z vavr. Kotlinowego null tylko na styku z kupowymi frameworkami, które sypią nullami. Szkoda, że zamiast tych dodatkowych kilku operatorów do null nie dorobili czegoś do sekwencjonowania monad (do notation). Pewnie bym używał T? częściej, gdyby nie to, że chce mieć null safety również w javie(w ramach tego samego projektu).

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