Web Connection Management
This chapter describes how to manage and set listeners and connectors provided by the web engine.
1. Overview
In JEUS, web connectors and web listeners are both referred to as web connections. The connections provided by a web engine includes connections to WebtoB and other web servers, direct connections to HTTP/TCP clients, and connections to Tmax. The web server receives an HTTP request from a client and delivers it to the corresponding web engine.
WebtoB and Apache are the typical web servers that are used. They provide the following connectors.
-
WebtoB connector
WebtoB provides the WebtoB connector since JEUS acts as the client when a connection is created.
-
AJP listener
Apache provides the AJP listener since JEUS acts as the server when a connection is created. Other commercial web servers such as IIS and SunOne(Iplanet) also support AJP, and therefore the AJP listener can be used to connect to other web servers.
The web engine provides the following listeners and connectors to directly create and manage connections for each client.
-
HTTP listener
Directly manages connections to HTTP clients. This listener must be used to use the functions of Async Servlet, Servlet NIO, and Websocket.
-
TCP listener
Manages connections to TCP clients.
-
Tmax connector
Manages connections to Tmax. When a connection is created, JEUS acts as a client, like the WebtoB connector.
Since listeners operate according to the JEUS server configurations, configure JEUS server and its listeners to use secure listeners (SSL).
For more information about configuring JEUS server, refer to Listener Configuration in JEUS Server Guide. |
2. Components
This section describes listeners and connectors provided by the web engine.
2.1. Listeners
Listeners are web engine channels that can be accessed by HTTP/TCP clients and web servers that follow the AJP protocol.
The following figure show the connections between the web engine connectors, each clients, and protocols.
The following describes each listener.
-
AJP listener
AJP listener allows web servers other than WebtoB, such as Apache, IIS, and SunOne(Iplanet), to interact with JEUS web applications. It is supported by the mod_jk module, uses the AJP1.3 protocol, and supports SSL. For more information about AJP listeners, refer to AJP Listeners and Configuring Web Server Load Balancing. For more information about the configuration of SSL server listeners, refer to JEUS Server Guide.
-
HTTP listener
HTTP listener is used when the web engine directly receives HTTP requests. It supports SSL. For more information, refer to HTTP Listeners.
For more information about configuring SSL for HTTP listeners, refer to JEUS Server Guide.
-
TCP listener
TCP listener is used for clients that use a custom protocol instead of the HTTP protocol. For more information about TCP listeners, refer to TCP Listeners and Using TCP Listeners.
2.2. Connectors
Connectors are channels that connect to WebtoB or Tmax from the web engine.
The following figure show the connections between the web engine connectors, each clients, and protocols.
The following describes each connector.
-
WJP (WebtoB) connector
WJP stands for WebtoB-JEUS-Protocol. WebtoB is a web server provided by TmaxSoft. It can be used as a standalone installation as well.
WebtoB connector can directly connect to WebtoB since JEUS acts as the client when a connection is created. This feature allows connections to be made to WebtoB without configuring the firewall. For more information about the WebtoB connector, refer to Configuring Web Server Load Balancing.
-
Tmax connector
Tmax is a system software that manages XA transactions in a distributed environment. Like WebtoB connectors, JEUS acts as a client for Tmax connectors. The Tmax connector can be used to exchange information between JEUS and Tmax, or to receive HTTP requests through the Tmax gateway in order to integrate communication channels. For more information about the Tmax connector, refer to Tmax Connectors.
JEUS only acts as a client when the connection is created. JEUS actually receives requests from external clients through WebtoB or Tmax, but it does not send requests to WebtoB or Tmax. JEUS functions as a server during service processing. |
2.3. Worker Thread Pool
Listeners and connectors have a worker thread pool that is required to process client requests. The worker thread pool manages worker threads.
In versions prior to JEUS 21, listeners and connectors managed the worker thread pool. From JEUS 21 fix#1 onwards, web connections, virtual hosts, and contexts manage the worker thread pool. For more information, refer to Thread Pool.
When a listener receives a request, a worker thread is allocated to process the request. When a WebtoB connector has HTTP, AJP13, and TCP listeners with <use-nio> being set to true, it looks up the contexts and hosts by parsing the request before passing the task to the worker thread, so it can redirect the request to the context or virtual host level thread pool. When a connector establishes a connection between WebtoB or Tmax and JEUS, JEUS acts as the client. If <use-nio> is set to false for a WebtoB or Tmax connector, requests cannot be read before assigning the worker thread pool because there is no server listener. In this case, only a connector-dependent thread pool can read and handle the requests, thus the number of connections must match the number of threads within the connector. Therefore, when configuring the thread pool for a web connection, ensure that the connection and thread pool have the same Min/Max values.
Since the Min/Max values for the worker thread pool have significant impact on the service processing performance, ensure that the worker thread pool is properly configured for a listener or connector.
Each thread pool manages its own status and the monitoring thread logs the result periodically. Hence, the changes in the log can be different from the actual changes of the thread pool. |
Active-Management and Status Notification
The worker thread pool contains configurations for active management. The administrator can configure active management to allow the web engine to send a warning message via e-mail or to recommend restarting the server of the engine. To requires configuring the number of blocked worker threads that will trigger an action like sending a warning message via e-mail or a recommendation to restart the server.
If the recommendation to restart is displayed, the administrator must determine whether to restart the server because it is likely that the server cannot process requests normally. |
3. Configuring Web Connections
Separate vendor-specific configurations are required to use an AJP listener, a WebtoB connector, or a Tmax connector. Since all web connections are managed by the engines, this section only describes the web engine configurations. For more information about configuring web servers, refer to Configuring Web Server Load Balancing.
|
Connectors are added, changed, or deleted in the console tool. Refer to Web Engine Commands in JEUS Reference Guide for detailed information about configuring connectors by using the console tool.
3.1. Common Listener Settings
This section describes the common listener settings.
-
Name
-
Unique name that identifies the web connection. This is a required option and must be unique within the web engine.
-
-
Server Listener Ref
-
Represents the server listener that the listener references.
-
HTTP and AJP listeners can reference the same server listener, but if the HTTP listener is configured for management, the HTTP listener cannot share the server listener. If not set, the default server listener will be used.
-
TCP listener cannot reference a server listener that is referenced by another listener.
-
2 or more protocol listeners cannot reference the same server listener. For example, if two AJP listeners are configured, but neither listener is configured with a server listener, an error will occur because both reference the default server listener. One must refer to a different server listener.
-
Idle client connections can be closed by using the server listener’s <keep-alive-timeout> setting. (Unit: ms)
-
-
Connection Type
-
Forcibly sets the "Connection" header for responses that are sent through each listener or connector.
-
Set one of the following.
Value Description keep-alive
Keep the connection after sending the response.
close
Terminate the connection after sending the response.
none
Set the "Connection" response header based on the properties defined in the request header. If not set, the default action is same as 'none'.
The 'Connection Type' cannot be configured for AJP listeners. It is recommended to follow the configurations of the web server, like Apache, for AJP listeners.
-
-
Thread Pool
-
Web connection-level worker thread pool configurations.
-
The following describes each setting item.
Item Description Min
Minimum number of worker threads managed by the pool.
If the <use-nio> setting is false for the WebtoB connector, this value must be the same as in <Connection-Count>.
Max
Maximum number of worker threads managed by the pool.
If the <use-nio> setting is false for the WebtoB connector, this value must be the same as in <Connection-Count>.
Maximum Idle Time
Amount of time during which a thread remains unused before being removed from the pool. This causes increased resource usage.
Max Queue
Maximum number of requests that can wait in queue.
If set to -1, there is no limit in the queue size.
Thread State Notify
Notifies when a worker thread is blocked.
Each thread pool contains the 'Thread State Notify' setting which defines the action to be taken when a failure occurs. For more information about this setting, refer to Configuring Automatic Thread Pool State Management.
-
-
Output Buffer Size
-
The size of the output buffer that is used by applications. If the buffer is full, its data will automatically be flushed by the web engine. (Unit: Byte)
-
For AJP listeners, it is recommended that this value match the value of max_packet_size in the workers.properties file of mod_jk. For more information about configuring mod_jk, refer to Configuring Web Server Load Balancing.
-
-
Postdata Read Timeout
-
The maximum amount of waiting time allowed when reading request bodies. Applied in the ServletInputStream.read() method. (Unit: ms)
-
The point in time when a timeout is applied is changed for HTTP and TCP listeners.
Since I/O control threads that exist in each listener read all request bodies, it is determined whether timeout occurred or not before the bodies are sent to a Servlet. If timeout occurs while reading request bodies, the 500 error is returned. If an HTTP request is chunked, the setting is applied when the servlet calls ServletInputStream.read().
-
-
Max Post Size
-
A POST data request that is too large and too many resources are required to read and analyze them may prevent other requests from getting processed. This configuration is used to prevent this by blocking requests that are too large and burdensome for processing. (Default value: -1)
-
Limits the maximum data size in bytes of POST requests based on the request Content-type.
-
If Content-Type is x-www-form-urlencoded
Stops processing the request and send a "413 Request Entity Too Large" response if the request size or the total size of chunked data is greater than the specified value.
-
If Content-Type is multipart/form-data
Limits the size of uploaded files and the total size of a POST request. To limit the size of uploaded files, it is recommended to use the multi-part configuration of Servlet.
-
-
Servlet web application deployment descriptor affects this configuration in the following ways.
-
<multipart-config> in web.xml.
If the <multipart-config> setting exists in web.xml, its child settings, <max-file-size> and <max-request-size>, are used. Otherwise, the web engine does not set a limit, so it is recommended to configure <multipart-config> for each application.
-
<content-length>
If the <content-length> setting exists and the content length exceeds the specified value, the request will not be processed. If <content-length> is not set and the sum of the bytes of the name/value pairs of parameters exceeds the specified value, the request will not be processed.
-
-
A negative value is considered as the default value, which means there is no limit on the data size.
-
Applies to listeners and connectors that receive HTTP requests. It does not apply to TCP listeners or Tmax connectors.
-
-
Max Parameter Count
-
A request with too many parameters increases the resources required to analyze and manage the parameters. This configuration can be used to prevent such a problem. (Default value: -1)
-
Limits the total number of parameters (name-value pairs) that can be included in GET and POST requests.
-
If the number of parameters in a multipart/form request, a POST request, or query string of a GET request exceeds the specified value, a "413 Request Entity Too Large" response will be sent and the request will not be processed.
-
A negative value is considered as the default value, which means there is no limit on the number of parameters.
-
Applies to listeners and connectors that receive HTTP requests. It does not apply to TCP listeners or Tmax connectors.
-
-
Max Header Count
-
A request with too many headers increases the resources required to read the request. This problem can be avoided by blocking the request. (Default value: -1)
-
If a request contains more headers than the specified value, a "400 Bad Request" response will be sent and the connection will be terminated.
-
A negative value is considered as the default value, which means there is no limit on the number of headers.
-
Applies to listeners and connectors that receive HTTP requests. It does not apply to TCP listeners or Tmax connectors.
-
-
Max Header Size
-
A request with a large header size increases the resources required to read the request. This problem can be avoided by blocking the request. (Default value: -1)
-
If a request contains a header, which includes the header name, delimiter, and header value, with a total byte size that is greater than the specified value, a "400 Bad Request" response will be sent and the connection will be terminated.
-
A negative value is considered as the default value, which means there is no limit on the header size.
-
Applies to listeners and connectors that receive HTTP requests. It does not apply to TCP listeners or Tmax connectors.
-
-
Max Query String Size
-
A GET request with a long query string increases the resources required to read the request. This problem can be avoided by limiting the query string size. (Default value: 8192, Unit: bytes)
-
If a request contains a query sting whose size is greater than the specified number of bytes, a "400 Bad Request" will be sent and request will not be processed.
-
If the value is negative, there is no limit on the query string size. Internally, JEUS limits the Request Line to 64 KB, so if the greater number is set, it will not be used.
-
Applies to listeners and connectors that receive HTTP requests. It does not apply to TCP listeners or Tmax connectors.
-
3.2. AJP Listeners
AJP listeners can be added, modified, or deleted in the console tool. AJP listeners comply with AJP 1.3.
Using the Console Tool
The following shows how to add, modify, and delete AJP listeners using the console tool.
-
Adding a listener
To add an AJP listener using the console tool, execute the add-ajp-listener command. For more information about the command, refer to add-ajp-listener in JEUS Reference Guide.
add-ajp-listener [-cluster <cluster-name> | -server <server-name>] [-f, --forceLock] -name <web-connection-name> -tmin <minimum-thread-num> [-tmax <maximum-thread-num>] [-tidle <max-idle-time>] [-qs <max-queue-size>] -slref <server-listener-ref-name>
-
Modifying a Listener
To modify an AJP listener using the console tool, execute the modify-web-listener command. For more information about the command, refer to modify-web-listener in JEUS Reference Guide.
modify-web-listener [-cluster <cluster-name> | -server <server-name>] [-f, --forceLock] -name <web-connection-name> [-tmin <minimum-thread-num>] [-tmax <maximum-thread-num>] [-tidle <max-idle-time>] [-http2 <enable-http2>] [-obuf <output-buffer-size>]
-
Deleting a Listener
To delete an AJP listener using the console tool, execute the remove-web-listener command. For more information about the command, refer to remove-web-listener in JEUS Reference Guide.
remove-web-listener [-cluster <cluster-name> | -server <server-name>] [-f, --forceLock] <web-connection-name>
3.3. HTTP Listeners
HTTP listeners can be added, modified, and deleted in the console tool. Using HTTP listeners is only recommended for internal management.
JEUS 9 supports HTTP/2. For information about how to use HTTP/2, see Using HTTP/2. |
Using the Console Tool
You can use the console tool to add, modify, and delete an HTTP listener, following the same process as for an AJP listener. For HTTP listeners, however, an additional option to use HTTP/2 is provided. For more information about this, refer to Using the Console Tool in AJP Listeners.
3.4. TCP Listeners
A TCP listener is a special listener that allows custom protocols to communicate with each other. TCP listener cannot share server listeners with other web listeners, so a dedicated listener for the TCP listener must be added to the server. TCP listeners can be added or modified in the console tool.
Using the Console Tool
You can use the console tool to add, modify, and delete a TCP listener, following the same process as for an AJP listener. For more information, refer to Using the Console Tool in AJP Listeners.
3.5. WebtoB Connectors
Since JEUS acts as a client when a WebtoB connector creates a connection, the address and port of WebtoB are required. WebtoB connectors can be added, modified, and deleted in the console tool.
The version of the WJP, the communication protocol between WebtoB and JEUS, has been upgraded from 1 to 2 (hereafter WJPv1 and WJPv2). WJPv2 uses a smaller packet sizes than WJPv1 and provides various additional functions. If the WebtoB that JEUS will connect to does not provide WJPv2, WJPv1 is used instead. Since WebtoB cannot obtain the WJP version information, it must be configured in the <wjp-version> option of JEUS. WJP stands for WebtoB-JEUS Protocol. |
Using the Console Tool
The following shows how to add, modify, and delete WebtoB connectors using a console tool.
-
Adding a listener
To add a WebtoB connector using the console tool, execute the add-webtob-connector command. For more information about the command, refer to add-webtob-connector in JEUS Reference Guide.
add-webtob-connector [-cluster <cluster-name> | -server <server-name>] [-f,--forceLock] -name <web-connection-name> -tmin <minimum-thread-num> [-tmax <maximum-thread-num>] [-tidle <max-idle-time>] [-qs <max-queue-size>] -conn <thread-number> -regid <registration-id> [-ver <wjp-version>] [-useNio <use-nio>] [-addr <WebtoB address>] [-dsocket | -port <WebtoB port>] [-wbhome <webtob-home>] [-ipcport <ipc-base-port>] [-sndbuf <send-buffer-size>] [-rcvbuf <receive-buffer-size>] [-hth <set-hth-count.>]
-
Modifying a Listener
To modify the WebtoB connector using the console tool, execute the modify-webtob-connector command. For more information about the command, refer to modify-webtob-connector in JEUS Reference Guide.
modify-webtob-connector [-cluster <cluster-name> | -server <server-name>] [-f,--forceLock] -name <web-connection-name> [-tmin <minimum-thread-num>] [-tmax <maximum-thread-num>] [-tidle <max-idle-time>] [-conn <thread-number>] [-obuf <output-buffer-size>] [-ver <wjp-version>] [-addr <WebtoB address>] [-dsocket | -port <WebtoB port>] [-wbhome <webtob-home>] [-cloud] [-ipcport <ipc-base-port>] [-regid <registration-id>] [-sndbuf <send-buffer-size>] [-rcvbuf <receive-buffer-size>] [-hth <set-hth-count.>]
-
Deleting a Listener
To delete a WebtoB connector using the console tool, execute the remove-webtob-connector command. For more information about the command, refer to remove-webtob-connector in JEUS Reference Guide.
remove-webtob-connector [-cluster <cluster-name> | -server <server-name>] [-f,--forceLock] <web-connection-name>
3.6. Tmax Connectors
Just like with WebtoB connectors, JEUS operates as a client when connected through a Tmax connector, necessitating the specification of Tmax’s address and port. Tmax connectors can be added, modified, or deleted using the console tool.
Using the Console Tool
The following shows how to add, modify, and delete a Tmax connector using the console tool.
-
Adding a listener
To add a Tmax connector using the console tool, execute the add-tmax-connector command. For more information about the command, refer to add-tmax-connector in JEUS Reference Guide.
add-tmax-connector [-cluster <cluster-name> | -server <server-name>] [-f,--forceLock] -name <web-connection-name> -tmin <minimum-thread-num> [-tmax <maximum-thread-num>] [-tidle <max-idle-time>] [-qs <max-queue-size>] -addr <server-address> -port <server-port> -svrg <server-group-name> -svr <server-name> -dcc <dispatcher-config-class>
-
Modifying a Listener
To modify the Tmax connector using the console tool, execute the modify-tmax-connector command. For more information about the command, refer to modify-tmax-connector in JEUS Reference Guide
modify-tmax-connector [-cluster <cluster-name> | -server <server-name>] [-f,--forceLock] -name <web-connection-name> -tmin <minimum-thread-num> [-tmax <maximum-thread-num>] [-tidle <max-idle-time>] [-qs <max-queue-size>] -addr <server-address> -port <server-port> -svrg <server-group-name> -svr <server-name> -dcc <dispatcher-config-class>
-
Deleting a Listener
To delete a Tmax connector using the console tool, execute the remove-tmax-connector command. For more information about the command, refer to remove-tmax-connector in JEUS Reference Guide.
remove-tmax-connector [-cluster <cluster-name> | -server <server-name> | -f,--foreceLock] <web-connection-name>
4. Configuring Web Server Load Balancing
This section describes how to configure web servers and how to connect web connections to the web engine.
Web servers and web engines (servlet engines) can be organized to improve the system performance when processing HTTP requests. First, web servers distribute the HTTP requests to the web engines. After that, they direct the same connections or session requests to the web engine that processed the first request by using HTTP session clustering services to improve service processing efficiency.
If an error occurs in the web engine that first processed the request, requests that are received after the error occurrence will be sent to another web engine to provide seamless services. A cluster is required to perform this task. For more information about HTTP session clustering, refer to Distributed Session Servers in JEUS Session Management Guide.
Even if web engines are used without web servers, equipment or software that can deliver further requests to the web engine that processed the first request can be used to increase efficiency like when using web servers. However, JEUS neither provides this kind of software nor recommends using one.
Web server and mod_jk configurations can differ according to the web server version. The configuration method described here is used for enhancing the understanding of JEUS. When configuring web servers in the production environment, refer to each relevant web server documentations and configuration examples provided by local/overseas communities. |
4.1. Load Balancing Structure
When a web site needs to handle a large number of requests, a single web server and web engine are not sufficient in handling the requests. In such cases, multiple servers and web engines are required for load balancing.
The following diagram shows a load balancing structure in which two web servers are connected to four web engines.
The same web context must be deployed to each engine. In this environment, the most important thing is whether the sessions are shared or not. Web engines must be clustered in order to manage applications more easily or if distributed sessions are required. For more information about session clustering, refer to Session Tracking in JEUS Session Management Guide.
4.2. Apache
Execute the following steps to integrate Apache with the web engines.
-
Install the mod_jk library in Apache.
-
Configure an AJP13 listener in the JEUS web engine.
-
Create and modify the workers.properties file.
-
Insert the integration settings in the httpd.conf file for the Apache web server.
-
Restart the Apache web server.
The description in this guide is based on Apache 2.2.4 and mod_jk 1.2.20. |
Installing the mod_jk Library
To use an Apache web server as a front-end server for the web engine, the mod_jk module must be added to the Apache install module. The mod_jk module implements the Apache JServ Protocol 1.3 (AJP 1.3), a communication protocol between servers and engines.
Download the source from Apache Tomcat Connector Download Page, and compile it on the server. Currently, an executable file for Windows is provided from the site. |
Configuring AJP13 Listeners
After the mod_jk library has been installed, configure the AJP13 listener in the JEUS web engine. For more information about configuring AJP13 listeners, refer to AJP Listeners.
Configuring the workers.properties File
The workers.properties file is a configuration file for mod_jk. For example, there are two JEUS servers named server1 and server2 and the host names are server1 and server2. The name of the web engine for each server is server_servelt and server2_servlet. The AJP listeners configured on each web engine are 9901 and 9902.
The following is the example of a workers.properties file in the described JEUS environment.
worker.list=jeus_load_balancer_workers worker.jeus_load_balancer_workers.type=lb worker.jeus_load_balancer_workers.sticky_session=true ########################################### # listener specific configuration ########################################### worker.jeus_load_balancer_workers.balance_workers=server1 worker.server1.reference=worker.template worker.server1.host=192.168.0.101 worker.server1.port=9901 worker.server1.route=ZG9tYWluMS9zZXJ2MQ== worker.jeus_load_balancer_workers.balance_workers=server2 worker.server1.reference=worker.template worker.server1.host=192.168.0.102 worker.server1.port=9902 worker.server1.route=ZG9tYWluMS9zZXJ2Mg== ########################################### # common config ########################################### worker.template.type=ajp13 worker.template.socket_connect_timeout=5000 worker.template.socket_keepalive=true worker.template.ping_mode=A worker.template.ping_timeout=10000 worker.template.connection_pool_minsize=0 worker.template.connection_pool_timeout=600 worker.template.reply_timeout=300000 worker.template.recovery_options=3
The workers.properties file uses the "worker.<worker_name>.<directive>=<value>" format to define most settings.
The following describe the major configuration items.
-
worker.list
Worker names. Multiple workers can be defined and each worker name is separated by a comma (",").
The following example defines a worker with the name "jeus_load_balancer_workers".
worker.list=jeus_load_balancer_workers
-
worker.<worker_name>.type
Worker types. 'ajp13', 'ajp14', 'jni', 'lb', and 'status' can be used. To support AJP13, setting 'ajp13', and 'lb' are sufficient in JEUS.
The following example defines "jeus_load_balancer_workers" as a load balancer.
worker.jeus_load_balancer_workers.type=lb
-
worker.<worker_name>.balance_workers
A comma (',') can be used to list the workers for load balancing. The workers written in worker.list above cannot be in this list.
When integrating with an AJP13 listener in JEUS, the worker names must be the servlet engines of JEUS for the workers to properly function as load balancers or sticky sessions. JEUS uses the servlet engine names for the session ID routing information, and mod_jk uses the worker names.
-
worker.<worker_name>.sticky_session
Option to support routing based on session ID. Options are 'true'(or 1) or 'false'(or 0). Since JEUS supports sticky sessions, this must be always set to 'true'. (Default value: true)
The following example sets the "jeus_load_balancer_workers" setting to support sticky sessions.
worker.jeus_load_balancer_workers.sticky_session=true
-
worker.<worker_name>.host
Host name or IP address where the AJP13 listener exists.
-
worker.<worker_name>.port
AJP listener port number in JEUS.
-
worker.<worker_name>.reference
Useful for configuring multiple load balancer workers. The specified workers can be referenced. For example, if "worker.castor.reference=worker.template" is set, all worker.template configurations will be inherited except configuration values that are explicitly set for castor workers.
-
worker.<worker_name>.route
A sticky session is a session routing technology used in sessions that are created by the JEUS session manager. By matching the session with a worker, this can improve the availability of local sessions. For more information about session routing, refer to Session Tracking Structure in JEUS Session Management Guide.
The value domain_name/server_name is encoded in Base16. The encoded value can be retrieved by using the encryption command in the 'JEUS_HOME/bin' directory.
The following is an example of using the encryption command.
${JEUS_HOME}/bin/encryption -algorithm base64 -text domain1/server1
Note that a "domain name/server" format is used as in "domain1/server1" or "domain1/server2".
Since this configuration information may not be current for the latest version of mod_jk, use the examples in this section only for reference. To configure the settings, mod_jk related descriptions in the Tomcat site must be followed.
Configuring httpd.conf
To use the mod_jk module, add the following to the httpd.conf file.
. . . LoadModule jk_module "/usr/local/apache/modules/mod_jk.so" JkWorkersFile "/usr/local/apache/conf/workers.properties" JkLogFile "/usr/local/apache/logs/mod_jk.log" JkLogLevel info JkMount /examples/* jeus_load_balancer_workers . . .
Since this configuration information may not be current for the latest version of Apache, use the examples in this section only for reference. Refer to the Apache manuals. |
4.3. IIS and Iplanet Web Servers
IIS and Iplanet support the AJP13 protocol. The workers.properties file is configured in the same way as JEUS, but mod_jk is installed and configured differently. Refer to the manual of each web server.
4.4. Load Balancing with WebtoB
This section describes how to configure load balancing between WebtoB and JEUS with some examples.
The following shows the server structure of the example. Each engine is connected a WebtoB server. In the following example, there are two WebtoB servers and each one is connected to two web engines.
The same context must be deployed to each server. In general, in a structure like the previous figure, servers A through D become clustered and distributed session servers are used accordingly. Clustering is not necessary if user sessions are not used.
The following diagram shows the dotted box above in detail and displays each WebtoB connector configurations.
When configuring WebtoB connectors, the number of WebtoB HTH processes must be considered.
A WebtoB HTH process behaves as an engine having multiple sub-processes. It establishes a 1 to 1 connection with the worker thread in the WebtoB connector. Therefore, it must be configured by considering the 'connection-count' value for the WebtoB connector and the 'MaxProc' value in the WebtoB configuration.
The number of HTH processes in the WebtoB configuration can be set in the 'Hth Count' setting for the WebtoB connector. The 'MaxProc' value of WebtoB and the 'connection-count' value of the WebtoB connector can be expressed using the following formulas.
MinProc = Listener A connection-counts + Listener B connection-counts + … + Listener X connection-counts setting. MaxProc = Listener A connection-counts + Listener B connection-counts + … + Listener X connection-counts setting.
The 'Hth Count' of the WebtoB connector must be the same as the number of HTH processes in the *NODE configuration in the WebtoB configuration file. For more information about configuring WebtoB connectors, refer to WebtoB Connectors.
The following example of the http.m file configures WebtoB A from the previous example.
*NODE foo … HTH = 2, JSVPORT = 9900, … *SVRGROUP jsvg NODENAME = foo, SVRTYPE = JSV *SERVER default SVGNAME = jsvg, MinProc = 6, MaxProc = 25 *URI uri1 Uri = "/examples/", Svrtype = JSV uri2 Uri = "/test/", Svrtype = JSV *EXT jsp MimeType = "application/jsp", SvrType = JSV
The connection count must be between 6 and 25.
5. Using TCP Listeners
TCP listeners can define a communication protocol between TCP clients and TCP servlets, but they are only recommended when the HTTP and HTTPS protocols are not sufficient.
Execute the following steps to use a TCP listener.
-
Define a customized communication protocol.
-
Implement the dispatcher config class (Protocol configuration)
-
Implement the TCP handler servlet (Protocol implementation)
-
Set the TCP listener to implement the custom protocol.
-
Implement the TCP client.
-
Compile and run the TCP client.
The following are the terms used in this section.
Term | Description |
---|---|
Protocol(communication protocol) |
Defines the message structure and contents that are exchanged between the TCP client and TCP handler (TCP listener is a mediator). |
Message |
Data exchanged between the TCP client and TCP handler. Must follow the structure defined in the protocol. |
TCP Client |
External application, which is processed by the TCP handler, that communicates and exchanges messages with the TCP listener. A standard socket is used to exchange messages. |
TCP Handler |
Receives messages from the TCP listener and processes them. The TCP handler is implemented as a subclass of jeus.servlet.tcp.TCPServlet and is registered in the web engine like regular servlets. The TCP handler works as if it is the provider or implementation class of the custom protocol that exist above the TCP protocol. |
TCP Dispatcher Configuration Class |
Extended class of jeus.servlet.tcp.TCPDispatcherConfig. This class sends the custom protocol information to the TCP listener and processes non-HTTP messages. Place the class in the 'DOMAIN_HOME/lib/application' directory, and configure 'Dispatcher Config Class' for the TCP listener in the web engine configuration. (See TCP Listeners) |
TCP Listener |
Interprets custom messages and provides the routing infrastructure. This acts as a non-HTTP mediator between the TCP client and TCP handler. Similar to other HTTP listeners, this exists in the web engine. |
5.1. Defining Custom Communication Protocols
The TCP listener divides all messages that are exchanged between TCP client and TCP handler into two parts, the header and body. In general, the header is fixed in size and contains standard information. The body contains user data, such as the HTML code in an HTTP response, to transmit.
This section defines a simple protocol (message structure) to describe how to use the TCP listener.
The custom communication protocol (custom message structure) contains the following contents.
-
Header
-
The header starts with a 4 byte magic number. This is used to identify the protocol. For the example, set it to '7777'.
-
Next is a 1 byte type field. '0' indicates a request and '1' indicates a response.
-
The third item is a 4 byte body length. This item contains the body length in bytes. It is fixed at 128 bytes.
-
The last item is a 32 byte string called service name. For the example, enter the name of the TCP servlet that handles the request.
-
-
Body
-
The body contains 128 bytes of character data. In this example, enter the 128 byte block as two 64 byte strings.
-
5.2. Implementing Dispatcher Configuration Classes
A dispatcher configuration class is a subclass of the jeus.servlet.tcp.TCPDispatcherConfig class. The abstract method of the class must implement the information required for the TCP listener to deliver messages to the appropriate TCP handler. The methods are described in JEUS_HOME/docs/api/jeus-servlet/index.html.
From JEUS 7 Fix #1 onwards, the getBodyLengthLong method has been added. If the TCP Body is 2 GB or more, the Body length can be set to 8 bytes by using this method.
The following code shows how the dispatcher configuration class is implemented based on the defined protocol. To understand how the methods are used, refer to comments in the following example.
package sample.config;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jeus.servlet.tcp.*;
/*
This class extends the abstract class jeus.servlet.tcp.
TCPDispatcherConfig class. This implementation provides
routing and handling information to the TCP listener
according to our defined communications protocol.
*/
public class SampleConfig extends TCPDispatcherConfig {
/*
Any init code goes into this method. This method will be
Called once after starting the TCP listener.
We leave this method empty for our simple example.
*/
public void init() {}
/*
This method returns the fixed-length of the header so
that the TCP listener knows when to stop
reading the header. The header length for
our example is 41 (bytes): 4 (magic) + 1
(type) + 4 (body length) + 32 (service name).
*/
public int getHeaderLength() {
return 41;
}
/*
This method must return the length of the body.
For our example, this length is represented as an
“int” in the header, starting at position “5”
(see the protocol definition above).
*/
public int getBodyLength(byte[] header) {
return getInt(header, 5);
}
/**)
* Returns the long-size length of request body of
* incoming request packet.
* If you don't need to support long, you may map to
* {@link #getBodyLength(byte[])}.
*/
public long getBodyLengthLong(byte[] header) {
return getBodyLength(header);
}
/*
This method must return the context path so that the
request can be routed by the TCP listener to the context
that contains the TCP handler (TCPServlet implementation).
For our example, we always use the context path “/tcptest”.
*/
public String getContextPath(byte[] header) {
return "/tcptest";
}
/*
This method must return the name (path) of the TCP
handler(TCPServlet) relative to the context path.
For our example, we fetch this name from the 9th position
in the header.
*/
public String getServletPath(byte[] header) {
return "/" + getString(header, 9, 32);
}
/*
This method returns some path info from the header.
It is not used in our example and thus returns “null”.
*/
public String getPathInfo(byte[] header) {
return null;
}
/*
This method returns any session ID embedded in the header.
It is not used in our example and thus returns “null”.
*/
public String getSessionId(byte[] header) {
return null;
}
/*
This method determines whether the TCP listener
should keep the socket connection open after the TCP handler
has delivered its response. If it returns “false”, the
connection will be dropped like in HTTP communications.
If it returns “true” the connection will be kept open
like in the Telnet or FTP protocols. For our example,
we choose to make it persistent (connection not closed
by the TCP listener).
*/
public boolean isPersistentConnection() {
return true;
}
}
5.3. Implementing TCP Servlets
TCP servlets are always a subclass of the jeus.servlet.tcp.TCPServlet class. The handler always contains the abstract void service (TCPServletRequest req, TCPServletResponse, res) method that is overridden.
The service method must be implemented to process messages that follow the custom protocol. The web container reads a header and sends it to the TCPServletRequest object, and the TCP servlet writes a response to an output stream of the TCPServletResponse object.
The following is an implementation of the TCP servlet that processes the message that follows the custom protocol.
package sample.servlet;
import java.io.*;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jeus.servlet.tcp.*;
/**
* Sample TCPServlet implementation
*
* Protocol scheme:
*
* common header (for request and response) : total 41 byte
*
* magic field: length = 4 byte, value = 7777
* type field : length = 1 byte, 0 : request, 1:response
* body length field : length = 4, value = 128
* service name field : length = 32
*
* request and response body
*
* message1 field : length = 64
* message2 field : length = 64
*
*/
public class SampleTCPServlet extends TCPServlet {
public void init(ServletConfig config) throws ServletException {
}
public void service(TCPServletRequest req, TCPServletResponse res)
throws ServletException, IOException {
ServletContext context = req.getServletContext();
byte[] header = req.getHeader();
byte[] body = new byte[req.getContentLength()];
int read = req.getInputStream().read(body);
if (read < body.length) {
throw new IOException("The client sent the wrong content.");
}
String encoding = res.getCharacterEncoding();
if (encoding == null)
encoding = "euc-kr";
DataInputStream in = new DataInputStream(new ByteArrayInputStream(header));
int magic = in.readInt();
context.log("[SampleTCPServlet] received magic = " + magic);
byte type = (byte)in.read();
context.log("[SampleTCPServlet] received type = " + type);
int len = in.readInt();
context.log("[SampleTCPServlet] received body length = " + len);
byte[] svcname = new byte[32];
in.readFully(svcname);
context.log("[SampleTCPServlet] received service name = "
+ (new String(svcname)).trim());
String rcvmsg = null;
rcvmsg = (new String(body, 0, 64)).trim();
context.log("[SampleTCPServlet] received msg1 = " + rcvmsg);
try {
rcvmsg = (new String(body, 64, 64, encoding)).trim();
} catch (Exception e) {}
context.log("[SampleTCPServlet] received msg2 = " + rcvmsg);
String msg1 = "test response";
String msg2 = "test response2";
byte[] result1 = null;
byte[] result2 = null;
if (encoding != null) {
try {
result1 = msg1.getBytes(encoding);
result2 = msg2.getBytes(encoding);
} catch (UnsupportedEncodingException uee) {
result1 = msg1.getBytes();
result2 = msg2.getBytes();
}
} else {
result1 = msg1.getBytes();
result2 = msg2.getBytes();
}
header[4] = (byte)1; // mark as response
ServletOutputStream out = res.getOutputStream();
out.write(header);
byte[] buf1 = new byte[64];
System.arraycopy(result1, 0, buf1, 0, result1.length);
out.write(buf1);
byte[] buf2 = new byte[64];
System.arraycopy(result2, 0, buf2, 0, result2.length);
out.write(buf2);
out.flush();
}
public void destroy() {
}
}
From JEUS 7 Fix #2 onwards, it is not recommended to use the TCPServletRequest.getBody() method. This method may cause a memory issue if the request body is too big. It is recommended to use the ServletInputStream class defined in the servlet standard instead. This object can be obtained by using the TCPServletRequest.getInputStream() method. |
5.4. Configuring TCP Listeners for Custom Protocols
Configure the TCP listener based on the SampleConfig.java and SampleTCPServlet.java implementations and using the following steps.
-
Configure the TCP listener information in the web engine. For more information about TCP listeners, see TCP Listeners. Ensure that the server listener port to which the TCP listener refers to '5555', and set 'Dispatcher Config Class' to 'sample.config.SampleConfig'.
-
Start the JEUS server and deploy the web application that contains the previous TCP servlet. The following is an example of the deployment descriptor for the web application.
TCP Handler Deployment Descriptor: <web.xml><?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" metadata-complete="false" version="5.0"> <display-name>test</display-name> <distributable/> <servlet> <servlet-name>SampleServlet</servlet-name> <servlet-class>sample.servlet.SampleTCPServlet</servlet-class> <load-on-startup>0</load-on-startup> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>SampleServlet</servlet-name> <url-pattern>/sample</url-pattern> </servlet-mapping> <login-config> <auth-method>BASIC</auth-method> </login-config> </web-app>
5.5. Implementing TCP Clients
TCP clients connect to TCP listeners using a socket and uses the connection to send messages. The messages are byte streams that follow the custom protocol defined in Defining Custom Communication Protocols.
The TCP listener receives the messages and calls the service() method of the SampleTCPservlet class based on dispatch information defined in the SampleConfig class. The SampleTCPServlet creates the response based on the client data and delivers it. The client receives the response and outputs it using System.out.
The following is the example of a TCP client implementation.
package sample.client;
import java.io.;
import java.net.;
public class Client {
private String address;
private int port;
private int magic = 7777;
private byte type = 0;
private int bodyLength = 128;
private byte[] serviceName="sample".getBytes();
public Client(String host, int port) {
this.address = host;
this.port = port;
}
public void test()
throws IOException, UnsupportedEncodingException {
Socket socket = new Socket(address, port);
DataOutputStream out = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream()));
DataInputStream in = new DataInputStream(
new BufferedInputStream(socket.getInputStream()));
out.writeInt(7777);
out.write(type);
out.writeInt(bodyLength);
byte[] buf = new byte[32];
System.arraycopy(serviceName, 0, buf, 0, serviceName.length);
out.write(buf);
byte[] msg1 = "test request".getBytes();
byte[] msg2 = "test request2".getBytes();
buf = new byte[64];
System.arraycopy(msg1, 0, buf, 0, msg1.length);
out.write(buf);
buf = new byte[64];
System.arraycopy(msg2, 0, buf, 0, msg2.length);
out.write(buf);
out.flush();
// rx msg
int magic = in.readInt();
System.out.println("[Client] received magic = " + magic);
byte type = (byte)in.read();
System.out.println("[Client] received type = " + type);
int len = in.readInt();
System.out.println("[Client] received body length = " + len);
byte[] svcname = new byte[32];
in.readFully(svcname);
System.out.println("[Client] received service name = " +
(new String(svcname)).trim());
byte[] body = new byte[128];
in.readFully(body);
String rcvmsg = null;
rcvmsg = (new String(body, 0, 64)).trim();
System.out.println("[Client] received msg1 = " + rcvmsg);
rcvmsg = (new String(body, 64, 64, "euc-kr")).trim();
System.out.println("[Client] received msg2 = " + rcvmsg);
out.close();
in.close();
socket.close();
}
public static void main(String[] argv) throws Exception {
Client client = new Client("localhost", 5555);
client.test();
}
}
In the previous client code, note the various field configurations of the header that are required for the protocol.
The 'magic' number is set to '7777', the 'type' is set to '0' (request), the 'body length' is set to '128 bytes' (fixed length), and the 'service name' is set to 'sample'. (The name of SampleServlet is specified in web.xml.). After creating two messages, the header information is sent and the messages are sent to the TCP listener. Finally, the 'hostname' is set to 'localhost' and the port number is set to '5555'.
5.6. TCP Client Compilation and Execution
Assume that the TCP listener is set to 'localhost' with the port number '5555'. The TCP client is compiled and executed using the following steps.
-
Compile Client.java.
javac -classpath ${JEUS_HOME}/lib/system/jeus.jar -d . Client.java
-
Execute Client.class.
java -classpath ${JEUS_HOME}/lib/system/jeus.jar:. sample.client.Client
-
The JEUS administrator console must display the result of the TCP handler. (SampleServlet class).
[SampleServlet] received magic = 7777 [SampleServlet] received type = 0 [SampleServlet] received body length = 128 [SampleServlet] received service name = sample [SampleServlet] received msg1 = test request [SampleServlet] received msg2 = test request2
-
The following messages are displayed on the client screen.
[Client] received magic = 7777 [Client] received type = 1 [Client] received body length = 128 [Client] received service name = sample [Client] received msg1 = test response [Client] received msg2 = test response2
6. Using HTTP/2
HTTP/2 is the next version of HTTP/1.1. It is a new and improved HTTP standard.
The following describes the characteristics of HTTP/2.
-
Header Compression
HTTP/2 uses Huffman coding to compresses and send headers. Also, each server and client creates an index in the header table so that repeated headers are not sent multiple times. The number of headers to be indexed can be set by using Settings Header Table Size.
-
Request/Response Multiplexing
HTTP/2 refers to a series of request/reponse as a stream. A stream consists of multiple frames such as a headers frame and a data frame. The basic protocol unit in HTTP/2 is a frame. In HTTP/1.1, a single request can be sent after completing a single request/response. However in HTTP/2, multiple streams (requests) can be created and sent concurrently.
The Settings Max Concurrent Streams setting specifies how many streams are to be used concurrently. The size of a data frame can be set through the Settings Max Frame Size setting.
-
Server Push
For information about Server Push, refer to Server Push.
This guide only provides information about how to use HTTP/2 in JEUS. For more information about HTTP/2, refer to "RFC Documentation". |
6.1. Configuring HTTP/2
HTTP/2 uses two identifiers, h2c and h2. The following table describes each identifier.
Term | Description |
---|---|
h2c |
Indicates HTTP/2. "HTTP" is used. |
h2 |
Indicates HTTP/2 that runs by using TLS (Transport Layer Security). "https" is used. |
Most browsers only support h2, and do not support h2c. |
To utilize HTTP/2 by using h2, additional work is required. h2 runs by using TLS (Transport Layer Security), and must use the ALPN (Application Layer Protocol Negotiation) function during a TLS handshake process. Since h2 runs by using TLS, it must use a port set with a secure listener.
The following tasks are required to use ALPN.
Since OpenJDK 8u252 version, ALPN is supported by JDK itself from OpenJDK 8u252 version onwards, so Jetty ALPN setting is not necessary as a JVM option. This may vary depending on the JDK. |
-
In the following address, check the appropriate alpn-boot library for the JDK version to be used, and then download it in the "MVN Repository".
http://www.eclipse.org/jetty/documentation/current/alpn-chapter.html#alpn-versions
The alpn-boot library only supports OpenJDK and OracleJDK. Currently, HTTP/2 cannot be used in IBM JDK.
-
Add the <jvm-option>, which adds the downloaded alpn-boot library to bootclasspath, to domain.xml.
<jvm-config> <jvm-option>-Xbootclasspath/p:<path_to_alpn_boot_jar> ...</jvm-option> </jvm-config>
|
6.2. Server Push
Server Push is a function in which a response is sent by a server even if a client does not send a request for a specified resource. This decreases the amount of time required for sending a request, which results in faster response. To use the Server Push function, specify a resource to be server pushed during web application development.
Server Push is implemented based on the Servlet 4.0 API. |
The following describes how Server Push is used: a PushBuilder object is obtained, then the resource path is specified, and then the push() method is called.
Server Push gets a PushBuilder object, and then specifies the resource path, and then calls the push() method. The following is an example of using Server Push.
package sample.serverpush
...
@WebServlet("/ServerPush")
public class ServerPushServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PushBuilder builder = req.newPushBuilder();
String pushResourcePath = "resources/a.txt";
// Enter the path of the resource to push and then call the push() method.
builder.path(pushResourcePath);
builder.push();
resp.getWriter().write("main page\n");
}
}
If Server Push is specified to be not used, then the above example will have no effect. |
7. Tuning Listeners
Consider the following when configuring listeners for optimal performance.
-
Increase the out buffer size by using many system resources or prolonging the waiting time.
-
In general, if the min, max, and step values of the worker thread pool are large, performance improves when many clients access the web engine. To use less memory, lower these values.
-
Disabling the 'Server Access Control' setting may improve performance.
-
As described earlier, in the WebtoB connector, set the number of worker threads for the web connector of the web engine equal to the value in http.m.