Configuration file rwagent.xml defines all configuration data needed to initialize the Agent. It also includes references to other configuration files in the conf directories. You can modify this file to specify:
Agent startup and shutdown configuration
Connectors
Handler chains
Please note that rwagent.xml makes use of an environment variable RWSF_CONF pointing to the default location of the conf directory, which is RWSF_HOME\conf. If you move the conf directory or any of its files to anther location, you will need to revise all references to RWSF_CONF in rwagent.xml to point to its new location.
The Agent startup and shutdown section of rwagent.xml sets the following:
default logger configuration file
shutdown properties
default locale, and the location of the catalog files that define Agent strings for various locales
methods to be called at startup and shutdown
The preStartup section loads a file describing named objects. If you wish to use named objects, you will need to uncomment the rwsf:methods element named load-namedobjects, and update the rwsf:objects-file property to point to your named objects definition file. For information see Chapter 17, "Named Objects," in the HydraExpress Web Service Development Guide.
The connector layer isolates the functionality for handling incoming requests on different transports so this functionality can be modified without affecting the rest of the system.
When a message enters the system, the associated connector spawns a new thread to handle the request and starts off a transport handler of the same type as the connector. At that point, the message is sent to the Agent general handler chain.
HydraExpress provides three default connectors:
HTTP
This connector listens for and accepts requests, stores the transport-specific information and the request payload, and passes the request data to a handler chain.
HTTPS
This connector provides security at the transport level through the HTTPS transport, and at the message level through its WS-Security. The default port for receiving HTTPS requests is 8443. For a discussion on configuring the HTTPS connector, see Section 3.5.
AJP13
This connector listens for and accepts requests from an Apache Web server. The default port is 8009. For information on the AJP 1.3 Apache connector, see Section 3.4.
By default, all connectors point to the handler chain named http.
The file may contain configuration information for any number of connectors, including multiple connectors of the same type, provided that each connector has a unique name and listens on a different port.
You can add support for additional transports by deriving from a connector base class and implementing the required functionality (Chapter 5).
The default http handler chain runs on every request and response message coming into and out of the Agent. Every connector passes the incoming request to this handler chain. This chain includes the following handlers:
httpserver
servlet
The servlet handler simply passes requests to the servlet execution engine, which has its own handlers. You can create handlers for any additional message handling functionality your system requires. For the details of how to create and configure custom handlers in the servlet execution engine, see Chapter 15, "SOAP Message Handler SDK," in the HydraExpress Web Service Development Guide.
Localization information is defined in the rwsfagent.xml file by two properties:
rwsf:locale-directory sets the directory where the message catalogs for different locales reside. The default value is $RWSF_HOME/conf/locale.
rwsf:default-locale sets the default locale() to use after the Agent loads the message catalogs. The default value is en_US.
For more information, see Chapter 7.
Agent ports are set in rwagent.xml. For example, the line in bold below
<rwsf:connector name="HTTP/1.1" ... <rwsf:property name="port" value="8090"/> ... </rwsf:connector>
sets the port for the HTTP connector to 8090.
The HydraExpress Agent uses the following default ports:
8090 | Used for HTTP requests sent directly to the Agent. |
8013 | Default port for HTTP requests sent to an external Web server (for redirection to the HydraExpress runtime). If your external Web server uses a different port, you will want to use that port instead. |
8009 | Used for AJP 1.3 requests sent to the Agent; usually sent from an external Web server such as Apache. |
8443 | Used for HTTPS requests sent directly to the Agent |
8413 | Used for HTTPS requests sent to an external Web Server (for redirection to the Agent). This number should be updated to reflect the port used in your external Web Server. |
8089 | Used for sending shutdown requests to the HydraExpress runtime. Shutdown requests must be issued from the host on which the Agent is running. |
9090 | Used for HTTP requests sent to a standalone client |
9413 | Used for HTTPS requests sent to a standalone client |
If you are running other servers on the same machine as the Agent, such as Tomcat or Apache, be sure that each is assigned a different port. For example, the default Tomcat AJP 1.3 port is 8009, the same port as the default AJP-1.3 connector in HydraExpress. In this case, you would need to change either the port for Tomcat or the AJP-1.3 connector port.
Requests or listeners assigned to the same ports on the same server will result in a fatal startup error Unexpected exception: SocketException: in Socket::bind: ADDRINUSE.
The Agent URL is defined by the connector (in rwagent.xml), the host name, and the port (both in transports.xml and client-transports.xml), followed by a path to various services. For example, for the HTTP connector on localhost, port 8090, the URL would be http://localhost:8090/<contextname>/<servicename>.
Agent thread pools are configured in the connector definitions in the file <installdir>\conf\rwagent.xml.
<rwsf:connector name="HTTP/1.1" class="rwsf_transport_http35.createHttpConnectorImp" handlerChain="http"> <rwsf:property name="accepter-threads" value="1"/> <rwsf:property name="thread-pool-min" value="15"/> <rwsf:property name="thread-pool-max" value="50"/> ... </rwsf:connector>
The accepter threads pool is for the operation that takes requests off the wire and passes it to the other thread pool for message handling. This operation is simple and fast, so generally one thread is sufficient to keep up with incoming requests. The intent is to avoid connection time out errors even if the Agent is severely backed up in the handling of service requests. If you requests may arrive so fast that they will overwhelm the default single acceptor thread, simple add another thread or two.
Be aware that multiple acceptor threads results in a very small but non-zero possibility that requests may not be queued up in the order received. This is because Agent low-level threading uses the operating system's thread scheduler. The scheduler could switch from a thread that has taken an incoming request off the socket but has not yet enqueued it, to another acceptor thread that takes another request off the socket and enqueues it before control returns to the first acceptor thread. These two incoming requests would then be enqueued in reverse order.
The second thread pool in this layer handles all the remaining operations that occur before a service request is handed to the servlet execution engine. This includes the operations of the connector itself, and the operations of the handler chain the connector passes the service request to. When the Agent starts up, it creates a thread pool with thread-pool-min number of threads. If load increases to the point where there are more than thread-pool-min service requests in this layer, the Agent creates additional threads up to a maximum of thread-pool-max. Once the number of threads increases, it stays at that level until the Agent is shut down and restarted.
The obvious question is: what are the optimum minimum and maximum values? This is a complicated question that relies on a number of factors:
What is the anticipated load on the given connector? Obviously, a high load suggests a higher number of threads in the pool.
How much processing takes place in the message handling layer? The more customization you add to this layer, the longer a service request is likely to remain before being passed to the service execution engine. This gives more time for additional requests to arrive, suggesting the need for more threads.
How processor-intensive is the processing? The whole point of thread pools is to keep the system processors busy, whatever the number of processors. If the processing in this layer relies mainly on processor cycles, fewer threads are needed because there is always likely to be at least one thread ready to execute. If, on the other hand, processing involves a lot of blocking time, when an operation is waiting on something like I-O, it increases the chance that all of the operations in all of the threads will be blocking and the processors will sit idle. In this case, you want to enlarge the thread pool to decrease the likelihood of this happening.
By considering the above factors, you can make an educated guess on how large to make your thread pool, both initially and under load. Ultimately, though, the only way to determine the optimum values is empirically. Set some values, put the system under load, and gather some metrics. Then change the values and gather those numbers. Eventually you should be able to arrive at a set of values that yields the best performance.
©2004-2007 Copyright Quovadx, Inc. All Rights Reserved.
Quovadx and Rogue Wave are registered trademarks of Quovadx, Inc. in the United States and other countries. All other trademarks are the property of their respective owners.
Contact Rogue Wave about documentation or support issues.