Platforma Azul Prime je založena na open-source zdrojovém kódu OpenJDK, což je referenční implementace pro standard Java SE. Aby Azul poskytoval lepší výkon než tradiční JVM, nahrazuje části jádra JVM alternativními implementacemi. Konkrétně se jedná o systém správy paměti a část kompilačního systému Just in Time (JIT). Platform Prime vylepšuje výkon mikroslužeb založených na Javě třemi způsoby:
- Rychlejší zahřívání s ReadyNow
- Zkrácená doba zahřívání díky kompilátoru Cloud Native Compiler
- Méně pauz s odvozem odpadu C4
Rychlejší JIT kompilace zlepšuje výkon
Zdrojový kód Javy je kompilován do bajtkódů. Bajtkódy jsou instrukce pro virtuální stroj Java (JVM). Když JVM spustí aplikaci, musí interpretovat každý bajtkód a převést ho na potřebné nativní instrukce a volání operačního systému. Tato interpretace představuje režijní náklady, které způsobují, že kód běží mnohem pomaleji než staticky kompilovaný kód.
Aby se tento problém eliminoval, JVM profiluje kód při interpretaci bytkódů a počítá, kolikrát jsou metody volány. JVM používá tato profilovací data k identifikaci aktivních míst v kódu, která lze kompilovat do nativních instrukcí pomocí kompilátoru just in time (JIT). Postupem času bude většina kódu spuštěného aplikací zkompilována, ale doba potřebná k dosažení tohoto bodu se nazývá zahřívací doba aplikace.
| O JIT kompilátorech |
|---|
Tradiční JVM používá dva JIT kompilátory nazývané C1 a C2 (někdy označované jako klient a server). Každý JIT má charakteristické vlastnosti, které určují výkon aplikace.
|
Od verze JDK 7 lze oba JITy použít pro stejnou aplikaci prostřednictvím vrstvené kompilace. C1 se používá zpočátku; C2 se používá, když aplikace běží déle, aby se zvýšil výkon.
Platforma Azul Prime nahrazuje C2 JIT novou, vylepšenou verzí s názvem Falcon [obrázek 1]. Kompilátor Falcon JI je založen na projektu kompilátoru LLVM s otevřeným zdrojovým kódem, který je podporován řadou společností a jednotlivců, včetně společností Intel, NVidia, Apple a Sony.

1. Zkraťte dobu zahřívání s ReadyNow
Problém zahřívání aplikace je zhoršen skutečností, že při každém spuštění aplikace JVM neví, co se mohlo stát během předchozích spuštění. JVM musí projít stejnou fází profilování, provádět stejnou analýzu a kompilovat stejné části kódu. U aplikací, které je třeba často restartovat, je to problematické.
Zřejmým způsobem řešení tohoto problému by bylo pořídit snímek kompilovaného kódu, jakmile aplikace dosáhne ustáleného stavu a veškerý potřebný kód bude zkompilován. Po restartu aplikace by se tento snímek mohl znovu načíst a aplikace by mohla pokračovat, jako by se nezastavila (z hlediska kompilace). Bohužel to tak jednoduché není (implementace by byla ve skutečnosti složitá, i když to zní jednoduše). Definice JVM klade omezení na to, co se může stát při jeho spuštění, konkrétně při načítání a inicializaci tříd. Několik dalších problémů činí tento přístup nepraktickým.
Funkce ReadyNow, která je součástí Azul Platform Prime, urychluje zahřívání aplikací v produkčním prostředí od samého začátku. V tomto okamžiku se zaznamená profil stavu JIT aplikace. Tento profil zaznamenává podrobnosti o aktuálně načtených třídách, inicializovaných třídách, datech profilování instrukcí (například data používaná JVM k rozhodování o tom, které části kódu kompilovat) a spekulativních selháních optimalizace. Ukládá se také kopie kompilovaného kódu.
Když se aplikace znovu spustí, použije profil k tomu, aby JVM a JIT provedly veškerou práci, kterou by normálně dělaly během zahřívací fáze aplikace; v tomto případě se to vše může stát ještě předtím, než aplikace začne provádět kód v metodě main(). Tím se zahřívací fáze prakticky eliminuje, takže aplikace může při spuštění běžet téměř plnou rychlostí [obrázek 1].

2. Další zkrácení doby zahřívání pomocí kompilátoru Cloud Native Compiler
JIT kompilace poskytuje výkon nezbytný pro moderní podnikové aplikace a často překonává nativně kompilovaný kód, ale výkon má svou cenu. Pracovní zátěž JIT kompilace musí sdílet zdroje s aplikací, aby mohla provádět transakce, což prodlužuje dobu zahřívání a snižuje výkon aplikace během zahřívání.
Pokud běžíme v cloudu s jeho elastickými zdroji a cenovým modelem založeným na užitných hodnotách, proč nepřesunout práci JIT kompilátoru jinam?
Tohle Azul udělal s kompilátorem Cloud Native Compiler.
Cloud Native Compiler vytváří centralizovanou JIT-as-a-service [obrázek 2]. Když JVM potřebuje kompilovat metodu, místo aby to dělal lokálně, odešle podrobnosti do Cloud Native Compiler. To umožňuje větší propustnost během zahřívání. Cloud Native Compiler může být také proces spouštějící protokol, který ukládá výsledky z kompilací metod. Při spouštění více instancí mikroslužby, když je požadována stejná metoda, namísto její opětovné kompilace lze uložený kód okamžitě vrátit, což dále zkracuje dobu zahřívání.
3. Méně pauz s odvozem odpadu C4
Když je spuštěna Java aplikace, JVM automaticky zvládá správu paměti. JVM alokuje prostor na haldě, když je vytvořena instance nového objektu, a tento prostor uvolní, když na něj aplikace již nemá žádné odkazy. Jedná se o proces garbage collection (GC). GC také spravuje haldu a optimalizuje dostupnost prostoru pro nové objekty periodickým zhutňováním haldy, přesouváním objektů tak, aby živá data byla souvislá, a eliminuje tak fragmentaci. GC poskytuje významné výhody oproti jazykům jako C a C++, které se spoléhají na to, že programátor explicitně uvolní prostor používaný aplikací. Toto explicitní uvolňování může být zdrojem mnoha chyb aplikací, zejména v podobě úniků paměti nebo náhlého ukončení aplikace, když se programátor pokusí uvolnit neplatnou nebo nesprávnou adresu.
V tradičním JVM však GC také vyžaduje, aby se aplikační vlákna pozastavila, aby se zabránilo poškození dat při přesunu objektů během komprimace. Tento efekt je dvojí: za prvé, zavádí do aplikace pauzy, zatímco GC vykonává svou práci. Délka těchto pauz se může pohybovat od milisekund do hodin a je přímo úměrná množství paměti přidělené haldě, nikoli množství dat v haldě.
Platforma Azul Prime používá jiný algoritmus GC, Continuous Concurrent Compacting Collector (C4). Na rozdíl od jiných komerčních algoritmů GC mohou aplikační vlákna pokračovat v provozu, zatímco GC vykonává svou práci (odtud část názvu „concurrent“).
Za druhé, nelze přesně předpovědět, kdy k těmto pauzám dojde. To zavádí do aplikace nedeterministické chování. V kontextu mikroslužby by to mohlo vést k tomu, že klienti služby budou mylně předpokládat, že služba již není k dispozici, přestože její JVM právě pracuje na GC. To může způsobit spuštění nových instancí služby, což dále ovlivňuje výkon, pokud to není nutné.
Ačkoli jiné algoritmy, jako například Concurrent Mark Sweep (CMS) a Garbage First (G1), vykonávají část své práce za chodu aplikačních vláken, jiné části stále vyžadují, aby aplikační vlákna byla pozastavena. Oba tyto algoritmy se vrátí k cyklu úplného zhutňování, pokud nejsou schopny uspokojit paměťové potřeby aplikace. Toto úplné zhutnění vyžaduje doby pozastavení aplikace úměrné velikosti haldy.
Na rozdíl od tradičních kolektorů, které vyžadují řadu možností příkazového řádku, jež je obtížné správně konfigurovat, C4 vyžaduje nastavení pouze velikosti haldy. C4 škáluje od 1 GB do 20 TB prostoru haldy bez prodlužování doby pauzy aplikace.
Shrnutí
Vývoj softwaru se přesouvá do cloudu a k tomu se využívají mikroslužby flexibilním a škálovatelným způsobem. Java, jako nejoblíbenější programovací jazyk na světě, je pro vývoj mikroslužeb zřejmou volbou. Mikroslužby Java také poskytují oproti těm, které jsou vyvíjeny v jiných jazycích, několik výhod. Azul Platform Prime zahrnuje moderní JVM, které používá různé interní algoritmy pro sběr odpadu a je součástí systému kompilace JIT. V kombinaci s technologií ReadyNow, která efektivně eliminuje zahřívací fázi výkonu mikroslužeb, se Azul Platform Prime stává perfektní volbou pro použití v moderním vývoji aplikací v Javě na mikroslužbách.

