Many sites have a need to integrate with one or more third party external systems, whether this need is for transferring orders, fetching tax information, pricing, payments, etc. These integrations may operate over a variety of transport methods such as MQ/JMS, HTTP WebServices or RESTful services. Whenever developing an external systems integration solution, one key factor to keep in mind is to ensure that if the external service becomes unavailable, it does not bring down your Commerce storefront with it. This is especially important in cases where the execution of the external calls are directly associated with shoppers' actions on the site-- for instance, viewing a product display page and fetching a price, adding an item to the cart and fetching tax or shipping information, or checking out and transferring an order.
Here are some general guidelines to follow when developing an external systems integration solution:
- Whenever possible, try to separate any invocations to external systems from shoppers' actions on the site. If you need to transfer an order at checkout to an external service, instead of doing it during the user's OrderProcess transaction, leverage the sendTransacted() API provided with Commerce in your command logic to store the message in the database. Schedule the SendTransactedMsg job to run periodically in the background to send out these order messages captured in the database. This technique ensures we don't block valuable threads in the WebContainer pool while waiting on responses from back-end services. More available threads = more potential active shoppers on your site = more throughput! See my other blog post below for specific configuration recommendations when scheduling the SendTransactedMsg job:
E-mail best practices (see steps 1-3)
See the following document for examples on leveraging the sendTransacted() method:
Examples: Outbound messaging using SendMsgCmd
- When you are able to, cache data from external systems to reduce the number of outbound calls and overall real-time dependency on the external system. For example, the IBM Sterling Order Management and WebSphere Commerce direct inventory integration leverages a local database cache to store inventory quantities fetched from the external Order Management system. Within that configuration, timeout and quantity thresholds are set to determine when an actual outbound call is absolutely required. With this approach, we can rely primarily on locally cached data for most requests with a low dependency on the external system's availability.
- Employ the use of a circuit breaker mechanism to have all subsequent requests cease all invocations to the external system if it has been detected to be unavailable. If we know the external service is down, there's is no need to block multiple WebContainer threads as they wait for responses from or connections to the service. To cite another example from the IBM Sterling Order Management and WebSphere Commerce direct inventory integration, the integration employs the use of a heartbeat mechanism to periodically check the state of the external server. Before any request to the external system is made, this state is checked. If it is determined to be unavailable, we can still return a successful response to the shopper promptly using the locally cached data available.
- Set timeouts on all transports and invocations to external services. For instance, if you are using the HTTP WebServices adapter module provided with WebSphere Commerce, you may leverage the connectTimeout and readTimeout settings. Use the shortest timeout possible (ex. 3-5 seconds) to ensure WebContainer threads are not blocked for an excessive amount of time waiting on responses from the external service. Do not use timeouts in excess of 60 seconds as waiting requests may quickly saturate the entire WebContainer pool and block subsequent shoppers from accessing the site. Depending on the libraries and API's being used to invoke the external services, see the corresponding documentation for configuration parameters and methods.
Note: If you do not see these timeout properties available, see the following fix:
- Rather than having WebSphere Commerce make the call to the external system (server-to-server), leverage the AJAX/Dojo framework instead to offload these requests to clients so that they are made directly from the browser. An example of this might be loading product reviews from an external provider.
Tips for updating your store to support Dojo 1.8
Leveraging the techniques above can help ensure that during peak traffic your store remains fully operational and accepting orders regardless of the states of the external systems you may be using.