Tema evenimentului de lansare a al numărului 97 / august 2020 a revistei a fost Java Performance. Am avut o discuție interesantă legată de acest subiect cu:
Denis Polivanov: La compania unde lucrez, inițiez direcțiile noi de dezvoltare și mă axez pe menținerea nivelului de performanță necesar aplicațiilor să facă față oricărei provocări. Aleg direcția de dezvoltare după ce selectez un sistem scalabil (Kubernetes, Kafka). Uneori, trebuie să intru în detalii (CPU, procesare de date, tehnologii). Principala mea responsabilitate este de a scrie cod Java. Sunt un programator și un arhitect care iubește să lucreze practic.
Cătălin Roman: Lucrez la Frequentis care contruiește soluții software și hardware pentru gestionarea traficului aerian, a siguranței publice, a apărării. Recent, am fost promovat pe poziția de Lead Software Architect. Momentan, lucrez la un proiect numit EAD (European Aeronautical Database) pentru EUROCONTROL, agenția europeană pentru control aeronautic. EAD este un sistem de gestionare a conținutului în domeniul aeronautic. Cu alte cuvinte, este un centru de date care face agregări de informații precum rute aeriene, baze disponibile, nivele de zbor și nu numai. Lucrez cu mai multe echipe pe care le ajut în secțiunea de arhitectură. Anul trecut, am câștigat un premiu pentru un proiect complex pe care l-am realizat pentru o companie aeriană (Quantas Airways). A fost rezultatul unui efort comun depus de mai multe companii care au lucrat la o soluție nouă de planificare a zborurilor. Aplicația trebuia să calculeze rute eficiente la nivel de consum de combustibil.
Ovidiu Mățan: Toți programatorii au fost influențați de Java la un moment dat. Cât de mult a influențat acest lucru modul în care abordați celelalte limbaje de programare? Cum au evoluat cunoștințele voastre de Java?
Denis Polivanov: Java are o istorie bogată. La un moment dat, credeam că Java va deveni învechită, dar recent, dezvoltarea Java a devenit mai dinamică. Funcționalitățile noi sunt lansate din ce în ce mai des. Îmi place cum a evoluat Java. Datorită unor funcționalități precum garbage collector sau librăriilor de infrastructură, Java se va menține ca limbaj de programare enterprise mulți ani de acum înainte. Am fost și sunt încă interesat de Rust. C++ și Rust s-au influențat reciproc. De asemenea, când a apărut Scala, Java a fost influențată de aceasta. Una din marile realizări Java a fost Java Memory Model care a analizat deprecierea memoriei în mediile cu concurență înaltă. Ce a făcut C++? A introdus un model de memorie. Prin urmare, vedem cum lucrurile se influențează unele pe altele. Funcționalitățile cele mai bune sunt moștenite de celelalte limbaje de programare.
Cătălin Roman: Când am început să lucrez ca programator, am folosit C++. Eram membru al unei echipe mici de C++, într-un birou în care se afla o mare echipă Java. Ovidiu, tu erai în echipa Java. Mi-a plăcut să lucrez cu C++, dar auzeam tot felul de lucruri interesante de la echipa Java. Am devenit curios și am făcut tranziția spre Java. Java integrează microtehnologii din diverse limbaje de programare, ceea ce este foarte bine. Totuși, lucrând momentan în domeniul aeronautic, observ că aici lucrurile noi sunt adoptate cu mai multă prudență. De exemplu, o funcționalitate este adoptată doar după câțiva ani de maturitate. E interesant să studiem ce apare pe piață și ce ne face mai productivi.
Domeniile voastre necesită performanță înaltă. Ce efect are acest lucru asupra arhitecturii sistemului?
Denis Polivanov: Când realizăm specificațiile pentru un proiect, trebuie să acordăm o atenție sporită specificațiilor non-funcționale - latența, scalabilitatea, permanența (high availability). Acest lucru trebuie efectuat de la bun început. Performanța înaltă aduce complexitate în sistem, ceea ce înseamnă că efortul investit într-o arhitectură corectă e semnificativ. De exemplu, chiar și o diferență precum cea dintre milisecunde și nanosecunde modifică complet abordarea.
Cătălin Roman: Şi eu analizez foarte atent specificațiile non-funcționale. Performanța trebuie inclusă devreme în arhitectură. De multe ori, folosim lucruri precum arhitectură bazată pe evenimente sau tehnologii non-blocking. Folosim și multe in-memory data grids. Performanța este importantă, dar nu e singura. Siguranța joacă și ea un rol important. De exemplu, programul software folosit de un lift este complet diferit de cel dintr-o carlingă de avion sau de cel dintr-o soluție e-commerce.
Există cerințe speciale pentru hardware-ul pe care rulați software-ul?
Denis Polivanov: În ceea ce privește hardware-ul, cel general disponibil, nu cel din aeronave, ci din domeniul finanțelor, folosim cele mai rapide CPU-uri și rețele, ultimele apărute pe piață. Viteza este foarte importantă. Facem upgrade la hardware destul de des. Pentru high-frequency trading, puteți asambla hardware-ul care poate fi extrem de rapid.
Cătălin Roman: În aviație, presiunea nu este atât de mare la nivel de performanță. Nu folosim hardware puternic optimizat, dar facem deployment în cloud, AWS sau Azure. Folosim elastic load balancer sau auto-scaling groups. Un lucru interesant pe care l-am aflat legat de hardware deployment este că Departamentul American de Apărare rulează clustere Kubernetes pe avioanele F16. Ştiu că folosesc Java și Go, dar nu știu ce aplicații rulează. Evident, au nevoie de redundanță. Redundanța e importantă în domeniul nostru. Folosim configurații precum activ-activ sau activ-stand by etc. High availability vine pe primul loc, iar performanța pe loc secund.
Folosiți și microservicii?
Cătălin Roman: Da și nu. Entuziasmul a fost mare când microserviciile au fost introduse anii trecuți. Chiar și așa, autorii care au scris cărți despre microservicii și-au mai revizuit opiniile după ce au constatat ce presupune mentenanța ecosistemelor cu sute de microservicii în producție. Microserviciile funcționează până la un punct, dar cu cât crește numărul microserviciilor, cu atât crește complexitatea. Recent, am întâlnit termenul "jumbo service", care nu e nici monolit, nici microserviciu, ci ceva la mijloc. Când procesele sunt distribuite pe mai multe mașini ce trebuie să comunice unele cu altele, trebuie serializate datele, comunicate, ceea ce implică latență. Sunt curios cum sunt abordate microserviciile în trading?
Denis Polivanov: Sincer, cred că adevărul e undeva la mijloc. Oamenii cred că dacă ai microservicii, ai de fapt microservicii REST, ce sunt apoi convertite sau serializate în șiruri JSON strings, dar acest lucru consumă mult CPU în funcție de numărul de microservicii. Nu folosim microserviciile foarte mult. Pentru unele taskuri, folosim Kubernetes, dar serviciile pe care le folosim corespund unei singure funcționalități și nu separăm lucrurile dacă nu este necesar. Prețul orchestrării componentelor este mare atunci când se face deploymentul.
Folosiți un server de aplicație, un server web sau comunicare direct TCP/IP?
Denis Polivanov: Pentru a face optimizări, inginerii trebuie să se detașeze și să privească lucrurile în ansamblu, deoarece, uneori, presupunem lucruri incorecte. Imaginați-vă că aplicația voastră este o conductă enormă și că există legături între conducte. Identificați blocajele. Odată ce ați identificat blocajul, puteți rezolva problemele. Nu faceți presupuneri. După ce ați identificat problema, analizați-o în detaliu. Recomand folosirea JFR (Java Flight Recorder) ce vă permite să profilați sistemele din producție. Poate colecta informații utile despre aplicație, în special atunci când sunt probleme.
Cătălin Roman: Sunt de acord cu Denis. Optimizarea prematură este cauza tuturor relelor. Folosiți un profiler și analizați rezultatele.
Cum se compară Java cu alte limbaje de programare? Ce alte limbaje de programare studiați?
Cătălin Roman: Sunt atras de Scala, dar a rămas la nivel de pasiune, în principal datorită curbei de învățare și termenelor limită pe care le avem cu toții. Functional Programming este interesantă uneori. În cele din urmă, nu este vorba neapărat de limbajul de programare folosit, ci de tehnicile folosite, lucruri precum arhitectura bazată pe evenimente sau tehnologii non-blocking.
Denis Polivanov: În mediul de producție folosesc Java, dar sunt pasionat de Rust. Încercați-l pentru o experiență inedită.
Ce cărți recomandați pentru o mai bună înțelegere a performanței?
Cătălin Roman: Începătorii pot citi două cărți: Java Performance sau Java Performance Tuning. Apoi, puteți citi Designing Data-Intensive Applications. Aceste cărți vă vor învăța lucruri de bază.
Denis Polivanov : Cărțile vă învață lucrurile de bază, dar pentru aprofundare, trebuie să ascultați prelegeri la conferințe și să citiți postări sau bloguri. Puteți urmări forumul Google aferent grupului Mechanical Sympathy.