JMSのQueueサイズ制限指定とMDBの同時実行性指定の方法

要望があってたのでちょっくら調べてみました。

デフォルトではQueueを作成しても、そこにストアできるメッセージの数の制限はないようです。極端な話、receiveを行わずにひたすらsendを繰り返すと、OutOfMemoryErrorまで行き着くと思われます。

これを設定によって制限し、Exceptionをスローさせるようにしたいという要求があるとします。その場合は以下のようにやるとできる(かもしれません)。動作確認まではやれてないので不確かですが。

<mbean code="org.jboss.mq.server.jmx.Queue"
  name="jboss.mq.destination:service=Queue,name=A">
  <attribute name="MaxDepth">100</attribute>
  <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
</mbean>

deploy/jms/jbossmq-destination-service.xmlなどにQueueの設定が書いてあるとおもうのですが、これにMaxDepth属性を追加します。この例ではQueueに溜め込める最大メッセージ数を100に制限しています。

この制限値を超える場合には、org.jboss.mq.DestinationFullExceptionがスローされます。アプリケーション側でこれをハンドリングしてあげることで、制限時への対処が可能となります。

続いて、Message Driven Beanの同時実行性の制御方法ですが、これはconf/standardjboss.xmlあるいは各EJBと一緒にパッケージングするjboss.xmlに以下のように記述します(これまた動作未確認ですが多分これでいけるかと)。

<container-pool-conf>
  <MaximumSize>100</MaximumSize>
  <MinimumSize>10</MinimumSize>
  <strictMaximumSize>true</strictMaximumSize>
</container-pool-conf>

strictMaximumSizeをtrueにしないと、そのままだとMaxを超えるような結果となる処理要求があったときに意図的にBlockするという振る舞いにはなりません。ちなみにこの設定はMDBに限定した話ではなく、すべてのEJBについて同様に設定が効きそうです。

たとえばシステム用件から、同時に実行されるMDBを1つに限定したい(シリアルに実行させたい)ような場合には、ここを1に設定することになると思います。

↑↑↑
以上、全部動作確認してない話なので若干自信なさげなのですが、まあこんな感じで、メモ程度に。。。



追記:
tfukuiさんより情報をいただきました。どうもありがとうございます(^^;

同時実行性の制御には、JMSContainerInvoker の MaximumSize でサーバセッションの数も変更しないといけないと思います。

この部分でしょうか。

<container-invoker-conf>
  <JMSProviderAdapterJNDI>DefaultJMSProvider</JMSProviderAdapterJNDI>
  <ServerSessionPoolFactoryJNDI>StdJMSPool</ServerSessionPoolFactoryJNDI>
  <MaximumSize>15</MaximumSize>
  <MaxMessages>1</MaxMessages>
  <Optimized>True</Optimized>
</container-invoker-conf>