Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Best Practices 
Java und JVM in Containern

19 Aufrufe

Veröffentlicht am

■Basics, die nichts mit Java/JVM zu tun haben aber wichtig sind ■Java und der Speicher ■Java und die CPU ■Java und Images
Vortrag auf dem Berlin Experte Day 2019

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

Best Practices 
Java und JVM in Containern

  1. 1. © OPITZ CONSULTING 2019 Best Practices 
 Java und JVM in Containern BEDCon 2019 Dr. Halil-Cem Gürsoy OPITZ CONSULTING
 
 @hgutwit
  2. 2. © OPITZ CONSULTING 2019 $ whoami | xargs finger ■Senior Solution Architect @ OPITZ CONSULTING ■Seit 20 Jahren in der Java-Welt ■ davor im wissenschaftlichen Umfeld Pascal, C, Lisp, Prolog… ■Verteilte Enterprise Systeme ■ Build, Deployment & Persistenz ■„DevOps“, Infrastructure as Code, Automatisierung…
  3. 3. © OPITZ CONSULTING 2019 Eine lange Docker-Reise ■Seit Docker 0.8 (2014) produktiv mit Docker unterwegs ■Build & Testumgebungen für große agile Teams ■ Java/JEE, Testcluster, Datenbanken (NoSQL, RDBMS) ■Continuous Delivery mit Docker ■ Jenkins, Atlassian Bamboo, Docker Swarm, Kubernetes … ■ …aber bekennend "Kubephob" (Konfrontations-Therapie)
  4. 4. © OPITZ CONSULTING 2019 Agenda ■Basics, die nichts mit Java/JVM zu tun haben aber wichtig sind ■Java und der Speicher ■Java und die CPU ■Java und Images ■Noch sparsamer, noch schneller
  5. 5. © OPITZ CONSULTING 2019 Warum gerade Java? https://www.tiobe.com/tiobe-index/
  6. 6. © OPITZ CONSULTING 2019 Warum gerade Java? https://redmonk.com/rstephens/2019/07/18/top20-june-2019/
  7. 7. © OPITZ CONSULTING 2019 –Wladimir Iljitsch Lenin „Доверяй, но проверяй“
  8. 8. © OPITZ CONSULTING 2019 Base Images ■Ideal-Welt: wir bauen unsere Base-Images FROM scratch ■ kann sehr aufwendig sein, aber Kontrolle über den Inhalt ■Möglichst mit offiziellen Images starten ■Sicherheitsupdates beachten, regelmäßig bauen
  9. 9. © OPITZ CONSULTING 2019 Base Images ■möglichst nur eine oder wenige Linux-Distributionen auswählen ■minimales System nutzen: 
 nur die Pakete, die notwendig sind, nachvollziehbar installieren ■--entrypoint sollte die eigentliche Applikation aufrufen ■… aber auch ein docker run myimage:1 bash erlauben ■Weitere Hinweise im Github-Repo docker-library/official-images
  10. 10. © OPITZ CONSULTING 2019https://www.flickr.com/photos/clement127/15914534662 latest is Evil!
  11. 11. © OPITZ CONSULTING 2019 Deployment? ■Container sollten nicht wie VM’s „provisioniert“ werden ■Anti-Pattern: ■ Container mit Application Server wird gestartet… ■ …und Applikation wird in den laufenden App-Server deployed ■Reproduzierbar?
  12. 12. © OPITZ CONSULTING 2019https://www.flickr.com/photos/vanmelis/14920357394
  13. 13. © OPITZ CONSULTING 2019 https://www.flickr.com/photos/mac_users_guide/3665683020
  14. 14. © OPITZ CONSULTING 2019 Java & glibc ■glibc’s malloc() reserviert 64Mb-Blöcke („Arenas“) ■ Virtual Adress space, u.a. Java Metaspace, Threads usw. ■(Fast) kein Problem bis zur Verwendung von mlockall() ■ „Arenas“ werden dann tatsächlich gemappt ■ElasticSearch, Apache Cassandra (via JNA) ■ Optionale Konfiguration zur Swap-Vermeidung ■Diverse Bug-Einträge, u.a. JDK-8193521
  15. 15. © OPITZ CONSULTING 2019 Java & glibc ■MALLOC_ARENA_MAX auf niedrigen Wert setzen ■ Vorsicht wenn SELinux im Einsatz ist! ■ Default: 8 * CPU-Kerne ■Ausprobieren und messen! ■Swap disablen statt JNA/mlockall
  16. 16. © OPITZ CONSULTING 2019https://www.flickr.com/photos/venndiagram/5331296718
  17. 17. © OPITZ CONSULTING 2019 Java Heap docker run -m 256m --rm openjdk:8u111-jdk java -XX:+PrintFlagsFinal -version |grep -i heapsize | egrep 'Initial|Max' openjdk version "1.8.0_111" OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-2~bpo8+1-b14) OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode)     uintx InitialHeapSize                          := 65011712     uintx MaxHeapSize                              := 1035993088
  18. 18. © OPITZ CONSULTING 2019 Java Heap docker run -m 256m --rm openjdk:8-jdk java -XX:+PrintFlagsFinal -version | grep -i heapsize | egrep 'Initial|Max' openjdk version "1.8.0_222" OpenJDK Runtime Environment (build 1.8.0_222-b10) OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)     uintx InitialHeapSize                          := 8388608     uintx MaxHeapSize                              := 132120576
  19. 19. © OPITZ CONSULTING 2019 Neue Optionen ab 8u191* ■JDK-8196595: 
 --XX:[+|-]UseContainerSupport (default: +) ■JDK-8186248: ■ -XX:InitialRAMPercentage, -XX:MaxRAMPercentage
 -XX:MinRAMPercentage ■ ersetzen:
 -XX:InitialRAMFraction, -XX:MaxRAMFraction
 -XX:MinRAMFraction ■ Genaue Berechnungsformeln im Code
  20. 20. © OPITZ CONSULTING 2019 Min / Max Heap docker run -m 1024m --rm openjdk:12.0.2-jdk java -XX:+PrintFlagsFinal - version | grep -E "UseContainerSupport | MaxRAMPercentage | MinRAMPercentage"    double MaxRAMPercentage                       = 25.000000    double MinRAMPercentage                       = 50.000000      bool UseContainerSupport                    = true docker run -m 1024m --rm openjdk:12.0.2-jdk java -XshowSettings:vm -version VM settings:     Max. Heap Size (Estimated): 247.50M     Using VM: OpenJDK 64-Bit Server VM docker run -m 1024m --rm openjdk:12.0.2-jdk java -XX:MaxRAMPercentage=75.0
 -XshowSettings:vm -version VM settings: Max. Heap Size (Estimated): 742.44M Using VM: OpenJDK 64-Bit Server VM
  21. 21. © OPITZ CONSULTING 2019https://www.flickr.com/photos/lemsipmatt/2894816411/
  22. 22. © OPITZ CONSULTING 2019 CPU-Limits ■Ab Java 9 / 10 werden Docker CPU-Limits berücksichtigt ■ --cpuset-cpus, --cpus / --cpu-quota, --cpu-period,
 --cpu-shares ■–XX:PreferContainerQuotaForCPUCount (default true) ■Alternativ/Manuell: –XX:ActiveProcessorCount
  23. 23. © OPITZ CONSULTING 2019 CPU-Limits echo 'Runtime.getRuntime().availableProcessors()' | 
 docker run -i --rm openjdk:12.0.2-jdk jshell jshell> Runtime.getRuntime().availableProcessors() $1 ==> 4 echo 'Runtime.getRuntime().availableProcessors()' | 
 docker run --cpus 1 -i --rm openjdk:12.0.2-jdk jshell jshell> Runtime.getRuntime().availableProcessors()
 $1 ==> 1
  24. 24. © OPITZ CONSULTING 2019https://www.flickr.com/photos/digimeister/16138848190
  25. 25. © OPITZ CONSULTING 2019 Ein hochkomplexes Beispiel
  26. 26. © OPITZ CONSULTING 2019 Java Images $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE hellojava 3 7733be0c7852 About a minute ago 390MB debian stretch-slim 220611111e8c 2 weeks ago 55.3MB openjdk 12.0.2-jdk e1e07dfba89c 2 weeks ago 470MB
  27. 27. © OPITZ CONSULTING 2019 Auf Diät… ■Ab Java 9 haben wir JDK-Module zur Verfügung ■Es sollten nur die benötigten Module der JRE in das Image ■Mit Hilfe von jlink kann eine angepasste JRE erzeugt werden ■ Mit jdeps kann Liste der benötigten Module erzeugt werden
  28. 28. © OPITZ CONSULTING 2019 Auf Diät…
  29. 29. © OPITZ CONSULTING 2019 Slim… docker images | grep hello hellojava slim-1 0f67adf4b101 5 minutes ago 92.1MB hellojava 3 7733be0c7852 51 minutes ago 390MB
  30. 30. © OPITZ CONSULTING 2019 Da geht noch was! ■Projekt Portola migriert die OpenJDK von glibc auf musl ■musl ist eine schlanke Implementierung der libc für Alpine Linux ■Early Access von OpenJDK für Alpine/musl: 
 http://jdk.java.net/14/ ■Alpine/musl mit java.base ca. 51 Mb!
  31. 31. © OPITZ CONSULTING 2019https://www.flickr.com/photos/grepsy/6993325519/
  32. 32. © OPITZ CONSULTING 2019 AppCDS ■In 8u40 als kommerzielles Feature eingeführt ■Option -XX:+UseAppCDS in JDK 11 obsolet erklärt und in 12 entfernt, da nun „default“ ■Interne Repräsentation der Applikations-Klassen in memmory-mapped files ■Schnelleres Laden bei großen Servern/Applikationen und kleineres memory Footprint ■ Beispiele mit WebLogic usw. ca. 10% - 20% schneller ■ Bei „einfachen“ / kleinen Applikationen kein besonderer Effekt
  33. 33. © OPITZ CONSULTING 2019 AppCDS
  34. 34. © OPITZ CONSULTING 2019 AOT statt JIT-Compiler ■Ähnlich der AppCDS wird im Vorfeld eine Shared Library erzeugt ■Es erfolgt zur Laufzeit keine Optimierung durch HotSpot ■Macht Sinn bei kurz laufenden Java-Prozessen ■ … z.B. bei Functions mit Java (Fn, OpenFaaS, …) ■Stolperfalle: Shared Library kann sehr groß werden ■ Selektiv die verwendeten Klassen compilieren
  35. 35. © OPITZ CONSULTING 2019https://www.flickr.com/photos/jdlasica/698202275/
  36. 36. © OPITZ CONSULTING 2019 GraalVM ■„…is a universal virtual machine for running applications written in JavaScript, Python, Ruby, R, JVM-based languages like Java, Scala, Groovy, Kotlin, Clojure, and LLVM-based languages such as C and C++.“ https://www.graalvm.org
  37. 37. © OPITZ CONSULTING 2019 GraalVM
  38. 38. © OPITZ CONSULTING 2019 GraalVM
  39. 39. © OPITZ CONSULTING 2019 GraalVM Step 5/8 : RUN native-image HelloJava ---> Running in ca6f04a96def Build on Server(pid: 32, port: 38449)* [hellojava:32]    classlist:   1,477.66 ms [hellojava:32]        (cap):     890.19 ms [hellojava:32]        setup:   1,932.33 ms … [hellojava:32]      compile:   6,405.54 ms [hellojava:32]        image:     502.27 ms [hellojava:32]        write:     109.88 ms [hellojava:32]      [total]:  20,302.07 ms root@b914b8045203:/# ls -lh total 5.5M drwxr-xr-x   2 root root 4.0K Aug 12 00:00 bin drwxr-xr-x   2 root root 4.0K Mar 28 09:12 boot drwxr-xr-x   5 root root  360 Sep  4 20:30 dev drwxr-xr-x   1 root root 4.0K Sep  4 20:30 etc -rwxr-xr-x   1 root root 5.4M Sep  4 20:24 hellojava
  40. 40. © OPITZ CONSULTING 2019 GraalVM ■Aktuell noch „Probleme“ mit Reflection und Proxies ■"Spring Framework provides initial support for GraalVM native images as of 5.1.“ ■Andere Frameworks wie Micronaut sind da besser vorbereitet
  41. 41. © OPITZ CONSULTING 2019http://www.flickr.com/photos/an_untrained_eye/6630719431
  42. 42. © OPITZ CONSULTING 2019 https://www.flickr.com/photos/tcmorgan/7372944070 @OC_WIRE OPITZCONSULTING opitzconsulting opitz-consulting-bcb8-1009116 WWW.OPITZ-CONSULTING.COM

×