Performance Tuning

This article provides guidelines for you to consider while developing your applications to maximize application performance.

Many of these guidelines focus on awareness of your application's session usage in regards to Nexaweb's session usage. Other guidlines focus on various uses of messaging within your application.

Scalability and performance configuration

Aside from session configuration, which controls polling and reliable messaging, the single most important configuration items are the resource pools. Nexaweb has two thread pools and several byte buffer pools that you should monitor and adjust during your performance testing. You can view resource pool statistics through the Nexaweb service console. Adjust the resource pools by editing the appropriate parameters in the ResourcePool Configuration section of the nexaweb-server.xml configuration file.

Server-side session data limits sessions per server

Any data kept on the server-side on a per-session basis limits the number of sessions supported.

The server parses all XML outbound for the client from server-side documents, since the Nexaweb server cannot know what type of instructions a document may contain.

You need to use server-side documents only for documents that contain a server-side instruction such as:

  • Server-side or shared DOM manipulation
  • Web-service discovery instruction

If you expect the number of sessions per server to be a highly important consideration, or to support the maximum number of concurrent sessions, limit the amount of session data kept on the server. This is especially true in a failover-clustered environment, since in this environment, each Nexaweb server must hold twice the amount of data per session as each session has a backup copy in memory somewhere in the cluster.

Be aware of the threading context in which your code will be executing

Your code may execute in the context of a:

  • User request
  • Message delivery thread
  • Pooled thread
  • or the UI update thread on the client.

How long your code may use that thread will likely be different under each scenario. If your code is repeating anything in high volume or performing slow operations such as network or file IO, investigate whether the operations can be executed in another thread, a pooled thread if possible. A primary determinant of whether they can be executed in another thread is often related to error handling and whether the current thread needs to know whether the operations succeeded.

Single threaded document access

Do not use the document lock when accessing:

  • Unregistered documents
  • Client-side only user documents from a single thread.

It is okay to use the document lock with registered documents or the UI document, as other threads are always involved with these.

Messaging in high volume

On the server, there is a queue per messaging subscriber. Each queue is served by shared threads in the messaging thread pool. While the performance of this can vary widely based on delivery patterns, if there are many thousands of subscribers all receiving the same messages in high volume, this requires a large number of service threads in the messaging thread pool. One subscriber listening to ten topics may be more efficient (depending on your use pattern) than ten subscribers with one topic and vice-versa. Experiment with this in conjunction with your messaging thread pool settings to achieve the desired performance.

PushConnections are extremely expensive; close them when realtime data is not required

PushConnections use a thread per connection and are thus very expensive; they drastically limit the number of sessions per server.

Although you may want data to arrive on the client as soon as possible, applications rarely have realtime requirements.

PushConnections severely limit scalability; use them if scalability is not an issue or true realtime data delivery is required.

The organization of your application can aid you in balancing the need for realtime data versus scalability. For example, if you organize all UI components that are fed realtime data onto one tab or into one window, then the PushConnection can open and close when the tab or window opens and closes.

Nexaweb's reliable messaging adds overhead; most applications don’t need it

The use of Nexaweb's reliable messaging requires the Nexaweb server to maintain a lot of data about what has and has not been sent and received. The maintenance of this data adds significant amounts of overhead to applications.

The reliability layer is applied to all communications between the client and server. You can achieve better performance by knowing what data in your application is sensitive and cannot be lost and accounting for that information yourself. It is sometimes the case that certain sessions (such as superuser sessions) will require reliable messaging. Enable reliable messaging only for those sessions that truly require it.

Use client-side memory and processing power for maximum scalability

To achieve better scalability on the server, move logic, data and state to the client. In addition to being closer to the user, clients have processing power and memory available.

Measure performance in advance of a problem

Instrument your code. Use the tools available to measure performance in advance of a problem. PerformanceMeter provides insight into how long operations take and how many times they are performed. This data is invaluable, see the documentation for information on PerformanceMeter use.

Initial load time is affected by your application structure and packaging

How you structure and package your application has more to do with application load times than does Nexaweb’s intrinsic performance.

Debug statements can be expensive

String concatenation is extremely expensive. When putting debug statements in your code, ensure that you always have them wrapped in an if statement that will prevent the String concatenation from happening if debug logging is not turned on.

Example:

if ( myLog.isDebug() ) {
myLog.debug( “There are “ + i + “ things associated “ + “with “ + x + “ other things for session “ + session.getSessionId() );


Nexaweb

by Erik Abel