nimbus (1.2.4) | 2018-01-25 20:02 |
nimbus-sample (1.2.4) | 2018-01-26 17:06 |
システムのリソースを守りながらアプリケーションを開発するためには、処理量を制御する必要があります。
一般的な方法としては、いわゆる流量(実行並列度)を抑制する方法があります。
JavaEEを使った開発での流量制御は、Servletコンテナのスレッドプール数及びEJBのインスタンスプール数を設定する事で行います。
大雑把な流量制御としては、その機能で可能でしょう。
Nimbusでは、流量を制御するための基本機能として、セマフォを提供します。
このサービスを使う事で、単純なリソース数の制限に加え、FIFOでのリソース割り当てや、リソースが枯渇した場合の制御として、待機数の上限設定、タイムアウト、占有状態の強制解放タイムアウトなどの細かい制御が可能になります。
このセマフォを使って、様々な場所で流量制御を可能にします。
一般的には、サーブレット層では、Servletコンテナのスレッドプール数で流量を制御します。
設定方法や流量制御の方式は、アプリケーションサーバの実装に依存しますが、一般的には、HTTP接続を待ち受けるポート単位で、スレッドプール数の設定が可能で、その単位での流量制御となります。
Nimbusでは、特定のURL単位で流量制御を行う事が可能です。
関連するサービスは、以下。
web.xmlの記述例は、ここ。
サービス定義の記述例は、以下。
- <?xml version="1.0" encoding="Shift_JIS"?>
- <!DOCTYPE server PUBLIC
- "-//Nimbus//DTD Nimbus 1.0//JA"
- "http://nimbus.sourceforge.jp/dtd/nimbus-service_1_0.dtd">
- <server>
- <manager>
- <!-- インターセプタを連ねる順序を示すInterceptorChainListサービス -->
- <service name="InterceptorChainList"
- code="jp.ossc.nimbus.service.aop.DefaultInterceptorChainListService">
- <!-- 連ねるInterceptorサービスのサービス名を設定する -->
- <attribute name="InterceptorServiceNames">
- #SelectableServletFilterInterceptor
- </attribute>
- <depends>SelectableServletFilterInterceptor</depends>
- </service>
- <!-- HTTPリクエストに対して任意のパス毎に異なるインターセプタを呼び出すInterceptorサービス -->
- <service name="SelectableServletFilterInterceptor"
- code="jp.ossc.nimbus.service.aop.interceptor.servlet.SelectableServletFilterInterceptorService">
- <!-- 呼び出されるパスとインターセプタのマッピングを定義する -->
- <attribute name="PathAndInterceptorServiceNameMapping">
- /hoge.bf=#ServletFilterFlowControlInterceptor1
- /fuga.bf=#ServletFilterFlowControlInterceptor2
- </attribute>
- <depends>ServletFilterFlowControlInterceptor1</depends>
- <depends>ServletFilterFlowControlInterceptor2</depends>
- </service>
- <!-- サーブレットフィルタ層のInterceptorにアダプタするInterceptorサービス -->
- <service name="ServletFilterFlowControlInterceptor1"
- code="jp.ossc.nimbus.service.aop.interceptor.servlet.ServletFilterInterceptorAdapterService">
- <!-- アダプタするInterceptorサービスのサービス名を設定する -->
- <attribute name="InterceptorServiceName">#FlowControlInterceptor1</attribute>
- <depends>
- <!-- 流量を制御するInterceptorサービス -->
- <service name="FlowControlInterceptor1"
- code="jp.ossc.nimbus.service.aop.interceptor.FlowControlInterceptorService">
- <attribute name="SemaphoreServiceName">#Semaphore1</attribute>
- <depends>
- <service name="Semaphore1"
- code="jp.ossc.nimbus.service.semaphore.DefaultSemaphoreService">
- <attribute name="ResourceCapacity">3</attribute>
- </service>
- </depends>
- </service>
- </depends>
- </service>
- <!-- サーブレットフィルタ層のInterceptorにアダプタするInterceptorサービス -->
- <service name="ServletFilterFlowControlInterceptor2"
- code="jp.ossc.nimbus.service.aop.interceptor.servlet.ServletFilterInterceptorAdapterService">
- <!-- アダプタするInterceptorサービスのサービス名を設定する -->
- <attribute name="InterceptorServiceName">#FlowControlInterceptor2</attribute>
- <depends>
- <!-- 流量を制御するInterceptorサービス -->
- <service name="FlowControlInterceptor2"
- code="jp.ossc.nimbus.service.aop.interceptor.FlowControlInterceptorService">
- <attribute name="SemaphoreServiceName">#Semaphore2</attribute>
- <depends>
- <service name="Semaphore2"
- code="jp.ossc.nimbus.service.semaphore.DefaultSemaphoreService">
- <attribute name="ResourceCapacity">10</attribute>
- </service>
- </depends>
- </service>
- </depends>
- </service>
- </manager>
- </server>
一般的には、業務層では、EJBのインスタンスプール数で流量を制御します。
Nimbusでは、業務層は、業務フローを使って開発します。
業務フローでは、業務処理のフロー単位及びフロー内の1処理であるステップ単位での流量制御が可能です。
業務フロー定義の定義例は、以下。
- <?xml version="1.0" encoding="Shift_JIS"?>
- <!DOCTYPE flows PUBLIC
- "-//Nimbus//DTD Nimbus Bean Flow 1.0//JA"
- "http://nimbus.sourceforge.jp/dtd/beanflow_1_0.dtd">
- <flows>
- <flow name="SampleFlow"
- maxRunThreads="5"
- maxWaitThreads="10"
- timeout="10000"
- forceFreeTimeout="60000">
- :
- <step name="Step3"
- maxRunThreads="2">
- :
- </step>
- :
- </flow>
Nimbusでは、静的アスペクトの1手法として、サービスをプロキシ化する事で、サービスの呼び出しに対して特定の機能を付加する事ができます。
その方法で、サービスの呼び出しに対して、流量制御機能を付加する事ができます。
関連するサービスは、以下。
サービス定義の記述例は、以下。
- <?xml version="1.0" encoding="Shift_JIS"?>
- <!DOCTYPE server PUBLIC
- "-//Nimbus//DTD Nimbus 1.0//JA"
- "http://nimbus.sourceforge.jp/dtd/nimbus-service_1_0.dtd">
- <server>
- <manager>
- <!-- リモートのプロキシとなるRemoteClientサービス-->
- <service name="Messenger"
- code="jp.ossc.nimbus.service.proxy.RemoteClientService">
- <attribute name="RemoteInterfaceClassName">sample.service.Messenger</attribute>
- <attribute name="InvokerServiceName">#Invoker</attribute>
- <!-- インターセプタのチェインを定義するInterceptorChainListサービスのサービス名を設定する-->
- <attribute name="InterceptorChainListServiceName">#InterceptorChainList</attribute>
- <depends>
- <!-- プロキシする実体を呼び出すInvokerサービス
- ローカルのサービスを呼び出す。
- -->
- <service name="Invoker"
- code="jp.ossc.nimbus.service.proxy.invoker.LocalClientMethodCallInvokerService">
- <attribute name="LocalServiceName">#RealMessenger</attribute>
- <depends>RealMessenger</depends>
- </service>
- </depends>
- <depends>InterceptorChainList</depends>
- </service>
- <!-- プロキシから呼び出される実体となるサービス-->
- <service name="RealMessenger"
- code="sample.service.POJOService">
- <attribute name="Message">Hello!</attribute>
- </service>
- <!-- インターセプタのチェインを定義するInterceptorChainListサービス-->
- <service name="InterceptorChainList"
- code="jp.ossc.nimbus.service.aop.DefaultInterceptorChainListService">
- <attribute name="InterceptorServiceNames">
- #FlowControlInterceptor
- </attribute>
- <depends>FlowControlInterceptor</depends>
- </service>
- <!-- 流量を制御するInterceptorサービス -->
- <service name="FlowControlInterceptor"
- code="jp.ossc.nimbus.service.aop.interceptor.FlowControlInterceptorService">
- <attribute name="SemaphoreServiceName">#Semaphore</attribute>
- <depends>
- <service name="Semaphore"
- code="jp.ossc.nimbus.service.semaphore.DefaultSemaphoreService">
- <attribute name="ResourceCapacity">10</attribute>
- </service>
- </depends>
- </service>
- </manager>
- </server>
また、サービスによっては、流量制御を組み込む事を前提としたサービスもあります。
以下にその一覧を示します。
Nimbusでは、アスペクト指向を使う事で、任意のクラスの任意のメソッド呼び出しに対して、機能を付加する事ができます。
その方法で、任意のクラスの任意のメソッド呼び出しに対して、流量制御機能を付加する事ができます。