Topics
Enterprise Architecture
Spring 2.0.1とBEA WebLogic Server 9.2の統合
Pages:
1,
2,
3,
4
Spring Frameworkの非侵襲的なIoC開発モデルは、Java EEアプリケーションサーバで利用できる一連の機能をベースにしており、またそれらの機能を補完するように設計されています。実際に、厳しい運用環境では、基盤となるアプリケーションサーバインフラストラクチャから提供されるサービスの品質が、Springアプリケーションの信頼性、可用性、および性能の維持にとってきわめて重要です。WebLogic Server 9.2には、Springアプリケーションのあらゆる側面を向上させることができるエンタープライズクラスの機能が用意されています。このセクションでは、これらの機能の詳細と、Springアプリケーションでそれらを利用する方法について説明します。
WebLogic Serverクラスタは、同時に稼働し連携してスケーラビリティと信頼性を向上させる複数のWebLogic Serverインスタンスで構成されます。クラスタは、クライアントには単一のWebLogic Serverインスタンスのように見えます。クラスタを構成するサーバインスタンスは、同じマシンで稼働することも、異なるマシンで稼働することもできます。既存のマシン上のクラスタにさらにサーバインスタンスを追加することで、クラスタのキャパシティを増やすことも、またクラスタにマシンを追加して、そこに追加のサーバインスタンスをホストすることもできます。WebLogic Serverクラスタは、Springアプリケーションにとってエンタープライズクラスのデプロイメントプラットフォームとなります。なお、同様の機能をサポートしているテクノロジ製品は他にもありますが、WebLogic Serverほどの機能の豊富さと使いやすさを備えたものはありません。WebLogic Serverクラスタのコンフィグレーションと管理の詳細については、「クラスタのコンフィグレーションについて」を参照してください。
一般に、SpringアプリケーションはWebアプリケーションとしてパッケージ化され、このシナリオの場合には、WebLogic Serverクラスタリングを利用するためにアプリケーションを変更する必要はありません。クラスタ内のサーバにアプリケーションをデプロイするだけで、スケーラビリティと可用性の向上のメリットが得られるでしょう。
Spring Webアプリケーションでは、注文IDやユーザ情報などの情報を常にHTTPセッションに格納します。クラスタ内のサーブレットやJSPの自動的なレプリケーションとフェイルオーバをサポートするために、WebLogic Serverでは、HTTPセッション状態を保存するためのいくつかのメカニズムをサポートしています。これらは、しかるべきweblogic.xmlデプロイメント記述子をアプリケーション側で用意するだけで、Spring Webアプリケーションで非侵襲的に用いることができます。WebLogic Server 9.2で利用できるさまざまなタイプのセッション永続性のコンフィグレーションについて詳しくは、こちらをご覧ください。
Springには強力なリモーティングサポート機能が用意されているため、一貫性のあるPOJOベースのプログラミングモデルを依然として活かしつつ、リモートサービスのエクスポートや利用を手軽に行うことができます。Vanilla Springでは、単一のRMIインタフェースを通じた適切なSpring BeanへのPOJO呼び出しのプロキシ処理をサポートしています。ただし、このサポートはJRMP(SunによるRMIの実装)の場合か、JndiRmiProxyFactoryBeanで特定のリモートインタフェースを使用する場合に限られていました。WebLogic Server 9.2でのSpring 1.2.5の動作認定を受けて、RMI-IIOPやT3をはじめとする任意のJava EE RMI実装でのPOJOプロキシ処理をサポートするように、JndiRmiProxyFactoryBeanおよび関連するサービスエクスポータを拡張しました。このサポート機能には、プロキシRMIインタフェースに基づいたクラスタリングを可能にするWebLogic RMIデプロイメント記述子が付属しているため、POJO呼び出しをWebLogic Serverクラスタ内で負荷分散することができます。こうしたサポート機能のクライアントコンフィグレーションは、以下のようなものになります(applicationContext.xml)。
<bean id="proProxy"
class="org.springframework.remoting.rmi.JndiRmiProxyFactoryBean">
<property name="jndiName" value="t3://${serverName}:${rmiPort}/order"/>
</property>
<property name="jndiEnvironment">
<props>
<prop key="java.naming.factory.url.pkgs">
weblogic.jndi.factories
</prop>
</props>
</property>
<property name="serviceInterface"
value="org.springframework.samples.jpetstore.domain.logic.OrderService"/>
</bean>
サービスエクスポータは以下のようなものになります(上記同様、applicationContext.xmlより)。
<bean id="order-pro" class="org.springframework.remoting.rmi.JndiRmiServiceExporter">
<property name="service" ref="petStore"/>
<property name="serviceInterface"
value="org.springframework.samples.jpetstore.domain.logic.OrderService"/>
<property name="jndiName" value="order"/>
</bean>
クラスタ化された記述子は自動的に組み込まれ、必要な記述内容は、適切なクラスタコンフィグレーションと全クラスタメンバーへのSpringアプリケーションのデプロイメントのみです。フェイルオーバサポートの詳細については、こちらを参照してください。
WebLogic Server版Springのキットには、アプリケーションに定義されているSpring Bean、属性、および操作を表示するWebLogic Serverコンソール拡張機能が含まれています。これは、WebLogicコンソール拡張ポータルフレームワークをベースにしており、サーバやコンソールのコードを変更しなくてもWebLogic管理コンソールのルックアンドフィール、機能、およびレイアウトを変更することができます。コンソール拡張は、yourdomain/console-extディレクトリにコピーされ、サーバが再起動されるとデプロイされます。コンソール拡張のデプロイの詳細については、WebLogic Server版Springのキットを参考にしてください。
コンソール拡張は、MBeanでないSpring Bean(大半のSpring Beanがこれに該当)の(JMX)管理インタフェースを自動生成する働きをしますが、それは、applicationContext.xmlでMBeanExporterを構成し、アセンブラを通じてどのBeanを公開するかを指定することで行われます。この機能は、SpringとWebLogic Serverがシームレスかつ非侵襲的に連携することを示す非常によい例です。SpringアプリケーションをJMX対応にするには、アプリケーションコンテキストのデプロイメント記述子を変更するだけです。一方、コンソールをSpring対応にするには、既存のドメインにJARを2つデプロイするだけです。
WebLogic Serverの管理コンソールでSpringコンソール拡張を有効にするには、jarファイルが2つ必要です。必要なjarファイルはspring-ext-server.jarとspring-ext-client.jarで、これらのファイルはいずれもSpring WebLogicパッケージに含まれます。spring-ext-server.jarはyourdomain/console-extディレクトリにコピーする必要があります。対応するspring-ext-client.jarファイルは、Webアプリケーションと共にデプロイする必要があります。.WARファイルの場合は、spring-ext-client.jarをWebアプリケーションのWEB-INF/libディレクトリに配置します。
この2つのファイルを配置できたら、あとはSpringのXMLコンフィグレーションファイルでBeanをいくつか定義するだけです。絶対に定義する必要がある最初のSpring Beanはcom.interface21.wl9.jmx.mediator.Mediator Beanです。これは、その名のとおり、アプリケーションと、WebLogic ServerのMBeanServerと管理コンソール間の調整を行うBeanです。Beanの定義は簡単です。以下に例を示します。
<!-- WLS console adapter bean --> <bean id="consoleAdapter" class="com.interface21.wl9.jmx.mediator.Mediator"/>
このBeanは、絶対に構成する必要がある2番目のBean、つまりMBeanExporterにプラグイン(依存関係を注入)する必要があります。MBeanExporterクラスの責任は、Springアプリケーションコンテキストで定義された任意の数の異なるBeanをBEA WebLogic MBeanServer(または構成されている任意のMBeanServer)にエクスポートすることです。MBeanServerによってエクスポートされるBeanがJMX向けにコーディングされている必要はありません。JMXによる管理のためにエクスポートされるBeanを表すModelMBeanが、SpringのJMXインフラストラクチャコードによって生成されます。コンテキストコンフィグレーションファイルの典型的なMBeanExporter Beanの定義を以下に示します。
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="assembler" ref="assembler"/>
<property name="server" ref="server"/>
<property name="beans">
<map>
<!-- these are the beans that are to be exported... -->
<entry key="my_app_name:type=MaintenanceControl"
value-ref="maintenanceInterceptor"/>
<entry key="my_app_name:type=ExceptionMonitor"
value-ref="exceptionHandler"/>
<entry key="my_app_name:type=RequestStatistics"
value-ref="requestStatisticsFilter"/>
</map>
</property>
<property name="registrationBehaviorName"
value="REGISTRATION_REPLACE_EXISTING"/>
<property name="autodetect" value="true"/>
<property name="listeners">
<list>
<!-- notice how we 'plug-in' the Mediator bean
that was defined previously... -->
<ref bean="consoleAdapter"/>
</list>
</property>
</bean>
上記のBeanの定義では、MBeanExporterの'assembler'プロパティに別のBean('assembler')を注入しています。このBeanの定義を以下に示します。
<bean id="assembler" class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler">
<property name="interfaceMappings">
<props>
<prop key="my_app_name:type=MaintenanceControl">fully.qualified.management.interface.name</prop>
<prop key="my_app_name:type=ExceptionMonitor">fully.qualified.management.interface.name</prop>
<prop key="my_app_name:type=RequestStatistics">fully.qualified.management.interface.name</prop>
</props>
</property>
</bean>
この記事では、SpringのJMX機能については詳細に説明しません。ここでは、上記で定義しているInterfaceBasedMBeanInfoAssembler Beanが、管理のためにJMXの操作や属性として実際に公開されるBeanのメソッドやプロパティを制御する1つの戦略であるという説明にとどめておきます。InterfaceBasedMBeanInfoAssemblerでは、任意のインタフェースを使用して、エクスポートするメソッドやプロパティが決定されます。詳細については、この記事の末尾にある「参考資料」のセクションを参照してください。
MBeanExporterのBean定義で注目すべき2番目のプロパティはサーバプロパティです。ここで、WebLogic ServerのMBeanServerのインスタンスをMBeanExporterに注入します。MBeanExporterは、この特定のサーバに、エクスポートするように構成されているすべてのBeanをエクスポートします。Beanの定義は以下のとおりです。
<!-- WebLogic 9 MBeanServer --> <jndi:jndi-lookup id="server" jndi-name="java:comp/env/jmx/runtime"/>
このサーバBeanの定義では、JNDIをMBeanServerインスタンスのソースとしています(jndiNameプロパティに指定された値を使用してコンテキスト内をルックアップ)。MBeanServerのソースがJNDIであるという点はMBeanExporterでは意識する必要がありません。このような依存関係を必要とするオブジェクトへの依存関係の透過的なソーシングが、依存関係注入アプローチの最大の付加価値です。また、使用とコンフィグレーションが容易な上記のJndiObjectFactoryBeanからわかるように、Springの注入サポートは精巧にできています。
MBeanExporterコンフィグレーションの最後の最も興味深い部分はbeansプロパティです。beansプロパティは、(JMX)ObjectNameから、以前に注入したMBeanServerインスタンスに、管理のためにエクスポートするBeanへのマッピングです。Beanが実際にMBeanServerにエクスポートされるObjectNameを選択する戦略は、コンフィグレーションが可能です。この例では、beansマップのキーをObjectNameとして使用するというデフォルトの戦略を使用しています。さまざまなObjectName戦略の詳細については、Springの配布キットに付属するJavaDocを参照してください。
Springのリモーティング機能のもう1つの側面は、RPC形式のWebサービスをサポートしていることです。WebLogic Serverには、WebサービスのWSDL記述に基づいてJAX-RPCスタブを生成するAntベースのツールが用意されています。Webサービスクライアントは、生成されたこれらのスタブを使用して、サーバサイドの操作を表すリモートインタフェースを取得します。Springでは、JaxRpcPortProxyFactoryBeanを提供することで、この手続きを簡略化します。
WWebLogic Server環境でJaxRpcPortProxyFactoryBeanを正しく構成することは少し厄介であることがわかったため、時間を節約するために、複雑な型を含んだ、ドキュメントリテラルでラップされたWebサービスのプロキシ生成を構成する方法を以下のコード断片で示します。
属性の大半は内容が一目瞭然です。注目すべき属性が以下のようにいくつかあります。
JaxRpcPortProxyFactoryBeanでlookupServiceOnStartupをfalseに設定すると、起動時のJAX-RPCサービスのルックアップが行われなくなります。その代わり、ルックアップは最初のアクセス時にフェッチされることになります。これは、WebLogic Serverの信頼性の高いリクエスト/レスポンス型Webサービス(クライアントもWebサービスでなければならない)と通信するクライアントには必須です。これらの場合にはしばしば、発信元のクライアントがWebサービスクライアントと一緒にデプロイされます。アプリケーションのデプロイメントが終了するまではWebサービスのアクティブ化は起こらないため、Springのコンテキストの読み込みにはクライアントWebサービスは利用できません。applicationContext-ws.xmlコンテキストコンフィグレーションファイルからの抜粋を以下に示します。
<!-- reliable asynchronous Web service for sending new medical records to medrec -->
<bean id="reliableClientWebServicesPortType"
class="org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean"
lazy-init="true">
<property name="wsdlDocumentUrl"
value="http://${WS_HOST}:${WS_PORT}/ws_phys/PhysicianWebServices?WSDL"/>
<property name="portName" value="PhysicianWebServicesPort"/>
<property name="jaxRpcService">
<ref bean="generatedReliableService"/>
</property>
<property name="serviceInterface"
value="com.bea.physician.webservices.client.PhysicianWebServicesPortType"/>
<property name="username" value="medrec_webservice_user"/>
<property name="password" value="weblogic"/>
<property name="customProperties">
<props>
<prop key="weblogic.wsee.complex">true</prop>
</props>
</property>
</bean>
<!-- allows the jaxRpcService class to execute its constructor which loads in type mappings -->
<bean id="generatedReliableService"
class="com.bea.physician.webservices.client.PhysicianWebServices_Impl">
</bean>
詳細については、WebLogic Serverの「Webサービスの呼び出しの概要」とSpringの「 Remoting and Web Services Using Spring」(英語)を参照してください。