[Java, WLS] Concurrency Utilities support in WebLogic Server 12.2.1, Part One: ManagedExecutorService

原文はこちら。
https://blogs.oracle.com/WebLogicServer/entry/concurrency_utilities_support_in_weblogic1

Overview

ManagedExecutorService(管理対象エグゼキュータ・サービス)はWebLogic Serverが提供するスレッドで非同期でタスクを実行するためにあります。このサービスはjava.util.concurrent.ExecutorServiceの拡張ですが、新しいメソッドを持ちません。そのため、ExecutorSrevice由来のメソッド(execute、submit、invokeAll、invokeAny)を提供しますが、ライフサイクルのメソッド(awaitTermination、isTerminated、isShutdown、shutdown、shutdownNow)は無効にされており、使うとIllegalStateExceptionが発生します。
Weblogic Serverは事前構成済みのデフォルトの管理対象エグゼキュータ・サービスを各アプリケーションのために提供しており、アプリケーションは何も設定せずに簡単にこのサービスをWebコンポーネントやEJBコンポーネントで利用できます。デフォルトの管理対象エグゼキュータ・サービスをServletで使うという簡単な例からはじめてみましょう。

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

Step1)
非同期タスクを作成します。非同期タスクはjava.util.concurrent.Callableもしくは java.lang.Runnableのいずれかを実装する必要があります。タスクはjavax.enterprise.concurrent.ManagedTaskを実装して、識別情報やManagedTaskListener、もしくはタスクの追加実行プロパティを提供することができます。
JSR 236: Concurrency Utilities for JavaTM EE
https://jcp.org/en/jsr/detail?id=236
public class SomeTask implements Callable<Integer> {
    public Integer call() {
        // Interact with a database, then return answer.
    }
}
Step2)
SomeServlet.java がデフォルトの管理対象エグゼキュータ・サービスを注入し、タスクを管理対象エグゼキュータ・サービスに対し発行します。
@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

上図には2個のアプリケーション(赤はA、緑はB)があります。この2個のアプリケーションがタスクを異なる管理対象エグゼキュータ・サービス・インスタンスに発行していることがわかります。これは管理対象エグゼキュータ・サービスがアプリケーションスコープにあるためです。各アプリケーションにはそれぞれ固有の管理対象エグゼキュータ・サービス・インスタンスがあり、管理対象エグゼキュータ・サービス・インスタンスのライフサイクルはアプリケーションに紐付いています。管理対象エグゼキュータ・サービスに発行された非同期タスクもまたアプリケーションスコープであるため、アプリケーションをシャットダウンすると、関連する非同期タスクやスレッドはキャンセルもしくは中断されます。
各アプリケーションはそれぞれデフォルト管理対象エグゼキュータ・サービス・インスタンスを持ちます。それに加え、アプリケーションやシステムの管理者はカスタマイズされた管理対象エグゼキュータ・サービスを定義することができます。管理今ソースでグローバルに定義された管理対象エグゼキュータ・サービス・テンプレート(後述します)は実行時にはアプリケーションスコープであることにご注意ください。

Context Propagation

上図で、アプリケーションAがタスクを発行すると、そのタスクはアプリケーションAのコンテキストでラップされ、アプリケーションBがタスクを発行すると、そのタスクはアプリケーションBのコンテキストでラップされます。これは管理対象エグゼキュータ・サービスがアプリケーションコンテキストをタスク発行時に捕獲し、その後捕獲したアプリケーションコンテキストをタスク実行前に伝播するため、正しい振る舞いです。そえゆえタスクもアプリケーションコンテキストを伴って実行します。
4種類のアプリケーションコンテキスト、JNDI、クラスローダ、セキュリティ、ワークエリアが伝播されます。伝播されたコンテキストタイプは4種類のコンカレント管理対象オブジェクトと同じものです。

Self Tuning(for short-running tasks)

上図で、管理対象エグゼキュータ・サービスが短時間実行されるタスクをワークマネージャに対して発行すること、長時間実行されるタスク用に新たなスレッドを生成することがわかります。
Workload Management in WebLogic Server 9.0
http://www.oracle.com/technetwork/articles/entarch/workload-management-088692.html
ご存じかもしれませんが、WebLogic Serverは、一定期間(デフォルトでは10分)スレッドが引き続き動作している(アイドル状態ではない)場合、スタックしたと判断します。そのため、通常はタスクはその時間を超えて継続する場合、長時間実行するタスクの可能性があります。ManagedTask.LONGRUNNING_HINTプロパティ(JSR 236の仕様をご覧ください)にtrueを設定し、長時間実行するタスクとして実行させることができます。
JSR 236: Concurrency Utilities for JavaTM EE
https://jcp.org/en/jsr/detail?id=236
各管理対象エグゼキュータ・サービスはアプリケーションスコープのワークマネージャと関連づけられています。デフォルトでは、管理対象エグゼキュータ・サービスはアプリケーションのデフォルトのワークマネージャと関連付けられています。アプリケーションやシステムの管理者はディスパッチ・ポリシーを指定し、管理対象エグゼキュータ・サービスをアプリケーションスコープのワークマネージャと関連付けることができます。後の章でディスパッチ・ポリシーの利用例をご紹介します。
管理対象エグゼキュータ・サービスをワークマネージャと関連付けることで、WebLogic Serverはシングルスレッドプールのスレッドを活用し、非同期タスクをアプリケーションから実行します。非同期タスクはServletやRMIリクエストとともに動的に優先度を付けることもできます。

Limit of Concurrent Long-running Requests

前述の通り、長時間実行するタスクはシングルスレッドプールのスレッドを活用せず、WebLogic Serverが各タスク用に新規のスレッドを作成します。過剰に多くの実行中スレッドが存在するとサーバーのパフォーマンスと安定性に影響を及ぼす可能性があるため、WebLogic Serverは、同時長時間実行リクエストの最大数を管理対象エグゼキュータ・サービス/ManagedScheduledExecutorService(管理対象スケジュール済エグゼキュータ・サービス)インスタンス、サーバのグローバル(ドメインレベル)ランタイム、サーバにて提供します。デフォルト設定は以下のようになっています。
  • 管理対象エグゼキュータ・サービス/ 管理対象スケジュール済エグゼキュータ・サービス・インスタンス:10
  • サーバーのグローバル(ドメインレベル)ランタイム:50
  • サーバ:100
制限のいずれかを超過すると、管理対象エグゼキュータ・サービス/管理対象スケジュール済エグゼキュータ・サービスはRejectedExecutionExceptionをスローすることによって長時間実行タスクの発行を拒否します。
グローバル(ドメインレベル)ランタイムスコープの同時長時間実行リクエストの最大数と、サーバスコープの同時長時間実行リクエストの最大数に違いがあることにご注意ください。WebLogic Server 12.2.1の重要な機能の一つはMultitenancyのサポートで、一つのWebLogic Serverドメインに複数のパーティションを含めることができます。グローバル(ドメインレベル)ランタイムスコープの同時長時間実行リクエストの最大数は、グローバル(ドメインレベル)ランタイム用のサーバ上の管理対象エグゼキュータ・サービス/管理対象スケジュール済エグゼキュータ・サービスの全てが発行した同時長時間実行タスクの最大数であり、これはサーバ上で動作しているパーティションスコープ内で発行された同時長時間実行タスクを除くのに対し、サーバスコープの同時長時間実行リクエストの最大数は、サーバ上の管理対象エグゼキュータ・サービス/管理対象スケジュール済エグゼキュータ・サービスの全てが発行した同時長時間実行タスクの最大数であり、これにはグローバル(ドメインレベル)のランタイム、パーティション内で発行された同時長時間実行タスクを含みます。パーティションスコープの同時長時間実行タスクの最大数については、Part 5 - Multitenancy supportのエントリをご覧下さい。
Concurrency Utilities support in WebLogic Server 12.2.1, Part Five: Multi-tenancy Support
https://blogs.oracle.com/WebLogicServer/entry/concurrency_utilities_support_in_weblogic5
http://orablogs-jp.blogspot.jp/2015/12/concurrency-utilities-support-in_41.html
管理対象エグゼキュータ・サービス/管理対象スケジュール済エグゼキュータ・サービスは3個の制限のいずれも超えない場合のみ、同時長時間実行タスクの発行を受け付けます。例えば、サーバーのグローバル(ドメインレベル)ランタイムにデプロイされたアプリケーションがあって、長時間実行中のタスクをデフォルトの管理対象エグゼキュータ・サービスに発行したとします。そこで、
  • 管理対象エグゼキュータ・サービスに発行された進行中の長時間実行タスクが10個ある
  • グローバル(ドメインレベル)ランタイムスコープの管理対象エグゼキュータ・サービス/管理対象スケジュール済エグゼキュータ・サービスに発行された進行中の長時間実行タスクが50個ある
  • サーバの管理対象エグゼキュータ・サービス/管理対象スケジュール済エグゼキュータ・サービスに発行された進行中の長時間実行タスクが100個ある
のいずれかの場合に、RejectedExecutionExceptionがスローされます。同時長時間実行タスクの最大数の設定方法は後の章でご紹介します。

Configuration

前述の通り、各アプリケーションは個々の管理対象エグゼキュータ・サービスを持ちます。デフォルトの管理対象エグゼキュータ・サービスはデフォルトのワークマネージャと関連付けられており、次の設定値がデフォルトで設定されています。
  • 同時長時間実行タスクの最大数:10
  • スレッド優先度:Thread.NORM_PRIORITY
また、
  • サーバ全体に対する同時長時間実行タスクの最大数:100
がデフォルトで設定されています。デフォルトの設定が十分ではない場合、設定方法を記載していますので続きを読んでください。例えば、事前定義済みのワークマネージャに対する短時間実行タスクをより高い優先度で関連付ける場合、管理対象エグゼキュータ・サービスを構成する必要がありますし、サーバで同時長時間実行タスクが100を超える場合にはサーバスコープの同時長時間実行タスクの最大数を変更する必要があるでしょう。

Configure ManagedExecutorServices

名前、ディスパッチ・ポリシー、長時間実行リクエストの最大数、長時間実行プライオリティを管理対象エグゼキュータ・サービス内で設定します。
  • 名前:管理対象エグゼキュータ・サービスを識別する文字列
  • ディスパッチ・ポリシー:短時間実行タスクを発行するワークマネージャの名前
  • 最大同時長時間リクエスト:この管理対象エグゼキュータ・サービスに発行された同時長時間実行タスク個数の上限
  • 長時間実行の優先度:長時間実行タスクのために作成されたスレッドの優先度 
アプリケーションはDD(デプロイメント・ディスクリプタ:weblogic-application.xml/weblogic-ejb-jar.xml/weblogic.xml)で管理対象エグゼキュータ・サービスを構成できます。管理対象エグゼキュータ・サービス・インスタンスを@Resource(mappedName=<管理対象エグゼキュータ・サービスの名前>)で取得してから、タスクを発行します。アノテーションの他に、DDで<resource-env-description> と <resource-env-ref> を指定することで、アプリケーションは管理対象エグゼキュータ・サービス・インスタンスをJNDIにバインドすれば、JNDI Naming Contextを使って検索します。詳細は以下の製品ドキュメントをご覧下さい。
Oracle® Fusion Middleware Administering Server Environments for Oracle WebLogic Server 12c (12.2.1)
Configuring Concurrent Managed Objects
https://docs.oracle.com/middleware/1221/wls/CNFGD/concurrent-utils.htm#CNFGD359
また、WebLogicシステム管理者は事前定義済みの管理対象エグゼキュータ・サービス・テンプレートを構成することができます。アプリケーションをデプロイすると、WebLogic Serverが管理対象エグゼキュータ・サービス・テンプレートの設定に基づいて管理対象エグゼキュータ・サービスを作成します。作成された管理対象エグゼキュータ・サービスは全てこのアプリケーションのスコープに入っています。

Example-2: Configure a ManagedExecutorService in weblogic.xml

Step1)
管理対象エグゼキュータ・サービスを定義します
<!-- 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)
管理対象エグゼキュータ・サービス・インスタンスを取得して利用します
@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

個別アプリケーションではなく複数のアプリケーションに要件がある場合、管理対象エグゼキュータ・サービス・テンプレートをグローバルに作成して全てのアプリケーションで利用可能にすることができます。例えば、すべてのアプリケーションから低優先度の短時間実行タスクを実行する必要がある場合、管理対象エグゼキュータ・サービス・テンプレートを構成する必要があります。管理対象エグゼキュータ・サービス・テンプレートはバッチジョブでも有用です。
Oracle® Fusion Middleware Administering Server Environments for Oracle WebLogic Server 12c (12.2.1)
Prerequisite Steps Configure the JobRepository Tables, Batch Data Source, and Managed Executor Service
https://docs.oracle.com/middleware/1221/wls/CNFGD/batch-apps.htm#CNFGD374
前述の通り、管理対象エグゼキュータ・サービス・テンプレートがある場合、WebLogic Serverは管理対象エグゼキュータ・サービス・インスタンスをテンプレートの設定に従って各アプリケーション用に作成します。

Step1)
WebLogic Server管理コンソールから、同時管理対象オブジェクト・テンプレートのサマリーのページで、[新規]をクリックすると、管理対象エグゼキュータ・サービス・テンプレートを作成することができます。[管理対象エグゼキュータ・サービス・テンプレートの作成]ページで、管理対象エグゼキュータ・サービス・テンプレートの名前やその他のパラメータを指定することができます。この例では、testMESという管理対象エグゼキュータ・サービス・テンプレートを作成し、testWMという事前定義済みワークマネージャにマッピングしています。

Step2)
管理対象エグゼキュータ・サービス・テンプレートを作成すると、WebLogic Serverの任意のアプリケーションは管理対象エグゼキュータ・サービス・インスタンスを取得して利用することができます。
@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

グローバル(ドメインレベル)ランタイムの最大同時長時間リクエストとは、サーバのグローバル(ドメインレベル)ランタイムの全ての管理対象エグゼキュータ・サービスやManagedScheduledExecutorServiceに対して発行された同時長時間実行タスク個数の上限です。これには当該サーバで動作しているパーティションスコープ内で発行された長時間実行タスクを含まれません。
WebLogic Server管理コンソールの[(ドメイン名)の設定]画面で、グローバル(ドメインレベル)ランタイムの最大同時長時間リクエストを編集できます。この例では、base_domainのグローバル(ドメインレベル)ランタイムの最大同時長時間リクエストを80に設定しています。


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

サーバの最大同時長時間リクエストとは、当該サーバの全ての管理対象エグゼキュータ・サービスと管理対象スケジュール済エグゼキュータ・サービスに対して発行された同時長時間実行タスク個数の上限です。
WebLogic Server管理コンソールの[(サーバ名)の設定]画面で、サーバの最大同時長時間リクエストを編集できます。この例では、myserverの最大同時長時間リクエストを200に設定しています。


Related Articles:

詳細は、ドキュメントの以下の項をご覧下さい。
Oracle® Fusion Middleware Administering Server Environments for Oracle WebLogic Server 12c (12.2.1)
Configuring Concurrent Managed Objects
https://docs.oracle.com/middleware/1221/wls/CNFGD/concurrent-utils.htm#CNFGD359

0 件のコメント:

コメントを投稿