Lessons Learned: Java EE Webstack Performance

82
Lessons Learned Java EE Webstack Performance Jens Schumann | open knowledge GmbH

description

Speaker: Jens Schumann JAX 2013 23.4.2013 Performante Java-EE-6-Webanwendungen? Kein Problem! Doch auch für JSF2/CDI-Anwendungen gilt, dass kleinste Details enorme Auswirkungen haben können. Dies betrifft natürlich stark dynamische Inhalte, insbesondere aber den Einsatz von Ajax und Partial Rendering, EL API 2.2 Features und Composite Components. Worauf man grundsätzlich achten sollte und was unbedingt zu vermeiden ist, zeigt diese Session.

Transcript of Lessons Learned: Java EE Webstack Performance

Page 1: Lessons Learned: Java EE Webstack Performance

Lessons Learned Java EE Webstack Performance

Jens Schumann | open knowledge GmbH

Page 2: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

Web Entwicklung aus der Brille eines Java EE Entwicklers!

!

- The Backend-Tier Part -!

Page 3: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

public List<Order> findTodaysOrders(...) { Calender cal = Calender.getInstance(); cal.set(Calendar.HOUR, 0); ... if (LOG.isDebugEnabled()) { // log method request details } List<Order> result = repository.findOrdersByDate(cal.getTime); if (LOG.isDebugEnabled()) { // log result details } return result; }

Page 4: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

public List<Order> findTodaysOrders(...) { Calender cal = Calender.getInstance(); cal.set(Calendar.HOUR, 0); ... if (LOG.isDebugEnabled()) { // log method request details } List<Order> result = repository.findOrdersByDate(cal.getTime); if (LOG.isDebugEnabled()) { // log result details } return result; }

Page 5: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

public List<Order> findTodaysOrders(...) { Calender cal = Calender.getInstance(); cal.set(Calendar.HOUR, 0); ... if (LOG.isDebugEnabled()) { // log method request details } List<Order> result = repository.findOrdersByDate(cal.getTime); if (LOG.isDebugEnabled()) { // log result details } return result; }

Page 6: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

public List<Order> findTodaysOrders(...) { Calender cal = Calender.getInstance(); cal.set(Calendar.HOUR, 0); ... if (LOG.isDebugEnabled()) { // log method request details } List<Order> result = repository.findOrdersByDate(cal.getTime); if (LOG.isDebugEnabled()) { // log result details } return result; }

Page 7: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

Web Entwicklung aus der Brille eines Java EE Entwicklers!

!

- The Web-Tier Part -!

Page 8: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

@Named @SessionScoped public class OrderOverviewBean() { @Inject private OrderService service; private List<Order> orders; @PostConstruct protected void init() { orders = service.findTodaysOrders(...) } }

Page 9: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

@Named @SessionScoped public class OrderOverviewBean() { @Inject private OrderService service; private List<Order> orders; @PostConstruct protected void init() { orders = service.findTodaysOrders(...) } }

Page 10: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

@Named @SessionScoped public class OrderOverviewBean() { @Inject private OrderService service; private List<Order> orders; @PostConstruct protected void init() { orders = service.findTodaysOrders(...) } }

Page 11: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

@Named @SessionScoped public class OrderOverviewBean() { @Inject private OrderService service; private List<Order> orders; @PostConstruct protected void init() { orders = service.findTodaysOrders(...) } }

Page 12: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

Web Entwicklung aus der Brille eines Java EE Entwicklers!

!

- The UI Part -!

Page 13: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

<html> <head> <link ... href="theme.css" /> <link ... href="primefaces.css.jsf" /> <link ... href="fileupload.css.jsf" /> <script ... src="jquery.js.jsf" /> <script ... src="primefaces.js.jsf" /> <script ... src="fileupload.js.jsf" /> </head> <body> <div id="main_navigation"> <a ...><img src="print.png.jsf?ln=img"></a> <a ...><img src="export.png.jsf?ln=img"></a> </div> </body> </html>

Page 14: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

<html> <head> <link ... href="theme.css" /> <link ... href="primefaces.css.jsf" /> <link ... href="fileupload.css.jsf" /> <script ... src="jquery.js.jsf" /> <script ... src="primefaces.js.jsf“ /> <script ... src="fileupload.js.jsf“" /> </head> <body> <div id="main_navigation"> <a ...><img src="print.png.jsf?ln=img"></a> <a ...><img src="export.png.jsf?ln=img"></a> </div> </body> </html>

rendered=“#{bean.value.attr}“

Page 15: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

<html> <head> <link ... href="theme.css" /> <link ... href="primefaces.css.jsf" /> <link ... href="fileupload.css.jsf" /> <script ... src="jquery.js.jsf" /> <script ... src="primefaces.js.jsf" /> <script ... src="fileupload.js.jsf" /> </head> <body> <div id="main_navigation"> <a ...><img src="print.png.jsf?ln=img"></a> <a ...><img src="export.png.jsf?ln=img"></a> </div> </body> </html>

Page 16: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

Agenda •  Die üblichen Verdächtigen •  Java EE Zutaten •  6 Gänge Menü •  Die Summe macht es •  8 Gänge Menü •  Diät-Vorschlag: Kalorien-Arithmetik

Page 17: Lessons Learned: Java EE Webstack Performance

Die üblichen Verdächtigen!

Page 18: Lessons Learned: Java EE Webstack Performance

Die üblichen Verdächtigen!

•  „Tuning“ – Netzwerk-Latenz – Transfer-Volumen – Browser Perform.

•  HTML Rendering •  CSS Rendering •  JS Engine

Page 19: Lessons Learned: Java EE Webstack Performance

Die üblichen Verdächtigen!

•  „Tuning“ – Dynamic vs. Static – Stateful vs.

Stateless – EL vs. Code

Page 20: Lessons Learned: Java EE Webstack Performance

Die üblichen Verdächtigen!

•  „Tuning“ – Fine vs. Coarse – Backend-Interaktion

– Caches

Page 21: Lessons Learned: Java EE Webstack Performance

Die üblichen Verdächtigen!

•  „Tuning“ – EIS Interaktion

Page 22: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

Agenda •  Die üblichen Verdächtigen •  Java EE Zutaten •  6 Gänge Menü •  Die Summe macht es •  8 Gänge Menü •  Diät-Vorschlag: Kalorien-Arithmetik

Page 23: Lessons Learned: Java EE Webstack Performance

Java EE Zutaten!

•  JSF 2.0 – Templates – Composites – EL-API 2.2 – Partial Rendering – Partial Submit – Resource Libs

Page 24: Lessons Learned: Java EE Webstack Performance

Java EE Zutaten!

•  CDI 1.0 –  Injection – Conversation – Events

Page 25: Lessons Learned: Java EE Webstack Performance

Java EE Zutaten!

•  CDI 1.0 –  Injection – Events – Scopes

Page 26: Lessons Learned: Java EE Webstack Performance

Java EE Zutaten!

•  EJB 3.1 –  Injection – Asynchronous

Page 27: Lessons Learned: Java EE Webstack Performance

Java EE Zutaten!

•  EJB 3.1 –  Injection – Asynchronous

out of scope

Page 28: Lessons Learned: Java EE Webstack Performance

Java EE Zutaten!

•  CDI 1.0 –  Injection – Events – Scopes

Page 29: Lessons Learned: Java EE Webstack Performance

Java EE Zutaten!

•  JPA 2.0 – Cache API – Criteria API – Orphaned

Removal –  ...

Page 30: Lessons Learned: Java EE Webstack Performance

Java EE Zutaten!

•  JPA 2.0 – Cache API – Criteria API – Orphaned

Removal –  ...

out of scope

Page 31: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

Agenda •  Die üblichen Verdächtigen •  Java EE Zutaten •  6 Gänge Menü •  Die Summe macht es •  8 Gänge Menü •  Diät-Vorschlag: Kalorien-Arithmetik

Page 32: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

Page 33: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Phase I: Restore View –  (Wieder-)herstellen des aktionsauslösenden/

angeforderten Views •  Erstellung Komponentenbaum auf Basis .xhtml

Seite •  Beim ersten Request grundsätzlicher Aufbau des

Komponentenbaums

Page 34: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Restore View: Alles OK*

*JSF Development Mode beachten

Page 35: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Phase II: Apply Requests – Zuweisung (HTTP-Request) Parameter zu

JSF Komponenten als submittedValue •  Keine Validierung •  Keine Konvertierung

Page 36: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Apply Requests: Alles OK

Page 37: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Phase III: Process Validations – Konvertierung und Validierung der

Eingabeparameter und Berücksichtigung der im Modell und View definierten Regeln

– Nutzung von •  JSF-Validatoren •  JSF-Konvertern

Page 38: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Process Validations: Workload – Große Formularfelder erfordern hohe Anzahl

an Konvertierung und Validierung •  Auswirkungen bei Date, BigDecimal

– Folge: Vergleichsweise hoher Anteil in Validierung bei Submit des gesamten Formulars

Page 39: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Process Validations: Workload

Page 40: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Process Validations: Workload-Tipp – Nutzung von Wizards

•  Verkleinerung Formularbestandteile

– Partial Submits für Value Changes •  Kein finales Form Submit

Page 41: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Process Validations: PostConstruct – Ein einfaches Registrations-Formular

Page 42: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Process Validations: PostConstruct

Page 43: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Process Validations: PostConstruct-Tipp – Vermischung von Use-Cases vermeiden

•  Datenaufbereitung und Form Behandlung sind unterschiedliche Use Cases

– @PostConstruct in @RequestScoped gehören unter besondere Beobachtung

Page 44: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

@Named @RequestScoped public class RegistrationBean() { private List<News> currentNews; private String firstName; private String lastName; @PostConstruct protected void init() { currentNews = service.getPersonlizedNews(...) } }

Page 45: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

@Named @RequestScoped public class RegistrationBean() { private List<News> currentNews; private String firstName; private String lastName; @PostConstruct protected void init() { currentNews = service.getPersonlizedNews(...) } }

Page 46: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Process Validations: Backend Integration – Validatoren/Konverter können unter

Umständen JPA Caching Effekte nicht nutzen •  Transaction-Bound EntityManager

Page 47: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Process Validations: Backend Integration

Page 48: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Process Validations: Backend-Tipp – RequestScoped EntityManager nutzen* @Produces @RequestScoped @PersistenceContext(unitName=“x", type=EXTENDED) public EntityManager createEntityManager( @PersistenceUnit(unitName = “x") EntityManagerFactory factory) { return factory.createEntityManager(); }

*inclusive Disposer Method

Page 49: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Phase IV: Update Model Values – Aktualisierung des Modells durch Zuweisung

der konvertierten und validierten Parameter

Page 50: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Update Model Values – alles OK

Page 51: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Phase V: Invoke Application – Ausführung der Zielmethode via Reflection

Page 52: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Invoke Application: Keine Auffälligkeiten – Siehe „Die üblichen Verdächtigen“ – Siehe „Die Summe macht es“ – Siehe „PostConstruct“

Page 53: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Phase VI: Render Response – Erzeugung einer (HTML-)Antwort auf der Basis

des berechneten Ziel-Views und Modells •  Nutzung von der JSF-Renderer aus dem

verwendeten Renderkit •  Entfällt bei redirect

Page 54: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Render View: Komplexe Views – Moderne Web Anwendungen haben oft

Desktop Charakter •  Tiefe Verschachtelungen •  Bedingte Sichtbarkeiten

Page 55: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Render View: Komplexe Views-Tipp – Unnötige Formatierungsanweisungen

vermeiden – Layout via CSS und nicht via JSF

– Exit-Strategie Client Side Code •  JSF Client-Behaviours •  Pure JS/JQuery

Page 56: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Render View: Possibly-Lazy Views – Modale Dialoge, Detailansichten und Tabs

gehören zu heutigen Webanwendungen •  Desktop Usability

– Darstellung der Inhalte erfolgt In-Page, ohne Neuladen der Seite

–  Inhalte werden unter Umständen mit jedem Request ausgeliefert

Page 57: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Render View: Possibly-Lazy Views-Tip – Nicht sichtbare Inhalte auch nicht zum Client

ausliefern •  Dynamisches Nachladen realisieren •  „Dynamic“ Eigenschaften der Komponenten nutzen

<p:dialog modal="true" dynamic=“true“>...</p:dialog>

Page 58: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Render Response: EL Performance – Performance Reference Implementierung

EL- API ist OK

– JUEL* bringt erheblichen Performance-Gewinn

*http://juel.sourceforge.net

Page 59: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Render Response: EL Graph Evaluation –  In der Regel werden trotz eingeführter

„Variablen“ EL Ausdrücke immer komplett ausgewertet

<p:dataTable var=“customer" value="#{customerOverview.customers}“> <p:column> <h:outputText value="#{customer.firstName}"/> </p:column> </p:dataTable>

Page 60: Lessons Learned: Java EE Webstack Performance

6 Gänge Menu!

•  Render Response: EL Evaluation-TIP – Sehr tiefe EL-Ausdrücke, speziell über

Collections vermeiden – Composite Components mit Backing Beans

verwenden •  Binding-Attribute

Page 61: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

Agenda •  Die üblichen Verdächtigen •  Java EE Zutaten •  6 Gänge Menü •  Die Summe macht es •  8 Gänge Menü •  Diät-Vorschlag: Kalorien-Arithmetik

Page 62: Lessons Learned: Java EE Webstack Performance

Die Summe macht es!

•  Verschiedene Probleme werden nur in Kombination relevant – PostConstruct Evil –  „Rendered“-Attribute – EL Actions mit Params – CDI Events und Scopes – EntityManager Lifecycle

Page 63: Lessons Learned: Java EE Webstack Performance

Die Summe macht es!

•  PostConstruct Evil – PostConstruct führt in allen Phase zu

unerwarteten Seiteneffekten

– Tipp (Wiederholung) •  Eine CDI Bean pro Use Case •  Fachfremde Initialisierung IMMER auslagern •  Bei RequestScoped Beans auf Lazy Init statt

PostConstruct Initialisierung ausweichen

Page 64: Lessons Learned: Java EE Webstack Performance

Die Summe macht es!

•  Rendered-Attribute – Auswertung rendered-EL-Ausdruck erfolgt im

LifeCycle mehrmals (bis zu 6 mal)

– Tipp: Auf EL-Ausführungszeiten achten – Tipp: Rendered und PostConstruct beachten

<h:panelGrid rendered="#{db.welcomeMessages.size() > 0}“ > ... </h:panelGrid>

Page 65: Lessons Learned: Java EE Webstack Performance

Die Summe macht es!

•  Parameterisierte EL-Actions – EL API 2.2 erlaubt parameterisierte

Methodenaufrufe •  EL-API(!) enthält performancerelevante Bug*

– Tipp: EL-API 2.2.2 oder später nutzen

<h:commandButton action="#{delController.delete(customer)}“ ... />

*http://java.net/jira/browse/UEL-19

Page 66: Lessons Learned: Java EE Webstack Performance

Die Summe macht es!

•  CDI-Events, Scopes und PostConstruct – CDI Events eignen sich für Aktualisierung von

Informationen in der Web Anwendung

public class CustomerService { @Inject @Deleted private Event<Customer> eventSource; public void deleteCustomer(Customer customer) { ... eventSource.fire(customer); } }

Page 67: Lessons Learned: Java EE Webstack Performance

Die Summe macht es!

•  CDI-Events, Scopes und PostConstruct @Named @SessionScoped public class CustomerService { public void onCustomerDelete(@Observes @Deleted Customer customer) { // reset internal list loadList(); } @PostConstruct public void loadList() { ... } }

Page 68: Lessons Learned: Java EE Webstack Performance

Die Summe macht es!

•  CDI-Events, Scopes und PostConstruct – Laden/Aufbereitung von Daten in Observer-

Methoden vermeiden – @Observers(notifyObserver=IF_EXISTS)

verwenden

Page 69: Lessons Learned: Java EE Webstack Performance

Die Summe macht es!

•  CDI-Events, Scopes und PostConstruct @Named @SessionScoped public class CustomerService { private List<Customer> customers; public void onCustomerDelete(@Observes @Deleted Customer customer) { // remove customer from customers list ... } }

Page 70: Lessons Learned: Java EE Webstack Performance

Die Summe macht es!

•  EntityManager LifeCycle –  In der Regel ist der Lebenszyklus an Java EE

EntityManager gebunden •  Lebt für den Zeitraum der Transaktion

– Folge: Keine Caching Effekte über alle LifeCycle Phasen hinweg

– Tipp: RequestScoped EntityManager nutzen

Page 71: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

Agenda •  Die üblichen Verdächtigen •  Java EE Zutaten •  6 Gänge Menü •  Die Summe macht es •  8 Gänge Menü •  Diät-Vorschlag: Kalorien-Arithmetik

Page 72: Lessons Learned: Java EE Webstack Performance

8 Gänge Menü!

Page 73: Lessons Learned: Java EE Webstack Performance

8 Gänge Menü!

Client (Browser)

Netzwerk

Page 74: Lessons Learned: Java EE Webstack Performance

8 Gänge Menü!

•  Partial Rendering / Partial Submits – Partial Submit

•  Teilweise Übertragung von Formularinhalten

– Partial Rendering •  Aktualisierung von ausgewählten HTML Elementen

Page 75: Lessons Learned: Java EE Webstack Performance

8 Gänge Menü!

•  Partial Rendering / Partial Submits – Problem Partial Rendering

•  Es gilt die Kochanleitung für das 6 Gänge Menü •  Partial Rendering kann bei komplexen die Browser

Render-Engine stark belasten –  Tiefe Tabellenstrukturen – Modale Dialoge / Lazy

– Tipp: Frühzeitig Auswirkungen im IE 7+ testen

Page 76: Lessons Learned: Java EE Webstack Performance

8 Gänge Menü!

•  Composite Component Resources – Deklaration von HTML Ressourcen in CC‘s

•  CSS, JavaScript, (Images)

– Folge: Zusätzliche Client-Server Kommunikation

<composite:implementation> <h:outputStylesheet library="css" name="errorPopup.css"/> <h:outputScript library="js" name=“errorPopup.js“ target="head"/> </composite:implementation>

Page 77: Lessons Learned: Java EE Webstack Performance

8 Gänge Menü!

•  Composite Component Resources - Tipp – Bildung von Composite Component Groups mit

shared CSS/JavaScript Libraries

<composite:implementation> <h:outputStylesheet library="css" name=“utility.css"/> <h:outputScript library="js" name=“utility.js“ target="head"/> </composite:implementation>

Page 78: Lessons Learned: Java EE Webstack Performance

Java EE Webstack Performance!

Agenda •  Die üblichen Verdächtigen •  Java EE Zutaten •  6 Gänge Menü •  Die Summe macht es •  8 Gänge Menü •  Diät-Vorschlag: Kalorien-Arithmetik

Page 79: Lessons Learned: Java EE Webstack Performance

Diät-Vorschlag: Kalorien-Arithmetik!

•  End-to-End Performance betrachten

•  High-Level Monitoring im Echtbetrieb

•  Low-Level Analyse On-Demand – Java Profiling – Netzwerk Profiling

Page 80: Lessons Learned: Java EE Webstack Performance

Diät-Vorschlag: Kalorien-Arithmetik!

•  High-Level Performance Monitoring – JAMON, JavaMelody, Java Simon, JETM, ... – JXInsight, Dynatrace, ...

Page 81: Lessons Learned: Java EE Webstack Performance

Gibt es noch Fragen?

Dann los ...

Page 82: Lessons Learned: Java EE Webstack Performance