Create a dedicated thread pool for WebSphere Commerce REST requests
If you plan to use the Search Rule feature, a dedicated thread pool is needed to prevent a deadlock in requests between the WebSphere Commerce and Search servers.
Task info
When the Search rules feature is enabled, multiple simultaneous callback requests can be made from the Search server to the WebSphere Commerce server. To prevent callback requests from impacting performance, create a custom thread pool to manage the callbacks. This custom thread pool services all REST requests to the WebSphere Commerce server. In the following diagram, the custom thread pool can be seen in the WebSphere Commerce server box, as the REST service that sends REST requests to the Solr index.
In standard configurations, request callbacks from the Search server are served by the Classic thread pool in the Transaction Server. The default number of threads is sufficient for this configuration. However, when the system is configured for Search Rule pricing the number of callbacks from the Search server can increase, potentially using all the available Classic threads. With the custom thread pool in place, all REST requests made by the WebSphere Commerce server is managed separately, eliminating deadlocks in the Classic pool.
Procedure
- Create a custom thread pool.
- Start the WebSphere Application Server Administration Console and open the Application Servers > Server1 > Thread pools > New form.
- Type the name RestContainer in the General Properties field.
- Enter a Minimum Size and Maximum Size for the thread pool that is the same size as the WebContainer thread pool (for instance, 25 and 25).
- Choose a Thread inactivity timeout, in milliseconds, such as 5000.
- Create a transport chain.
- Open the Application servers > server1 > Web container transport chains form.
- Under Step 1: Select a transport chain template, enter a Transport chain name of WC_CHAIN_6. The Transport chain template is WebContainer(templates/chains|webcontainer-chains.xml#Chain_1).
- Under Step 2: Select a port, choose Create a new port. Select the REST Port name (normally REST_8008) and Port (8008, if it is not already used by another service), and enter an asterisk ("*" character) in the Host field.
Verify that the resource is running by opening the Preferences list.
- Enable an inbound TCP channel to use the Thread pool.
- Open the Application servers > server1 > Web container transport chains > WC_CHAIN 6 > TCP inbound channel (TCP_6) form.
- In the Thread pool list, choose RestContainer, and save the form.
- Ensure that the web server does not overwrite the relevant configuration file, plugin-cfg.xml, during regeneration of the plug-ins.
- If we are using the IBM HTTP Server for WebSphere Application Server, check to see whether the httpd.conf file contains a WebSpherePluginConfig field. If it does not, proceed to Step 5.
- If WebSpherePluginConfig points to /opt/WebSphere/AppServer/profiles/<instance-name>/config/cells/WC_<demo>_cell/nodes/WC_<instance-name>_node/servers/webserver1/plugin-cfg.xml (where <instance-name> is specific to your system), change the address to point to a temporary copy of the file. This configuration prevents the web server from overwriting the file during the regeneration step.
- Open the Web servers > webserver1 > Plug-in properties form and choose the Configuration tab. Clear the box Automatically propagate plug-in configuration file. This feature must be disabled to allow time for manual modification of the plugin-cfg.xml file.
Note: The plugin-cfg.xml is automatically regenerated from time to time, especially when you apply interim fixes. Therefore, Administrative users need to manually complete Step 6 whenever new fixes are installed.
- Regenerate the web server plug-ins. We can confirm the success of this operation by opening the file /usr/WebSphere/AppServer/profiles/demo/config/cells/WC_demo_cell/nodes/WC_demo_node/servers/webserver1/plugin-cfg.xml. The <ServerCluster> element contains a new <Transport> element corresponding to the new configuration, as in the following example.
<ServerCluster CloneSeparatorChange="false" GetDWLMTable="false" IgnoreAffinityRequests="true" LoadBalance="Round Robin" Name="server1_WC_demo_node_Cluster" PostBufferSize="64" PostSizeLimit="-1" RemoveSpecialHeaders="true" RetryInterval="60" ServerIOTimeoutRetry="-1"> <Server ConnectTimeout="0" ExtendedHandshake="false" MaxConnections="-1" Name="Your_server_name" ServerIOTimeout="0" WaitForContinue="false"> <Transport Hostname="WC_HOSTNAME" Port="9101" Protocol="http"/> <Transport Hostname="WC_HOSTNAME" Port="8008" Protocol="http"/> </Server> </ServerCluster>
- Search for the string <Uri AffinityCookie="JSESSIONID" AffinityURLIdentifier="jsessionid" Name="/wcs/resources/*"/> in the file and remove any instance of this string from your existing UriGroups. Important: We must remove this string because the element is mapped to a new Your_server_cluster_REST_URIs UriGroup in the next step.
- To complete the configuration, manually add a <ServerCluster> element to the plugin-cfg.xml file. Move the new <Transport> element into the new <ServerCluster> tree, as in the following example.
<ServerCluster CloneSeparatorChange="false" GetDWLMTable="false" IgnoreAffinityRequests="true" LoadBalance="Round Robin" Name="server1_WC_demo_node_Cluster_REST" PostBufferSize="64" PostSizeLimit="-1" RemoveSpecialHeaders="true" RetryInterval="60" ServerIOTimeoutRetry="-1"> <Server ConnectTimeout="0" ExtendedHandshake="false" MaxConnections="-1" Name="Your_server_name" ServerIOTimeout="0" WaitForContinue="false"> <Transport Hostname="WC_HOSTNAME" Port="8008" Protocol="http"/> </Server> </ServerCluster> <UriGroup Name="Your_server_cluster_REST_URIs"> <Uri AffinityCookie="JSESSIONID" AffinityURLIdentifier="jsessionid" Name="/wcs/resources/*"/> </UriGroup> <Route ServerCluster="Your_server_name" UriGroup=" Your_server_cluster_REST_URIs" VirtualHostGroup="VH_demo"/> <ServerCluster CloneSeparatorChange="false" GetDWLMTable="false" IgnoreAffinityRequests="true" LoadBalance="Round Robin" Name="server1_WC_demo_node_Cluster" PostBufferSize="64" PostSizeLimit="-1" RemoveSpecialHeaders="true" RetryInterval="60" ServerIOTimeoutRetry="-1"> <Server ConnectTimeout="0" ExtendedHandshake="false" MaxConnections="-1" Name="WC_demo_node_server1" ServerIOTimeout="0" WaitForContinue="false"> <Transport Hostname="WC_HOSTNAME" Port="9101" Protocol="http"/> </Server> </ServerCluster>
- If you directed the web server to look for a temporary plugin-cfg.xml file in Step 4, reverse the change so that the correctly updated plugin-cfg.xml file is found on restarting the web server.
- Restart the web server, and server1.
What to do next
You are encouraged to optimize the flow of transactions. Follow these guidelines:
- Ensure that REST requests are optimized in fetching only the content required and not more information than necessary.
- Reduce the number of callbacks from the Search server if possible. For information on how to reduce callbacks, see Disable the remote Business Context Service (BCS) call.
- Test and validate optimal thread setting across both WebSphere Commerce and Solr servers. Ensure that there are sufficient threads to handle the expected concurrency and hardware use.