Apache Tomcat, vyvinutý nadací Apache Software Foundation, je open source kontejner servletů Java, který funguje také jako webový server. Zatímco více než 10 000 webových stránek spoléhá na Tomcat jako webový server, Plumbr aplikačních serverů Java ukázal, že více než 60 % webových stránek, které používají technologii Java, spoléhá na Apache Tomcat jako hostitel obchodní logiky.
Produkční prostředí musí mít vysoký výkon. To vyžaduje, aby byl Apache Tomcat nakonfigurován tak, aby zvládal maximální možnou zátěž a přitom poskytoval uživatelům nejlepší dobu odezvy. Výkon, který aplikační server poskytuje, často závisí na tom, jak dobře je nakonfigurován. Poskytnutá výchozí nastavení často nejsou optimální.
V eG Innovations používá naše eG Enterprise IT řešení pro monitorování výkonu jako webový server Apache Tomcat. V průběhu let jsme objevili několik tipů a triků pro konfiguraci Tomcatu, abyste dosáhli nejvyšší možné úrovně škálovatelnosti. Tento blogový příspěvek dokumentuje naše poznatky o osvědčených postupech, které byste měli používat při nasazování Tomcatu do produkce.
Prvním krokem k dosažení vysokého výkonu je uvědomit si, že samotné vyladění aplikačního serveru Tomcat nestačí. Tomcat totiž běží na virtuálním stroji Java (JVM). Špatně nakonfigurovaný JVM tedy ohrozí výkon. Stejně tak JVM běží na operačním systému a pro dosažení nejvyššího možného výkonu je důležité mít co nejlepší konfiguraci operačního systému. Dokonce i úzká místa v kódu aplikace mohou vést ke stížnostem „Tomcat je pomalý“. Celkově vzato je třeba k ladění výkonu Tomcat zaujmout holistický přístup.
Ladění výkonu je nutné provést na každé vrstvě: operační systém, JVM, kontejner Tomcat a na úrovni kódu aplikace
V následujících částech představíme osvědčené postupy konfigurace operačního systému, JVM, kontejneru Tomcat a kódu aplikace pro dosažení nejlepšího možného výkonu.
Jelikož Tomcat používá JVM, má výkon JVM vliv také na výkon Tomcatu.
Než začnete upravovat jakékoli nastavení, měli byste se ujistit, že jste pro svou aplikaci vybrali moderní JVM. Existuje mnoho benchmarků, které ukazují 5-20% nárůst výkonu z každé verze Javy (další podrobnosti naleznete v tomto článku). Mnoho JVM je dostupných v 32bitových a 64bitových režimech. Zatímco 32bitový režim je omezen na 2 GB paměti, 64bitové JVM umožňují nastavení haldy Java mnohem vyšší. Proto se ujistěte, že používáte 64bitové JVM pro nejlepší výkon a nejvyšší škálovatelnost.Sběr odpadu je proces, kterým programy Java provádějí automatickou správu paměti. V minulosti se svoz odpadu prováděl způsobem „stop-the-world“. To znamená, že když došlo k uvolnění paměti, aplikace byla pozastavena, aby byla uvolněna paměť. Dnes existuje mnoho implementací garbage collection, kde garbage collection probíhá paralelně s prováděním aplikace.
Pro nejlepší výkon se ujistěte, že jste zvolili moderní garbage collector, jako je G1GC (Garbage First Garbage Collector) nebo Z Garbage Collector. Nastavení MaxGCPauseMillis pro JVM lze použít k nastavení maximální doby pauzy očekávané v prostředí. Pro nejlepší výkon se doporučuje, aby tato hodnota byla mezi 500-2000 ms. Zatímco delší pauzy zvyšují propustnost, kratší pauzy snižují latenci a propustnost. Kromě různých nastavení GC sledujte server Tomcat v produkci a ujistěte se, že procento času, které JVM tráví sběrem odpadu, je nízké. Jakákoli hodnota vyšší než 5 % bude mít negativní dopad na výkon Tomcatu.Dostupnost paměti v JVM může také nepříznivě ovlivnit výkon Tomcatu.
Musíte se ujistit, že je k dispozici dostatek paměti ve všech fondech haldy a nehaldové paměti. Pokud některému z paměťových fondů dochází dostupná paměť, setkáte se s výjimkami OutOfMemory a aplikace může selhat neočekávaným způsobem. Pomocí příznaků Xmx a Xms JVM nastavte maximální velikost haldy a velikosti zásobníku a pomocí příznaků XX nastavte velikost PermSize nebo MetaspaceSize v závislosti na verzi používaného JRE (další informace naleznete v tomto článku).Ujistěte se, že paměť dostupná pro každou z paměťových oblastí JVM je dostatečná. Nedostatek paměti nepříznivě ovlivní výkon serveru Tomcat.
Nastavení limitů paměti je často proces pokus-omyl. Nastavení příliš nízkých limitů paměti může vést k výjimkám, zatímco jejich příliš vysoké nastavení může vést k plýtvání zdroji. Použijte nástroj pro monitorování JVM a analyzujte výkon během týdne nebo déle, přičemž vezměte v úvahu také hodiny ve špičce, abyste určili optimální hodnoty paměťových fondů JVM.Pokud paměť roste v JVM neomezeně, budete muset určit, zda existuje paměť únik v aplikaci.
Vytvořte výpis haldy paměti pomocí vestavěných nástrojů Java, jako jsou JvisualVM a Jconsole. K určení podezřelých z úniku paměti použijte nástroje, jako je Eclipse Memory Analyzer (MAT). Dominator Tree MAT vám pomůže zúžit vlákna/objekty, které způsobují únik paměti.Nakonec sledujte aktivitu vláken v JVM.
Zatímco celkový počet vláken v JVM musí být sledován, aby bylo možné zjistit jakékoli úniky vláken, je důležité sledovat bloky vláken a uváznutí, protože jsou škodlivé pro výkon. Trasování zásobníku blokujících vláken a uvázlých vláken může odhalit problémy na úrovni kódu aplikace.Identifikace bloků vláken a uváznutí způsobujících zablokování aplikace
Kromě toho sledujte využití procesoru jednotlivými vlákny, abyste odhalili běžící vlákna, která zabírají CPU a zpomalují Tomcat. Tyto poznatky může opět poskytnout jakýkoli nástroj pro monitorování na úrovni JVM. V některých případech mohou vlákna na pozadí aplikace zabírat nadměrné zdroje. Sledováním aktivity vláken můžete určit takové scénáře a dokonce určit řádek kódu/metodu, která způsobuje problém.Jak je tomu v případě JVM, mnoho možností škálování a v nejnovějších verzích byla provedena bezpečnostní vylepšení. Proto se ujistěte, že používáte nejnovější verzi Tomcatu. V současné době je Tomcat 9 nejnovější verzí.
Konfigurační soubor server.xml společnosti Tomcat obsahuje několik prvků, které lze vylepšit a zvýšit tak výkon služby Tomcat.
Konfigurace konektorů
Toto jsou prvky, které umožňují Tomcatu přijímat požadavky od klientů. Jedna instance konektoru naslouchá požadavkům na určité číslo portu TCP na serveru.
Pokud na váš server Tomcat přicházejí různé typy zátěže, měli byste zvážit použití více konektorů – takže jeden typ provozu je zpracováván na jednom portu a druhý typ na jiném portu. Tím se sníží změny, které mohou různé typy úloh vzájemně ovlivňovat.Každý příchozí požadavek je zpracováván vláknem v Tomcat. Atribut maxThreads konektoru definuje maximální počet současných vláken, které lze pro konektor spustit. Počet současně spuštěných vláken závisí na hardwaru a počtu procesorů, které má. Čím lepší hardware a vyšší počet procesorů, tím větší souběžnost bude muset Tomcat podporovat.
Pokud je atribut maxThreads nastaven příliš nízko, požadavky budou muset počkat, dokud nebude vlákno dostupné pro zpracování požadavku. To může prodloužit dobu odezvy, kterou vidí uživatelé. Pro nejlepší výkon proto nastavte maxThreads na dostatečně vysokou hodnotu, aby vlákna byla v Tomcatu vždy dostupná pro zpracování příchozích požadavků.Atributy konektoru Tomcat
Z hlediska monitorování je důležité sledovat počet aktivních vláken ve fondu vláken každého konektoru. Pokud se počet aktivních vláken blíží limitu maxThreads, měli byste zvážit vyladění konfigurace serveru Tomcat tak, aby umožňovala větší fond vláken pro konektor.
Výběr protokolu konektoru pro zpracování příchozích požadavků také ovlivňuje propustnost serveru Tomcat. Tomcat 9 například podporuje blokovací a neblokující konektory. Podívejte se na tuto srovnávací tabulku.
S blokovacím konektorem, kde je spotřebováno každé pracovní vlákno, dokud není dokončeno jeho přidružené připojení. Neblokující konektor však vede k lepší správě vláken s déle běžícími požadavky. Testy výkonu naznačují, že neblokující konektor poskytuje lepší výkon s delšími požadavky.
Zvažte použití neblokujících konektorů, protože to přináší vyšší výkon.Nastavení enableLookups pro konektor určuje, zda server Tomcat provádí zpětné vyhledávání DNS, aby našel název hostitele každého vzdáleného klienta.
Vyhledávání DNS jsou drahé, a pokud je tato hodnota nastavena na hodnotu true, zpomalení služby DNS může způsobit, že to vypadá, jako by byl Tomcat pomalý. Pro nejlepší výkon proto u všech používaných konektorů nastavte enableLookups na hodnotu false.Dalším důležitým nastavením konektoru je acceptCount. Toto je maximální délka fronty přijetí, kam jsou zadávány požadavky při čekání na vlákno zpracování. Když je fronta přijetí plná, další příchozí požadavky budou odmítnuty. Výchozí hodnota 100 je pro typické produkční úlohy nedostatečná.
Pro nejlepší výkon proto musí být parametr acceptCount dostatečně velký, aby pojal množství příchozích připojení, která může server přijímat. Pokud je acceptCount příliš nízký, klienti uvidí chyby „připojení odmítnuto“. Pokud je hodnota příliš vysoká, fronta zabere další paměť serveru.Při použití konektorů NIO a NIO2 můžete nakonfigurovat velikost vyrovnávacích pamětí pro čtení a zápis soketů používaných službou Tomcat. Atributy socket.rxBufSize a socket.txBufSize řídí nastavení velikosti vyrovnávací paměti.
Čím větší je hodnota socket.rxBufSize a socket.txBufSize, tím vyšší je podporovaná propustnost. Zvažte nastavení 64 kB nebo vyšší pro tyto hodnoty.Často se mohou klienti připojovat k serveru Tomcat prostřednictvím připojení WAN. Atribut komprese řídí, zda Tomcat komprimuje obsah při jeho odesílání klientům.
Pro nejlepší výkon nastavte tento atribut na „on“. Pak se používá komprese GZIP. Typy obsahu, které by měly být komprimovány, jsou uvedeny v komprimovatelnémMimeType.Jakoukoli komunikaci mezi klientem a serverem, která je primárně textová, ať už jde o HTML, XML nebo jednoduše Unicode, lze pravidelně komprimovat až na 90 % pomocí jednoduchého a standardního algoritmu GZIP. To může mít obrovský dopad na snížení síťového provozu, což umožňuje mnohem rychlejší odesílání odpovědí zpět klientovi a zároveň umožňuje větší šířku pásma sítě, která je k dispozici pro jiné aplikace s velkým zatížením sítě.
Použití Exekutorů
Při použití konektorů je každému konektoru vyhrazena skupina vláken. Pokud používáte více konektorů, můžete nakonfigurovat exekutor. Exekutor je společný fond vláken, který může být sdílen více konektory. Nejen, že to umožňuje lepší sdílení vláken mezi konektory, ale také poskytuje mechanismus pro snížení počtu vláken ve fondu, pokud by příchozí pracovní zátěž tato vlákna ke zpracování nevyžadovala. Při použití fondu vláken na konektor Tomcat neuvolňuje vlákna ve fondu, takže pokud jednou zaznamenáte velký nárůst požadavků, může to zvýšit počet vláken ve fondu po celou dobu životnosti serveru Tomcat. Při použití exekutoru je nastavení maxThreads definováno na úrovni exekutora. V takovém případě musí správci Tomcatu sledovat aktivitu a využití fondu vláken na úrovni exekutora, nikoli na úrovni konektoru.
Konfigurace veřejných certifikátů SSL
Pokud je váš konektor povolen SSL, ujistěte se, že jste jej nakonfigurovali s platným veřejným certifikátem SSL.Podívejte se na tento blog, abyste porozuměli výkonu, který může mít nesprávná konfigurace certifikátu SSL na výkon Tomcat.
Vylaďte nastavení ukládání zdrojů do mezipaměti
Pro zlepšení výkonu je Tomcat ve výchozím nastavení nakonfigurován na ukládání statických zdrojů do mezipaměti. Velikost mezipaměti však musí být nakonfigurována tak, aby byla dostatečně velká pro úsporu výkonu.
Chcete-li vyladit nastavení mezipaměti Tomcatu, vyhledejte direktivu Context (v server.xml nebo context.xml) a nastavte atribut cacheMaxSize na příslušnou hodnotu.Sdružování připojení k databázi
Otevření připojení k databázi jsou drahé. Sdružování připojení je běžnou technikou pro optimalizaci přístupů k databázi tím, že má fond otevřených připojení, takže požadavky mohou přebírat připojení z fondu a vracet připojení zpět do fondu, jakmile dokončí své úkoly. Tím, že není nutné vytvářet a rušit připojení pro každý požadavek, umožňuje sdružování připojení rychlejší odezvu aplikací a snižuje režii na zpracování připojení na databázovém serveru. Tomcat má vestavěnou podporu pro sdružování databázových připojení.
Stejně jako v případě fondů vláken zajistěte, aby bylo nastavení fondu databázových připojení maxActive, které definuje, zda je maximální počet aktivních připojení ve fondu dostatečně velký, aby se přizpůsobil pracovní zátěži, kterou zpracovává. Monitorujte využití fondu připojení k databázi, protože pokud připojení fond je plně využit, nové požadavky budou čekat, až budou k dispozici volná připojení, což způsobí prodloužení doby odezvy.Optimalizace Web.xml
Soubor server.xml se používá k určení konfigurací specifických pro server. Pro každou instanci serveru Tomcat existuje pouze jeden server.xml. Soubor web.xml se používá k určení konfigurací specifických pro webovou aplikaci. Pro každou webovou aplikaci nasazenou na serveru Tomcat existuje jeden soubor web.xml. Výchozí nastavení zděděná všemi webovými aplikacemi jsou definována souborem web.xml v hlavním konfiguračním adresáři Tomcat.
Výchozí hodnoty vlastností v tomto souboru jsou vyladěny pro vývojová prostředí a je třeba je upravit pro produkční nasazení. Nastavení kompilátoru Java Server Pages (JSP) má nastavení režimu vývoje. To je ve výchozím nastavení pravda. Změňte toto na false, abyste se vyhnuli časté kontrole JSP, abyste zjistili, zda je nutná rekompilace. Předkompilujte JSP, abyste se vyhnuli režii kompilace na produkčních serverech. Podobně nastavte genStringAsCharArray na „true“, abyste vytvořili efektivnější pole znaků. Chcete-li odstranit nepotřebné, nastavte trimSpaces na „true“. bajtů z odpovědi.Neefektivní kód aplikace může také způsobit, že aplikace nasazená na Tomcat bude pomalá. Protokolování je běžný způsob sledování provozu aplikace. Protokolování do výstupních souborů je synchronizovaná operace a nadměrné protokolování může ve skutečnosti zpomalit výkon aplikace.
Použijte techniky trasování transakcí, které jsou založeny na instrumentaci bajtového kódu, abyste mohli sledovat zpracování aplikací, aniž byste museli měnit kód aplikace. Tyto techniky se spoléhají na speciálně vytvořený soubor jar, který využívá instrumentační rozhraní API, které JVM poskytuje ke změně existujícího bajtového kódu, který je načten v JVM.
Týmy IT a vývojáři mohou tuto schopnost využít k prohloubení pomalých transakcí a proaktivně detekovat problémy s výkonem dříve, než budou mít dopad na koncové uživatele.
Distribuované trasování transakcí používané k identifikaci problémů na úrovni kódu ve webových aplikacích využívajících Tomcat
Často můžete slyšet, že aplikační servery založené na Javě, jako je Tomcat, jsou pomalé nebo nejsou připraveny na produkci. V tomto blogu jsme poskytli řadu konfigurací osvědčených postupů, které vám pomohou co nejlépe využít váš webový aplikační server Tomcat. Naše řešení pro monitorování výkonu aplikací eG Enterprise využívá Apache Tomcat jako hlavní kontejnerový engine a bylo široce nasazeno na podporu monitorování desítek tisíc serverů, desítek milionů metrik v reálném čase a více než sto tisíc koncových uživatelů ve výrobě. Můžete si tedy být jisti, že osvědčené postupy, které jsme zde uvedli, skutečně fungují!