The GlassFish Server includes a high performance and scalable CORBA Object Request Broker (ORB). The ORB is the foundation of the EJB Container on the server.
For complete instructions on configuring ORB settings, refer to Chapter 15, Administering the Object Request Broker (ORB), in Oracle GlassFish Server 3.1 Administration Guide. Also refer to Chapter 12, RMI-IIOP Load Balancing and Failover, in Oracle GlassFish Server 3.1-3.1.1 High Availability Administration Guide. You can also configure most ORB settings through the GlassFish Server Administration Console by navigating to the Configurations->configuration-name-> ORB node and then following the instructions in the Administration Console online help.
The following topics are addressed here:
The ORB is primarily used by EJB components via:
RMI/IIOP path from an application client (or rich client) using the application client container.
RMI/IIOP path from another GlassFish Server instance ORB.
RMI/IIOP path from another vendor’s ORB.
In-process path from the Web Container or MDB (message driven beans) container.
When a server instance makes a connection to another server instance ORB, the first instance acts as a client ORB. SSL over IIOP uses a fast optimized transport with high-performance native implementations of cryptography algorithms.
It is important to remember that EJB local interfaces do not use the ORB. Using a local interface passes all arguments by reference and does not require copying any objects.
A rich client Java program performs a new initialContext() call which creates a client side ORB instance. This in turn creates a socket connection to the GlassFish Server IIOP port. The reader thread is started on the server ORB to service IIOP requests from this client. Using the initialContext, the client code does a lookup of an EJB deployed on the server. An IOR which is a remote reference to the deployed EJB on the server is returned to the client. Using this object reference, the client code invokes remote methods on the EJB.
InitialContext lookup for the bean and the method invocations translate the marshalling application request data in Java into IIOP message(s) that are sent on the socket connection that was created earlier on to the server ORB. The server then creates a response and sends it back on the same connection. This data in the response is then un-marshalled by the client ORB and given back to the client code for processing. The Client ORB shuts down and closes the connection when the rich client application exits.
ORB statistics are disabled by default. To gather ORB statistics, enable monitoring with the following asadmin command:
set serverInstance.iiop-service.orb.system.monitoringEnabled=true reconfig serverInstance
If using the Administration Console, you can enable ORB monitoring on the Configurations->configuration-name->Monitoring page. To view ORB monitoring statistics through the Administration Console, navigate to the server (Admin Server) page and click the Monitor tab. Refer to the Administration Console online help for complete instructions.
The following statistics are of particular interest when tuning the ORB:
The following statistics are gathered on ORB connections:
total-inbound-connections: Total inbound connections to ORB.
total-outbound-connections: Total outbound connections from ORB.
Use the following command to get ORB connection statistics:
asadmin get --monitor serverInstance.iiop-service.orb.system.orb-connection.*
The following statistics are gathered on ORB thread pools:
thread-pool-size: Number of threads in ORB thread pool.
waiting-thread-count: Number of thread pool threads waiting for work to arrive.
Use the following command to display ORB thread pool statistics:
asadmin get --monitor serverInstance.iiop-service.orb.system.orb-thread-pool.*
Tune ORB performance by setting ORB parameters and ORB thread pool parameters. You can often decrease response time by leveraging load-balancing, multiple shared connections, thread pool and message fragment size. You can improve scalability by load balancing between multiple ORB servers from the client, and tuning the number of connection between the client and the server.
The following topics are addressed here:
You can tune ORB parameters using the instructions in Chapter 15, Administering the Object Request Broker (ORB), in Oracle GlassFish Server 3.1 Administration Guide. If using the Administration Console, navigate to the Configurations->configuration-name->ORB node and refer to the online help.
The following table summarizes the tunable ORB parameters.
Table 3-3 Tunable ORB Parameters
The ORB thread pool contains a task queue and a pool of threads. Tasks or jobs are inserted into the task queue and free threads pick tasks from this queue for execution. Do not set a thread pool size such that the task queue is always empty. It is normal for a large application’s Max Pool Size to be ten times the size of the current task queue.
The GlassFish Server uses the ORB thread pool to:
Execute every ORB request
Trim EJB pools and caches
Execute MDB requests
Thus, even when one is not using ORB for remote-calls (via RMI/ IIOP), set the size of the threadpool to facilitate cleaning up the EJB pools and caches.
You can set ORB thread pool attributes using the instructions in Chapter 5, Administering Thread Pools, in Oracle GlassFish Server 3.1 Administration Guide. If using the Administration Console, navigate to Configurations->configuration-name-> Thread Pools->thread-pool-name, where thread-pool-name is the thread pool ID selected for the ORB. Thread pools have the following attributes that affect performance.
Minimum Pool Size: The minimum number of threads in the ORB thread pool. Set to the average number of threads needed at a steady (RMI/ IIOP) load.
Maximum Pool Size: The maximum number of threads in the ORB thread pool.
Idle Timeout: Number of seconds to wait before removing an idle thread from pool. Allows shrinking of the thread pool.
Number of Work Queues
In particular, the maximum pool size is important to performance. For more information, see Thread Pool Sizing.
Specify the following properties as command-line arguments when launching the client program. You do this by using the following syntax when starting the Java VM:
The following topics are addressed here:
When using the default JDK ORB on the client, a connection is established from the client ORB to the application server ORB every time an initial context is created. To pool or share these connections when they are opened from the same process by adding to the configuration on the client ORB.
For information on how to configure HTTP load balancing, including the Load Balancer Plug-in, see Chapter 7, Configuring Web Servers for HTTP Load Balancing, in Oracle GlassFish Server 3.1-3.1.1 High Availability Administration Guide and Chapter 8, Configuring HTTP Load Balancing, in Oracle GlassFish Server 3.1-3.1.1 High Availability Administration Guide.
For information on how to configure RMI/IIOP for multiple application server instances in a cluster, Chapter 12, RMI-IIOP Load Balancing and Failover, in Oracle GlassFish Server 3.1-3.1.1 High Availability Administration Guide.
When tuning the client ORB for load-balancing and connections, consider the number of connections opened on the server ORB. Start from a low number of connections and then increase it to observe any performance benefits. A connection to the server translates to an ORB thread reading actively from the connection (these threads are not pooled, but exist currently for the lifetime of the connection).
After examining the number of inbound and outbound connections as explained above, tune the size of the thread pool appropriately. This can affect performance and response times significantly.
The size computation takes into account the number of client requests to be processed concurrently, the resource (number of CPUs and amount of memory) available on the machine and the response times required for processing the client requests.
Setting the size to a very small value can affect the ability of the server to process requests concurrently, thus affecting the response times since requests will sit longer in the task queue. On the other hand, having a large number of worker threads to service requests can also be detrimental because they consume system resources, which increases concurrency. This can mean that threads take longer to acquire shared structures in the EJB container, thus affecting response times.
The worker thread pool is also used for the EJB container’s housekeeping activity such as trimming the pools and caches. This activity needs to be accounted for also when determining the size. Having too many ORB worker threads is detrimental for performance since the server has to maintain all these threads. The idle threads are destroyed after the idle thread timeout period.
It is sometimes useful to examine the IIOP messages passed by the GlassFish Server. To make the server save IIOP messages to the server.log file, set the JVM option -Dcom.sun.CORBA.ORBDebug=giop. Use the same option on the client ORB.
The following is an example of IIOP messages saved to the server log. Note: in the actual output, each line is preceded by the timestamp, such as [29/Aug/2002:22:41:43] INFO (27179): CORE3282: stdout.
++++++++++++++++++++++++++++++ Message(Thread[ORB Client-side Reader, conn to 220.127.116.11:1050,5,main]): createFromStream: type is 4 < MessageBase(Thread[ORB Client-side Reader, conn to 18.104.22.168:1050,5,main]): Message GIOP version: 1.2 MessageBase(Thread[ORB Client-side Reader, conn to 22.214.171.124:1050,5,main]): ORB Max GIOP Version: 1.2 Message(Thread[ORB Client-side Reader, conn to 126.96.36.199:1050,5,main]): createFromStream: message construction complete. com.sun.corba.ee.internal.iiop.MessageMediator (Thread[ORB Client-side Reader, conn to 188.8.131.52:1050,5,main]): Received message: ----- Input Buffer ----- Current index: 0 Total length : 340 47 49 4f 50 01 02 00 04 0 0 00 01 48 00 00 00 05 GIOP.......H....
Note - The flag -Dcom.sun.CORBA.ORBdebug=giop generates many debug messages in the logs. This is used only when you suspect message fragmentation.
In this sample output above, the createFromStream type is shown as 4. This implies that the message is a fragment of a bigger message. To avoid fragmented messages, increase the fragment size. Larger fragments mean that messages are sent as one unit and not as fragments, saving the overhead of multiple messages and corresponding processing at the receiving end to piece the messages together.
If most messages being sent in the application are fragmented, increasing the fragment size is likely to improve efficiency. On the other hand, if only a few messages are fragmented, it might be more efficient to have a lower fragment size that requires smaller buffers for writing messages.