X

Proactive insights, news and tips from Oracle WebLogic Server Support. Learn Oracle from Oracle.

  • November 25, 2015

Concurrency Utilities support in WebLogic Server 12.2.1, Part One: ManagedExecutorService

Overview

ManagedExecutorService
is for running tasks asynchronously on threads provided by WebLogic
Server. It extends from java.util.concurrent.ExecutorService without new
methods, it provides methods(execute, submit, invokeAll, invokeAny)
from ExecutorService, and its lifecycle methods(awaitTermination,
isTerminated, isShutdown, shutdown, shutdownNow) are disabled with
IllegalStateException.

Weblogic Server provides a preconfigured, default ManagedExecutorService for each application, and applications can easily use it in web or EJB components without any configuration. Let's begin with a simple example that uses default ManagedExecutorService in a servlet.

Example-1: Use Default ManagedExecutorService to Submit an Asynchronous Task in a Servlet

Step1:
Write an asynchronous task. Asynchronous tasks must implement either
java.util.concurrent.Callable or java.lang.Runnable. A task can
optionally implement javax.enterprise.concurrent.ManagedTask(see JSR236 specification) to provide identifying information, a ManagedTaskListener or additional execution properties of the task.

public class SomeTask implements Callable<Integer> {

    public Integer call() {

        // Interact with a database, then return answer.

    }

}

Step2: SomeServlet.java injects the default ManagedExecutorService and submit the task to it.

@WebServlet("/SomeServlet")

public class SomeServlet extends HttpServlet {

    @Resource ManagedExecutorService mes;

     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // Create and submit the task instances

        Future<Integer> result = mes.submit(new SomeTask());

        // do something else

        try {

            // Wait for the result

            Integer value = result.get();

            // Process the result and reply to the user

        } catch (InterruptedException | ExecutionException e) {

            throw new ServletException("failed to get result for SomeTask", e);

        }

    }

}

Runtime Behavior


Application Scoped Instance

There
are two applications(A in red and B in green) in the above figure. You
can see that the two applications are submitting tasks to different
ManagedExecutorService instances, this is true because
ManagedExecutorServices are application scoped. Each application has its
own ManagedExecutorService instances, and the lifecycle of the
ManagedExecutorService instances are bound to the application.
Asynchronous tasks submitted to ManagedExecutorServices are also
application scoped, so that when the application is shut down, related
asynchronous tasks/threads will be cancelled/interrupted.

Each
application has its own default ManagedExecutorService instance.
Besides, Applications or system administrators can define customized
ManagedExecutorService. Please note that even ManagedExecutorService
templates(see in a later section) defined globally in the console are application scoped during runtime.

Context Propagation

In
the above figure you can see that when application A is submitting a
task, the task is wrapped with the context of application A, whereas
when application B is submitting a task, the task is wrapped with the
context of application B. This is true because ManagedExecutorServices
will capture the application context at task submission, then propagate
the captured application context before task execution, so that the task
can also run with the application context.

Four types of
application context are propagated: JNDI, ClassLoader, Security and
WorkArea. The propagated context types are the same for four types of
the concurrent managed objects.

Self Tuning(for short-running tasks)

In the above figure you can see that ManagedExecutorServices submit short-running tasks to WorkManagers(see Workload Management in WebLogic Server 9.0 for overview of WebLogic work managers), and create a new thread for each long-running task. As you may know, WebLogic Server diagnoses a thread as stuck if it is continually working (not idle) for a set period of time(default is 10 minutes), so normally if a task would last longer than that period of time, it can be a long-running task. You can set ManagedTask.LONGRUNNING_HINT property(see JSR236 specification) to "true" to make it run as a long-running task.

Each ManagedExecutorService is associated with an application-scoped WorkManager. By default, ManagedExecutorServices are associated with the application default WorkManager. Applications or system administrators can specify Dispatch Policy to associate a ManagedExecutorService with a specific application-scoped WorkManager. There are examples on how to use the dispatch policy in a later section.

By associating a ManagedExecutorService with a WorkManager, WebLogic Server utilize the threads in the single thread pool to run asynchronous tasks from applications, so that asynchronous tasks can also be dynamically prioritized together with servlet or RMI requests.

Limit of Concurrent Long-running Requests

As mentioned earlier long-running tasks do not utilize the threads in the single thread pool, WebLogic Server
creates a new thread for each task. Because an excessive number of
running threads can have a negative affect on server performance and
stability, WebLogic Server provides configurations(Max Concurrent Long Running Requests) to limit the number of concurrent long-running tasks in a ManagedExecutorService/ManagedScheduledExecutorService instance, in the global (domain-level) runtime on a server or in the server. By default, the limits are: 10 for a ManagedExecutorService/ManagedScheduledExecutorService instance, 50 for the global (domain-level) runtime on a server and 100 for a Server. When either of the limits is exceeded, ManagedExecutorService/ManagedScheduledExecutorService rejects long-running tasks submissions by throwing a RejectedExecutionException.

Please note the difference between the global (domain-level) runtime scope Max Concurrent Long Running Requests and the server scope Max Concurrent Long Running Requests. One
of the key features in WLS 12.2.1 is the multi-tenancy support where a
single Weblogic Server domain can contain multiple partitions.
The global (domain-level) runtime scope Max Concurrent Long Running Requests is the maximum number of concurrent long-running tasks submitted by all of the ManagedExecutorServices/ManagedScheduledExecutorServices
on the server for global (domain-level) runtime, this excludes concurrent
long-running tasks submitted within the scope of partitions running on
the server, while the server scope Max Concurrent Long Running Requests is the maximum number of concurrent long-running tasks submitted by all of the ManagedExecutorServices/ManagedScheduledExecutorServices on the server, including concurrent long-running tasks submitted within global (domain-level) runtime and partitions. For partition scope Max Concurrent Long Running Requests, please read Part Five - Multi-tenancy Support.

ManagedExecutorService/ManagedScheduledExecutorService
accepts a concurrent long-running task submission only when neither of
the 3 limits is exceeded. For instance, there is an application deployed
to global (domain-level) runtime on a server, when a long-running task is submitted to its
default ManagedExecutorServiceRejectedExecutionException will be thrown if there are 10 in progress long-running tasks which are submitted to this ManagedExecutorService, or there are 50 in progress long-running tasks which are submitted to the ManagedExecutorServices/ManagedScheduledExecutorServices in scope of global (domain-level) runtime on the server, or there are 100 in progress long-running tasks which are submitted to the ManagedExecutorServices/ManagedScheduledExecutorServices in the server.

There are examples on how to specify the Max Concurrent Long Running Requests in a later section.

Configuration

As mentioned earlier, each application has its own default ManagedExecutorService. The default ManagedExecutorService
is associated with the default WorkManager, has a default max
concurrent long running requests(10), and has a default thread
priority(Thread.NORM_PRIORITY). There is also a default max concurrent long running requests(100) for the whole server. If the
default configuration is not good enough you will need to read further
for configurations. For instance, when you need to associate
short-running tasks to a pre-defined WorkManager with higher priority,
you will need to configure a ManagedExecutorService; and if
there would be more than 100 concurrent long-running tasks in the server, you will need to change the server scope Max Concurrent Long Running Requests.

Configure ManagedExecutorServices

Name, Dispatch Policy, Max Concurrent Long Running Requests, and Long Running Priority are configured inside a ManagedExecutorService. Name is a string that identifies the ManagedExecutorServiceDispatch Policy is the name of the WorkManager to which the short-running tasks are submitted, Max Concurrent Long Running Requests is the limit of concurrent long-running tasks submitted to this ManagedExecutorService, and Long Running Priority is the priority of the threads created for long-running tasks.

An application can configure a ManagedExecutorService in DD(weblogic-application.xml/weblogic-ejb-jar.xml/weblogic.xml), and gets the ManagedExecutorService instance using @Resource(mappedName=<Name of ManagedExecutorService>), then submits a task to it. Besides annotation, the application can also bind the ManagedExecutorService
instance to JNDI by specifying <resource-env-description> and
<resource-env-ref> in DD, then look it up using JNDI Naming
Context, you can read Configuring Concurrent Managed Objects in the product documentation for details.

Also, a WebLogic system administrator can configure pre-defined ManagedExecutorService templates. When an application is deployed, WebLogic Server creates ManagedExecutorServices based on the configuration of ManagedExecutorService templates, and the created ManagedExecutorServices are all in scope of this application.

Example-2: Configure a ManagedExecutorService in weblogic.xml

Step1: defining ManagedExecutorService:

<!-- weblogic.xml -->





<work-manager>

<name>customizedWM</name>

    <max-threads-constraint>

        <name>max</name>

        <count>1</count>

    </max-threads-constraint>

</work-manager>

<managed-executor-service>

    <name>customizedMES</name>

    <dispatch-policy>customizedWM</dispatch-policy>

    <long-running-priority>10</long-running-priority>

    <max-concurrent-long-running-requests>20</max-concurrent-long-running-requests>

</managed-executor-service>

Step2: obtaining the ManagedExecutorService instance to use

@WebServlet("/SomeServlet")

public class SomeServlet extends HttpServlet {

    @Resource(mappedName="customizedMES")

     ManagedExecutorService mes;

     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

         Runnable aTask = new Runnable() {
             ...
         };
         mes.submit(aTask);
         ...
    }

}

Example-3: Configure a ManagedExecutorService template using WebLogic Administration Console

If there is requirement on multiple applications instead of individual application, you can create ManagedExecutorService templates globally that are available to all applications. For instance, when you need to run short-running tasks from all applications with lower priority, you will need to configure a ManagedExecutorService template . ManagedExecutorService templates are also useful in Batch jobs. As mentioned earlier, if there is a ManagedExecutorService template, WebLogic Server creates a ManagedExecutorService instance for each application based on the configuration of the template.

Step1: in WebLogic Administration Console, a ManagedExecutorService
template can be created by clicking on the “New” button from the
“Summary of Concurrent Managed Object Templates” page. This brings up
the "Create a New Managed Executor Service Template" page where the name
and other parameters of the new ManagedExecutorService template can be specified. In this example, a ManagedExecutorService called "testMES" is being created to map to a pre-defined work manager "testWM".


Step2: Once a ManagedExecutorService template is created, any application in the WebLogic Server can get its own ManagedExecutorService instance to use.

@WebServlet("/SomeServlet")

public class SomeServlet extends HttpServlet {

    @Resource(mappedName="testMES")



    ManagedExecutorService mes;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        Runnable aTask = new Runnable() {
            ...
        };
        mes.submit(aTask);
        ...
    }

}

Configure Max Concurrent Long Running Requests Running in global (domain-level) runtime scope or server scope

Example-4: Configure global (domain-level) runtime Scope Max Concurrent Long Running Requests

Max Concurrent Long Running Requests of global (domain-level) runtime is the limit of concurrent long-running tasks submitted to all
ManagedExecutorServices and ManagedScheduledExecutorServices in global (domain-level) runtime
on that server, this excludes long-running tasks submitted within the
scope of partitions running on that server.

In WebLogic Administration Console, Max Concurrent Long Requests of global (domain-level) runtime can be edited from the “Settings for <domainName>” screen. In this example, global (domain-level) runtime Max Concurrent Long Running Requests for mydomain is set to 80.

Example-5: Configure Server Scope Max Concurrent Long Running Requests

Max Concurrent Long Running Requests of a server is the limit of concurrent long-running tasks submitted to all ManagedExecutorServices and ManagedScheduledExecutorServices in that server.

In WebLogic Administration Console, Max Concurrent Long Requests of a server can be edited from the “Settings for <serverName>” screen. In this example, Max Concurrent Long Running Requests of myserver is set to 200.


Related Articles:

See for more details Configuring Concurrent Managed Objects in the product documentation.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha