OFBiz Performance Tip: sync vs async

 

Apache OFBiz is HotWax Media’s enterprise ERP application development framework of choice, and scalability and performance are critically important for OFBiz systems. Requirements vary widely across different types and sizes of organizations. Some are heavy on front end web traffic (B2C e-commerce) while others are heavy in areas like manufacturing or warehouse. Of course, some systems see heavy utilization across the board.

Using the simple architecture described below on a standard AWS cloud infrastructure, our internal OFBiz performance testing is demonstrating OFBiz B2C e-commerce handling well over 20,000 orders per day (along with the associated web traffic assuming a 2% conversion rate as well as back-end users working on procurement, fulfillment, and other back office tasks). That is before any clustering. With a load balancer and one or more clusters, OFBiz can quickly get up to hundreds of thousands of orders per day and beyond!

When designing and implementing Apache OFBiz ERP applications, we always keep system performance requirements top of mind. Nothing discourages end users more than slow system response times, so it is important that we think ahead and plan for the type of system that will meet or exceed end user expectations based on business requirements.

One of the components of the OFBiz framework is the pool for the execution of asynchronous tasks. Examples of asynchronous tasks include scheduled jobs (e.g. a nightly job) and services executed asynchronously (with the runAsync method).

In some environments, with the default setup, the load caused by the execution of asynchronous tasks can be high and consume a lot of the hardware resources used by the JVM in which the OFBiz instance runs. This can detrimentally affect system responsiveness for synchronous users. In other words, if you are not careful, asynchronous jobs can slow the system down and leave your end users hanging.

Default setup

In its default configuration, OFBiz is executed as one instance running both synch and asynch tasks as described in the following diagram:

OFBiz performance diagram

One OFBiz instance (named “ofbiz1”) with one job pool (named “pool”). The OFBiz instance runs in one JVM and is responsible for executing all the work, including both synchronous (synch service execution, events, scripts, ui rendering etc…) and asynchronous (execution of jobs stored in the JobSandbox entity) tasks.

Configuration files

  1. the instance id is defined in the file framework/common/config/general.properties by the property: unique.instanceId=ofbiz1
  2. the name of the pool to use to submit/execute jobs and the poll settings are defined in framework/service/config/serviceengine.xml by the element.
      <thread-pool send-to-pool="pool"
                     purge-job-days="4"
                     failed-retry-min="3"
                     ttl="120000"
                     jobs="100"
                     min-threads="2"
                     max-threads="5"
                     poll-enabled="true"
                     poll-db-millis="30000">
            <run-from-pool name="pool"/>
        </thread-pool>

Two instances with one instance dedicated to async task processing

A heavy load can be caused by a large number of asynchronous tasks (i.e. large number of records in the JobSandbox entity), by the execution of resource demanding tasks (e.g. a nightly task that updates a large number of records) or both. In environments characterized by a heavy load, a simple solution is to delegate the processing of asynchronous jobs to a separate dedicated OFBiz instance.

The setup is straightforward as you can see from the following diagram:

OFBiz performance diagram

Two OFBiz instances are connected to the same database. The two instances are exactly the same except for slight differences in configuration files, highlighted with a bold font below.

The original OFBiz instance (“ofbiz1”) is now responsible for the execution of all the synchronous work only (synch service execution, events, scripts, ui rendering, etc). The new OFBiz instance (“ofbiz2”) is running in a different JVM and is dedicated to the executions of asynchronous tasks (execution of jobs stored in the JobSandbox entity).

The users interact with the “ofbiz1” instance only (“ofbiz2” should be protected behind a firewall); the “ofbiz1” instance submits asynchronous tasks to the pool (records are stored in the JobSandbox entity); the pool is polled by the “ofbiz2” instance and the jobs are executed by “ofbiz2”.

Configuration files ofbiz1

  • framework/common/config/general.properties: unique.instanceId=ofbiz1
  • framework/service/config/serviceengine.xml (now we have poll-enabled=”false”)
      <thread-pool send-to-pool="pool"
                     purge-job-days="4"
                     failed-retry-min="3"
                     ttl="120000"
                     jobs="100"
                     min-threads="2"
                     max-threads="5"
                     poll-enabled="false"
                     poll-db-millis="30000">
            <run-from-pool name="pool"/>
        </thread-pool>

Configuration files ofbiz2

  • framework/common/config/general.properties: unique.instanceId=ofbiz2
  • framework/service/config/serviceengine.xml:
       <thread-pool send-to-pool="pool"
                     purge-job-days="4"
                     failed-retry-min="3"
                     ttl="120000"
                     jobs="100"
                     min-threads="2"
                     max-threads="5"
                     poll-enabled="true"
                     poll-db-millis="30000">
            <run-from-pool name="pool"/>
        </thread-pool>

A cluster for async job processing

Similarly, it is possible to setup a cluster of instances for the execution of async tasks as described in the following diagram:

OFBiz performance diagram

This is similar to the previous setup, but this time two OFBiz instances poll the pool and execute the jobs (i.e. they share the load/execution of asynchronous jobs).

This architecture is simple and powerful and can be combined nicely with a separate load balancer and a cluster for splitting the load of synchronous tasks in environments characterized by high user traffic.

In conclusion, we all know performance is important for any ERP system, and OFBiz systems are no different. Using the simple but powerful approach outlined above, you will be well on your way to scaling an OFBiz system that gracefully meets or exceeds your end users’ expectations.

Contact us today if you would like to discuss your OFBiz project!


DATE: Jul 25, 2014
AUTHOR: Jacopo Cappellato
OFBiz Tutorials, Load Testing, OFBiz Service Provider, OFBiz Development, Apache OFBiz, Enterprise eCommerce Solutions, Enterprise ERP, OFBiz, Jacopo Cappellato