Handling Multiple Connections
Handling Many Connections on the Client Side
When a client Java application establishes many simultaneous sessions, or nSession instances, to Universal Messaging, you might encounter the following issues:
- The client application might run out of memory because the many Java threads that are created consume a lot of memory.
- The client application might return the error
"java.net.SocketException: Too many open files"
because it has reached the maximum allowed count of open files, or sockets, on the operating system.
Resolve Out of Memory Issues
Each non-multiplex nSession to Universal Messaging creates at least three Java threads:
- A connection read thread (
UM-Connection-Reader
) - responsible for reading events received from the Universal Messaging server. - A connection write thread (
fProcessThreadedQueue
) - responsible for sending events to the Universal Messaging server. - One or more event dispatch threads (
UM-Event-Processing-Pool
) - responsible for processing events that are read from the connection. These threads are available only when threading is enabled on the session. Threading is enabled by default and a thread is created when the session is started. For more information about threading, see the Universal Messaging Java API reference documentation for nSession.enableThreading(boolean).
The Java virtual machine (JVM) allocates a certain amount of memory to each thread stack. For this reason, when many threads are created for many sessions, the client application might run out of memory.
You can perform the following actions to reduce memory consumption:
- Reduce the amount of memory allocated for a thread stack by using the
-Xss
command-line option of the JVM. For more information about the option, see the documentation of your JVM vendor. - Decrease the number of event dispatch threads used for every session by configuring
the
com.softwareag.um.client.useSharedThreadPool
andcom.softwareag.um.client.SharedThreadPoolMaxSize
client system properties.Normally, the Universal Messaging Java client uses a dedicated thread pool of event dispatch threads for every session. Instead, you can configure the client to use a single, shared thread pool for this type of threads for all client sessions by using the following properties.
com.softwareag.um.client.useSharedThreadPool
- enables usage of a shared thread pool for processing incoming nConsumeEvent events for each client session. Values aretrue
orfalse
(default). By default, each client session creates and uses a separate thread pool for processing received nConsumeEvent events. When this system property is set totrue
, all client sessions will use a shared thread pool. Using a shared thread pool for all client sessions may have a performance impact depending on the size of the shared thread pool and the number of client sessions.Note: When each client session uses a separate thread pool, closing the session interrupts any event listener threads that are blocked during processing. When all client sessions share a thread pool, closing a session does not interrupt any event listener threads that are blocked during processing. Thus, the blocked event listener does not release a shared thread after closing the client session. This behavior impacts the processing of incoming events, because the shared pool will not have available threads. IBM recommends that you enable the shared pool for all client sessions only if the event listener of the client application ensures that the processing of the events is fast and graceful.com.softwareag.um.client.SharedThreadPoolMaxSize
- specifies the maximum size of the shared thread pool. The default is5
threads.
Resolve Socket Exceptions
The connection protocol used for each session to Universal Messaging impacts the total number of sockets that are created. An nSession using the nsp or nsps protocol, that is, the Universal Messaging socket protocol or SSL socket protocol, uses a single socket for communication with the Universal Messaging server. An nSession using the nhp or nhps protocol, that is, the Universal Messaging HTTP or HTTPS protocol, uses two sockets for communication with the server.
An application creating many sessions might fail with a
"java.net.SocketException: Too many open files"
error if it creates so
many sockets that it reaches the maximum allowed count of open files, or sockets, on the
operating system.
To resolve this issue, you might need to perform any or a combination of the following actions:
- Increase the limit of maximum allowed files or sockets.
- Consider if your application requires that many sessions.
- Check if the application creates sessions but fails to close them after they are no longer needed.
- Check for TCP/IP port exhaustion.
This issue might occur even when the application closes sessions when they are no longer needed. If the application creates and then closes a lot of sessions in a short time, it might cause TCP/IP port exhaustion because operating systems usually keep sockets in a waiting status (TIME WAIT) for some time after sockets are released by the application. In this case, you might need to do the following:
- Expand the range of ports available for use by your application.
- Reduce the time the operating system keeps those sockets in a waiting status after they are released.
Handling Many Connections on the Server Side
To handle many simultaneous inbound connections to Universal Messaging, you might need to do the following:
Use NSP or NSPS Protocol
When handling many inbound connections that do not require the HTTP or HTTPS protocol, IBM recommends that you use the Universal Messaging Socket Protocol (nsp) or the Universal Messaging SSL Protocol (nsps).
For more information about what native communication protocols that Universal Messaging supports, see Native Communication Protocols.
Adjust Interface Attributes
The Universal Messaging server does not allocate individual threads for each incoming connection. Instead, the server uses a thread pool named Accept Threads to accept the connection and a separate thread pool named Select Threads to monitor data to be read or written to the socket.
When a Universal Messaging server is handling many incoming connections at the same time, you might need to adjust several attributes of the server interface to which the client connects. You configure the attibutes on the Comms > Interfaces tab for a server in the Enterprise Manager as follows:
- Accept Threads. Increase the Accept Threads value, otherwise some of the connections will be queued in a backlog queue waiting to be accepted.
- Backlog. Increase the capacity of the
Backlog queue, otherwise when the capacity of the backlog queue
is reached, additional connection requests will be denied.Note: On Linux, you might need to set the kernel parameter
net.core.somaxconn
. For Linux 2.2 and greater, the parameter specifies the maximum queue length for completely established sockets waiting to be accepted.For additional operating-system-specific tuning, see Tuning the Linux Operating System.
- Auth Time. Increase the time to authenticate incoming connection requests if connection authentication is slow and causes the server to close the connection.
- Select Threads. Keep the Select Threads
value low even if the interface is handling a lot of connections. The number of select
threads should not typically exceed the number of cores available.
Select Threads transfers reading or writing of network data to separate read or write thread pools. You configure the maximum count of threads for the read and write thread pools in the ReadThreadPoolMaxSize and WriteThreadPoolMaxSize properties on the Config > Thread Pool Config panel in the Enterprise Manager. Read pool threads are used for processing incoming client requests, while write pool threads are involved in writing data to client connections.
For more information about the attributes of an interface, see Basic Attributes for an Interface.
Resolve "java.lang.OutOfMemoryError Direct buffer memory" Errors
Universal Messaging uses in-memory buffers to handle network traffic. By default, these network buffers use the Java direct (off-heap) memory. To configure the Java direct memory for a realm in the Enterprise Manager, you go to Config > Connection Config > UseDirectBuffering.
If the connections handle a lot of traffic or if there are too many connections, the
server might return the error "java.lang.OutOfMemoryError Direct buffer
memory"
. In this case, you should increase the amount of direct memory
allocated for the Universal Messaging server process by using the
-XX:MaxDirectMemorySize=<size>
Java command-line argument.
For information about -XX:MaxDirectMemorySize
, see the Oracle
documentation on Java command-line options.
For more information about how to troubleshoot the "java.lang.OutOfMemoryError
Direct buffer memory"
error and configure direct memory, see Troubleshooting.
Handle a Slow Network when Clients are Across WAN
In case of a slower network when clients are across WAN, IBM recommends that you increase the socket read and write buffer size based on bandwidth-delay product.
Be aware that increasing the read and write buffer size impacts the direct memory allocated by the server. You might need to adjust your direct memory accordingly.