17.3. Connector Configuration
17.3.1. Define Thread Pools for HTTP Connector in JBoss EAP 6
Thread Pools in JBoss EAP 6 can be shared between different components using the Executor model. These pools can be shared not only by different (HTTP) connectors, but also by other components within JBoss EAP 6 that support the Executor model. Getting the HTTP connector thread pool to match your current web performance requirements is tricky and requires close monitoring of the current thread pool and the current and anticipated web load demands. In this task, you will learn how to set the a thread pool for an HTTP Connector using the Executor model. You will learn how to set this using both the Management CLI and by modifying the XML configuration file.
Note
/profile=PROFILE_NAME
to all Management CLI commands in this procedure.
Procedure 17.2. Setup a thread pool for an HTTP Connector
Define a thread factory
Open up your configuration file (standalone.xml
if modifying for a standalone server ordomain.xml
if modifying for a domain based configuration. This file will be in theEAP_HOME/standalone/configuration
or theEAP_HOME/domain/configuration
folder).Add the following subsystem entry, changing the values to suit your server requirements.<subsystem xmlns="urn:jboss:domain:threads:1.1"> <thread-factory name="http-connector-factory" thread-name-pattern="HTTP-%t" priority="9" group-name="uq-thread-pool"/> </subsystem>
If you prefer to use the Management CLI to do this task, then execute the following command in a CLI command prompt:[standalone@localhost:9999 /] ./subsystem=threads/thread-factory=http-connector-factory:add(thread-name-pattern="HTTP-%t", priority="9", group-name="uq-thread-pool")
Create an executor
You can use one of six in-built executor classes to act as the executor for this factory. The six executors are:unbounded-queue-thread-pool
: This type of thread pool always accepts tasks. If fewer than the maximum number of threads are running, a new thread is started up to run the submitted task; otherwise, the task is placed into an unbounded FIFO queue to be executed when a thread is available.Note
The single-thread executor type provided byExecutors.singleThreadExecutor()
is essentially an unbounded-queue executor with a thread limit of one. This type of executor is deployed using theunbounded-queue-thread-pool-executor
element.bounded-queue-thread-pool
: This type of executor maintains a fixed-length queue and two pool sizes: acore
size and amaximum
size. When a task is accepted, if the number of running pool threads is less than thecore
size, a new thread is started to execute the task. If space remains in the queue, the task is placed in the queue. If the number of running pool threads is less than themaximum
size, a new thread is started to execute the task. If blocking is enabled on the executor, the calling thread will block until space becomes available in the queue. The task is delegated to the handoff executor, if a handoff executor is configured. Otherwise, the task is rejected.blocking-bounded-queue-thread-pool
: A thread pool executor with a bounded queue where threads submittings tasks may block. Such a thread pool has a core and maximum size and a specified queue length. When a task is submitted, if the number of running threads is less than the core size, a new thread is created. Otherwise, if there is room in the queue, the task is enqueued. Otherwise, if the number of running threads is less than the maximum size, a new thread is created. Otherwise, the caller blocks until room becomes available in the queue.queueless-thread-pool
: Sometimes, a simple thread pool is required to run tasks in separate threads, reusing threads as they complete their tasks with no intervening queue. This type of pool is ideal for handling tasks which are long-running, perhaps utilizing blocking I/O, since tasks are always started immediately upon acceptance rather than accepting a task and then delaying its execution until other running tasks have completed. This type of executor is declared using thequeueless-thread-pool-executor
element.blocking-queueless-thread-pool
: A thread pool executor with no queue where threads submittings tasks may block. When a task is submitted, if the number of running threads is less than the maximum size, a new thread is created. Otherwise, the caller blocks until another thread completes its task and accepts the new one.scheduled-thread-pool
:This is a special type of executor whose purpose is to execute tasks at specific times and time intervals, based on thejava.util.concurrent.ScheduledThreadPoolExecutor
class. This type of executor is configured with thescheduled-thread-pool-executor
element:
In this example, we will use theunbounded-queue-thread-pool
to act as the executor. Modify the values ofmax-threads
andkeepalive-time
parameters to suit your server needs.<unbounded-queue-thread-pool name="uq-thread-pool"> <thread-factory name="http-connector-factory" /> <max-threads count="10" /> <keepalive-time time="30" unit="seconds" /> </unbounded-queue-thread-pool>
Or if you prefer to use the Management CLI:[standalone@localhost:9999 /] ./subsystem=threads/unbounded-queue-thread-pool=uq-thread-pool:add(thread-factory="http-connector-factory", keepalive-time={time=30, unit="seconds"}, max-threads=30)
Make the HTTP web connector use this thread pool
In the same configuration file, locate the HTTP connector element under the web subsystem and modify it to use the thread pool defined in the previous steps.<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" executor="uq-thread-pool" />
Again, if you prefer to use the Management CLI:[standalone@localhost:9999 /] ./subsystem=web/connector=http:write-attribute(name=executor, value="uq-thread-pool")
Restart the server
Restart the server (standalone or domain) so that the changes can take effect. Use the following Management CLI commands to confirm if the changes from the steps above have taken place:[standalone@localhost:9999 /] ./subsystem=threads:read-resource(recursive=true) { "outcome" => "success", "result" => { "blocking-bounded-queue-thread-pool" => undefined, "blocking-queueless-thread-pool" => undefined, "bounded-queue-thread-pool" => undefined, "queueless-thread-pool" => undefined, "scheduled-thread-pool" => undefined, "thread-factory" => {"http-connector-factory" => { "group-name" => "uq-thread-pool", "name" => "http-connector-factory", "priority" => 9, "thread-name-pattern" => "HTTP-%t" }}, "unbounded-queue-thread-pool" => {"uq-thread-pool" => { "keepalive-time" => { "time" => 30L, "unit" => "SECONDS" }, "max-threads" => 30, "name" => "uq-thread-pool", "thread-factory" => "http-connector-factory" }} } } [standalone@localhost:9999 /] ./subsystem=web/connector=http:read-resource(recursive=true) { "outcome" => "success", "result" => { "configuration" => undefined, "enable-lookups" => false, "enabled" => true, "executor" => "uq-thread-pool", "max-connections" => undefined, "max-post-size" => 2097152, "max-save-post-size" => 4096, "name" => "http", "protocol" => "HTTP/1.1", "proxy-name" => undefined, "proxy-port" => undefined, "redirect-port" => 443, "scheme" => "http", "secure" => false, "socket-binding" => "http", "ssl" => undefined, "virtual-server" => undefined } }
You have successfully created a thread factory and an executor and modified your HTTP Connector to use this thread pool.