Thursday, July 24, 2014

Book Review: WildFly Performance Tuning

Packt Publishing recently published Arnold Johansson's and Anders Welén's WildFly Performance Tuning with the subtitle, "Develop high-performing server applications using the widely successful WildFly platform." As I discussed in my post Video Review: JBoss EAP Configuration, Deployment, and Administration, WildFly is the new name for the freely downloaded (community edition) version of the JBoss Application Server ("next generation of JBoss AS"). This post is my review of the PDF version of WildFly Performance Tuning.

Preface: Summary of Book's Contents and Who Book is Intended For

The Preface of Packt books is typically a useful place to quickly determine whether a Packt book is likely to address the subjects one is interested in and this continues to be the case with this book. The Preface of WildFly Performance Tuning contains brief summaries of what each of the book's ten chapters covers. It also explains what readers need to run many of the examples covered in the book (the book does cover some performance metrics tools not on this list because they are considered "optional" by the authors): Java SE 7 (I assume Java SE 8 will be okay), VisualVM (examples are based on VisualVM 1.3.6), and JMeter.

The "Who this book is for" section of the Preface describes the audience of this book and is a pretty good indicator of the content of the book: "This book is for anyone interested in what performance tuning is all about and how to do it using Java technologies, the WildFly Application Server, and other Open Source software." I also like that this section highlights something I was going to highlight in this review: Chapter 1 covers very general performance tuning principles, Chapter 2 and Chapter 3 cover performance tuning principles general to Java applications, and the remainder of the chapters focus on WildFly-specific performance tuning concepts and principles.

Chapter 1: The Science of Performance Tuning

The authors state in the initial chapter of WildFly Performance Tuning that "performance testing and tuning is a science." The chapter introduces, and describes in some detail, key performance-related terms such as response time, throughput, and scalability. The first chapter also covers some common high-level "performance tuning anti-patterns," many of which are more process and organizational in nature than technical in nature. Chapter 1 describes the software development cycle and how performance considerations need to be made in architecture and design phases and not simply just before shipping. There is a small amount of introductory WildFly-specific and Java/JMX-specific discussion in this chapter, but most of the chapter is on concepts at a higher level than a specific application server or even specific programming language or platform.

Chapter 2: Tools of the Tuning Trade

The second chapter of WildFly Performance Tuning discusses using tools "from the open source ecosystem" for JVM profiling and sampling, for operating system monitoring, and for load testing. The tools covered include VisualVM (including remote access with jstatd and JMX), top, netstat, vmstat (and vm_stat), OS X Activity Monitor, WildFly Command Line Interface (CLI), WildFly Management Console (HAL), and Apache JMeter.

Although the focus of this second chapter is on tools for profiling, monitoring, and load testing, there is more WildFly specific content in this chapter than in the first chapter. Several of the concepts and tools described are done so from a WildFly perspective.

Chapter 3: Tuning the Java Virtual Machine

Chapter 3 of WildFly Performance Tuning takes on the ambitious task of explaining basics of the JVM. It's particular focus is on tuning Oracle's HotSpot JVM and the authors state, "We focus on Java SE 7 based on the Oracle JDK 7 distribution in this book, we'll follow that trail by looking at its VM implementation named Hotspot." One consequence of the Java 7 JVM being covered is that changes to the JVM in Java 8 (such as removal of permanent generation) are not covered. A single chapter is necessarily briefer coverage than one would find in a full book such as Java Performance.

Chapter 3's JVM coverage begins by describing the relationship between concepts described by the terms Java Virtual Machine (JVM), Java Runtime Environment (JRE), and Java Development Kit (JDK). I would expect readers of a book on performance tuning related to a Java-based application server to already know the difference between the JDK and JRE, but this material is there for those who aren't aware of the difference. I think Oracle's JRE 8 Download page has about as clear of an explanation of the difference between the JDK and JRE as I have seen for non-developers:

Do you want to run JavaTM programs, or do you want to develop Java programs? If you want to run Java programs, but not develop them, download the Java Runtime Environment, or JRETM. If you want to develop applications for Java, download the Java Development Kit, or JDKTM. The JDK includes the JRE, so you do not have to download both separately.

The third chapter talks about the JVM stacks, the JVM heap, and garbage collection (GC) with a HotSpot JVM focus. The chapter introduces some of the most commonly used HotSpot JVM options such as -XX:+PrintFlagsFinal, -client and -server, -Xss, -Xms, and -Xmx. After reviewing these options, the chapter looks at how to determine through analysis and monitoring what the settings should be for initial heap size and maximum heap size. The chapter looks at using heap options -XX:MaxNewSize, -XX:NewSize, and -XX:NewRatio together to manage the size of the young generation portion of the heap.

Chapter 3's coverage of balancing eden space and survivor space on the JVM heap introduces the options -XX:+PrintTenuringDistribution, -XX:InitialTenuringThreshold, -XX:MaxTenuringThreshold, -XX:SurvivorRatio, and -XX:TargetSurvivorRatio. There is also a short description of permanent generation heap space with a side note that it is removed in Java 8.

The JVM option -XX:+UseLargePages for large memory pages is covered in Chapter 3 before moving onto discussion of OutOfMemoryError. This portion of the chapter has a highly useful break-down of several of the different specific types of OutOfMemoryError and how to deal with them.

There is also Chapter 3 discussion on memory leaks in Java and how they can be identified and resolved. An example is presented to illustrate using VisualVM to diagnose and address a memory leak.

The section of Chapter 3 that focuses on garbage collection strategies introduces and briefly describes the four "most common strategies of the Hotspot VM" (serial collector, parallel collector, concurrent collector, and G1 ["incremental parallel compacting"] collector). This section also briefly compares these collectors and describes the situations in which each fits best.

Chapter 3 introduces three ways to specify JVM options for the JVM in which an instance of WildFly is running. The chapter then goes onto introduce and briefly describe four virtual machine logging parameters that the authors assert "should always be set in your production environment to log relevant information" (-verbose:gc, -XX:+PrintGCDetails, -XX:+PrintTenuringDistribution, and -Xloggc). The authors list several available tools (such as GCViewer and the tools provided with the Oracle JDK) for analyzing this log output.

Chapter 4: Tuning WildFly

Each of the first three chapters provided a little more WildFly specific information than the one before it, but even the third chapter was mostly more "general Java" than "specifically WildFly." Chapter 4, which begins about one-third of the way into the book, is the first chapter with heavy emphasis on WildFly specifically. It is in this chapter that WildFly background information is provided. For example, the authors state, "WildFly is, as of 2013, the new name of the historically famous and well renowned JBoss Application Server (JBoss AS)."

The fourth chapter of WildFly Performance Tuning provides a history of WildFly as it evolved from Enterprise Java Bean Open Source Software (EJB-OSS) to JBoss Application Server to WildFly. A table in this section associates major releases of JBoss/WildFly with the version of J2EE/Java EE it implemented (albeit not always being certified). This table indicates that WildFly 8 (first version with new name WildFly) implements Java EE 7. There is a brief section of Chapter 4 on WildFly architecture that talks about WildFly's modular design with separate components and subsystems.

Chapter 4 describes each of the WildFly subsystems and their associated pools: thread pool executor with six of its offered thread pools (listed in Table of Contents), resource adapter subsystem (makes use of Java EE Connector Architecture [JCA] and Resource Archives [RAR files]), batch subsystem (implements Java EE 7 Batch API), remoting subsystem (based on NIO and XNIO), transaction subsystem, and logging subsystem. Several pages are devoted to configuring WildFly logging.

Chapter 5: EJB Tuning in WildFly

The fifth through ninth chapters of WildFly Performance Tuning each focus on tuning of a particular Java EE component type within WildFly. Chapter 5's focus is Enterprise JavaBean (EJB) tuning and the chapter begins with a history of EJB and a brief description of the various types of EJBs.

The "Performance tuning EJBs in WildFly" section of the fifth chapter begins by showing the CLI command to instruct WildFly to generate detailed EJB-related statistics. Several of the approaches listed in this chapter are true of Java EE optimization in general (not limited to WildFly). Examples of this include using pass-by-reference (@Local/shallow/not serialized) rather than pass-by-value (@Remote/deep/serialized) when possible and using coarse grained access for remote calls.

Chapter 5 contains numerous examples of WildFly-specific monitoring and tuning of different types of EJBs (stateless, stateful, singleton session, and message-driven). Many of the monitoring examples use CLI commands and JMX/JConsole and the tuning examples tend to be via XML configuration.

Chapter 6: Tuning the Persistence Layer

WildFly Performance Tuning's sixth chapter presents some WildFly-specific tuning information, but much of the information presented in this chapter is more general (database design, SQL statement design, JDBC, etc.). The chapter begins with an overview of normalization in relational database design, database partitioning and indexes, all at a high-level and covered in general terms rather than focusing on a specific relational database implementation.

Chapter 6 describes three approaches to tuning JDBC: connection pooling, setting fetch size [ResultSet.setFetchSize(int) and Statement.setFetchSize(int)], batching [Statement.executeBatch()], and use of PreparedStatements. The sections on connection pooling and using PreparedStatements include information on how to specify and monitor these things in WildFly. There are short sections in this chapter on database isolation and low-level JDBC network tuning.

A significant portion of Chapter 6 is focused on tuning Java Persistence API (JPA) and Hibernate. The authors state, "WildFly 8.0.0.Final makes use of the JPA 2.1 specification and the bundled module since the provider is Hibernate in Version 4.3.1." Numerous tactics and strategies related to JPA are covered here and the list of them is available in the listing for Chapter 6 in the Table of Contents (includes entity caching and named queries).

Most of Chapter 6 applies to the persistence layer in any Java EE application server, but there are some sections that discuss WildFly specifics.

Chapter 7: Tuning the Web Container in WildFly

Chapter 7 introduces Undertow, described on its web page as "a flexible performant web server written in java, providing both blocking and non-blocking API’s based on NIO." The chapter provides some Undertow implementation details and also mentions several things that are not yet fully implemented, but are planned for the future. The seventh chapter moves onto tuning the Undertow Worker and buffer pool using WildFly CLI and the WildFly Admin Console.

Chapter 7 introduces Jastow, which it describes as "the JSP engine in Undertow" and "a fork of the Apache Jasper project." This section provides a table with a subset of options available for tuning Jastow performance and demonstrates using CLI, JMX, and Admin Console to view these settings.

WildFly Performance Tuning's seventh chapter ends with a discussion of using Apache HTTPD as a "frontend" to WildFly. As part of this discussion, this section introduces Apache JServ Protocol (AJP) as an alternative to HTTP for communication between the Apache HTTPD server and the WildFly instance(s). Examples are included to demonstrate configuring Apache HTTPD and WildFly for this configuration.

Chapter 8: Tuning Web Applications and Services

Chapter 8 begins it coverage of web applications and web services with a history of web application development from Common Gateway Interface (CGI) to Java servlets to JavaServer Pages (JSP) to JavaServer Faces (JSF). There is also some discussion regarding why one might choose to use or not use JSF and the authors mention that "WildFly ships with the Mojorra JSF 2.2 implementation."

Chapter 8 has sections on tuning web applications and tuning web services. The section on tuning web applications presents performance considerations related to servlets and JSPs (with JSTL), JSF, and JSF with PrimeFaces 4.x. The chapter uses a "simple data table" example to illustrate performance considerations for all three approaches to building Java EE web applications. Some of the topics covered along the way include JSP scopes, session timeouts, asynchronous servlets, JSF client state versus server state, and JSF immediate. There are several topics specific to Undertow and JSF component libraries (PrimeFaces and RichFaces) also covered in the web application performance tuning section before brief discussion of Java support for WebSockets.

Chapter 8's section of performance tuning web services covers Java API for XML Web Services (JAX-WS) along with WildFly's implementation of JAX-WS [JBossWS and Apache CXF (JBossWS-CXF)] and JAXB. Recommendations for reducing XML messaging overhead are covered. The section of web services tuning also includs a very short section on REST-based web services [Java API for RESTful Web Services (JAX-RS)].

Chapter 9: JMS and HornetQ

WildFly Performance Tuning's ninth chapter focuses on Java Message Service (JMS) and HornetQ version 2.4.1.Final (WildFly's JMS broker provider). The chapter covers JMS basics such as JMS destination types and JMS message types. It discusses general JMS tuning ideas such as tuning the JMS session and tuning the JMS MessageProducer.

A significant portion of Chapter 9 focuses on performance tuning options specific to HornetQ. These recommendations, which include "using input and output streams for handling large messages, are listed in the Table of Contents. The chapter concludes with examples of using WildFly-provided mechanisms to monitor HornetQ.

Chapter 10: WildFly Clustering

The tenth and final chapter of WildFly Performance Tuning focuses on WildFly clustering. The chapter begins with definitions of clustering and distributed computing terms and discussion of the basics of clustering. It opens up its coverage of WildFly clustering by pointing out that WildFly's clustering is built upon JGroups and Infinispan. The chapter then covers using each of these foundational open source projects. Chapter 10 then runs down the Java EE components and explains which have Java EE standard cluster support and which have WildFly proprietary cluster support.

General Observations
  • WildFly Performance Tuning covers both Java EE and JDBC standard tuning concepts as well as proprietary WildFly tuning concepts. Readers who are familiar with tuning other application servers and JDBC applications will likely be able to skim or skip chapters 1 through 3 and much of chapter 6. Readers who are new to performance tuning of Java EE (and Java SE) applications will likely find the inclusion of these more general chapters useful.
  • Chapter 3 ("Tuning the Java Virtual Machine") has very little WildFly-specific detail in it, but a related consequence of this is that this is a great introductory chapter for anyone interested in learning principles of JVM tuning that apply to various Java EE implementations and even to Java SE applications. This chapter provides a quick preview of the most important concepts in JVM tuning.
  • The PDF edition I reviewed has color screen snapshots.
  • Code examples are generally well-formatted and indented, but do not have any color syntax or line numbers.
  • With rare exceptions, the text flows well and sentences are generally easy to understand.
  • A relatively small number of items discussed in this book have been delayed to WildFly 9 or else are expected in the near future. The book does a nice job of calling these relatively infrequent cases out and making it clear what's in WildFly 8.x and what will be in WildFly 9.x.
Conclusion

WildFly Performance Tuning provides background information, descriptive text, and illustrative examples that allow the reader to learn principles, concepts, and approaches that can be applied to tuning a WildFly-hosted application. WildFly Performance Tuning mixes general JVM and Java EE tuning principles and tools with WildFly-specific tuning principles and tools to provide a composite view of how performance tuning of WildFly applications can be performed.