|  | レベル: 中級 Shailesh K. Mishra (shailekm@in.ibm.com), Software Engineer, IBM
2007年 8月 16日 Web サービスのパフォーマンスを向上させる方法をお探しなら、ぜひ非同期 Bean をお試しください。この記事では、Web サービスが各種リソースからコンテンツにアクセスして順次ビジネス・オペレーションを実行する方法、そしてこの方法を非同期 Bean によって強化する仕組みを説明します。
はじめに
非同期 Bean は、IBM® WebSphere® Application Server V6.0 の機能の 1 つで、WebSphere Application Server には複数の J2EE (Java™ 2 Platform, Enterprise Edition) アプリケーションがタスクを並行して実行できるようにする一連の API が組み込まれています。非同期 Bean とは、J2EE アプリケーションから非同期で実行することが可能な Java オブジェクトまたは EJB (Enterprise JavaBeans) コンポーネントのことです。非同期 Bean は、その Bean のクリエーターの J2EE コンテキストを使用して非同期で動作します。非同期 Bean のタイプには以下のものがあります。
-
Work は、com.ibm.websphere.asynchbeans.Work インターフェースを実装するオブジェクトです。このオブジェクトは、WorkManager.startWork メソッドを使用して、その呼び出し元と並行に実行されます。
-
AlarmListener は、
com.ibm.websphere.asynchbeans.AlarmListener インターフェースを実装するオブジェクトです。このオブジェクトは、細かい単位での設定が可能なアラームに設定した時間が経過すると呼び出されます。
-
EventListener は、あらゆるインターフェースを実装することができるオブジェクトです。このオブジェクトは、単一の Java 仮想マシン (JVM) 内にある非同期イベント用の軽量で非同期の通知メカニズムとなります。その用途としては主に、さまざまなアプリケーション非同期イベントを互いに通知し合う、単一 EAR ファイル内の J2EE コンポーネントが想定されています。
非同期 Bean についての詳細は、この記事の最後で「参考文献」セクションに記載した Asynchronous beans programming guide やその他の資料を読んでください。
次のセクションでは、非同期 Bean を Web サービスで利用する方法を説明します。
非同期 Bean を Web サービスで利用する
注: Java Web サービスを作成する方法については、IBM Redbooks の 1 つ、「WebSphere Version 6 Web Services Handbook Development and Deployment」を参照してください。
例えば、2 つの異なるリソースからデータをフェッチしてビジネス・ロジックを実行する Web サービスがあるとします。この場合、Work オブジェクト (非同期 Bean のフレーバーの 1 つ) を使って 2 つのタスク (それぞれのリソースからデータを取得すること) をラップすれば、この 2 つのタスクを並行して実行することが可能になります。デモ用として、この Web サービスでは 2 つのテキスト・ファイルのコンテンツを追加して返すという想定にします。このような Web サービスを Java Bean を使って作成する方法は、リスト 1 とリスト 2 に記載するコード・サンプルのとおりです。
リスト 1. Java Bean を使用した Web サービスの作成
package com.demo.asynbean.ws;
import java.util.ArrayList;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.ibm.websphere.asynchbeans.WorkException;
import com.ibm.websphere.asynchbeans.WorkItem;
import com.ibm.websphere.asynchbeans.WorkManager;
/**
* Created on Jul 9, 2007
*
* @author Shailesh K Mishra (shailekm@in.ibm.com)
*
*/
public class WSAsyncBean {
WorkManager workManager = null;
/**
*
*/
public WSAsyncBean() {
super();
// TODO Auto-generated constructor stub
}
public String getContent() {
String str = "";
//get the WorkManager instance first.
if (workManager == null)
getWorkManager();
try {
WorkItem item = workManager.startWork(new FetchFileContentTask("1.txt"));
WorkItem item1 = workManager.startWork(new FetchFileContentTask("2.txt"));
//Create an ArrayList
ArrayList items = new ArrayList();
//Add the previous WorkItems to ArrayList
items.add(item);
items.add(item1);
//Join them using WorkManager workManager
workManager.join(items, WorkManager.JOIN_AND,(int) WorkManager.INDEFINITE);
FetchFileContentTask task1 = (FetchFileContentTask) item.getResult();
FetchFileContentTask task2 = (FetchFileContentTask) item1.getResult();
String contentFromFile1 = task1.getContent();
String contentFromFile2 = task2.getContent();
str = contentFromFile1 + contentFromFile2;
} catch (WorkException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return str;
}
/**
*
*/
private void getWorkManager() {
try {
InitialContext ic = new InitialContext();
workManager = (WorkManager) ic.lookup("java:comp/env/wm/myWorkManager");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
|
リスト 2. Work インターフェースを実装する Java クラス
package com.demo.asynbean.ws;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import com.ibm.websphere.asynchbeans.Work;
/**
* Created on Jul 7, 2007
* @author Shailesh K Mishra (shailekm@in.ibm.com)
*
*/
public class FetchFileContentTask implements Work {
String fileName = "";
String content ="";
public FetchFileContentTask(String filename) {
super();
this.fileName = filename;
}
/*
* (non-Javadoc)
* @see javax.resource.spi.work.Work#release()
*/
public void release() {}
/*
* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
public void run() {
StringBuffer buffer = new StringBuffer();
// read the text file present in root directory.
try {
/*
* read the given file name in this application's root dir(for demo).
* You can perform any task here, e.g.
* fetching data from DB, invoking some other app, web service, etc.
*/
URL url = new URL("http://localhost:9080/WSAsynBeans/"+fileName);
InputStream in = url.openConnection().getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line=br.readLine();
while (line != null) {
try {
buffer.append(line);
line=br.readLine();
}catch (IOException ioe) {
ioe.printStackTrace();
break;
}
}
content = new String(buffer);
} catch (NamingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @return Returns the name.
*/
public String getContent() {
return content;
}
}
|
リスト 1 では、まず Bean クラスが getWorkManager メソッドを呼び出してデフォルト WorkManager の参照を取得します。次に WorkManager の startWork メソッドを呼び出して、2 つのソース・ファイル (FetchFileContentTask クラスにラップ済み) からコンテンツをフェッチします。FetchFileContentTask クラスは Work インターフェースを実装し、それによって 2 つのメソッド (run および release) を実装します。リスト 2 は、この FetchFileContentTask クラスのコードです。両方のタスクが正常に並行処理された後、これらのタスクからファイル・コンテンツを取得して追加します。そして最後に、追加されたストリングが Web サービスによって返されるというわけです。
まとめ
この記事では、非同期 Bean を使用して Web サービスのパフォーマンスを向上させる方法を説明しました。非同期 Bean を使用する上でのメリットは、Web サービスが複数のタスクを並行スレッドとして実行できる一方、各スレッドはそのクリエーターと同じコンテキストで実行されるという点です。
参考文献 学ぶために
製品や技術を入手するために
議論するために
著者について  | 
|  | Shailesh K. Mishra は、インド、グルガオン所在の IBM ソフトウェア研究所のソフトウェア・エンジニアです。現在、「BizPortlets」プロジェクトに従事しており、ビジネス・インテグレーションを専門分野としています。 |
記事の評価
|  |
IBM、IBM ロゴ、および WebSphere は、International Business Machines Corporation の米国およびその他の国における商標です。 Java およびすべての Java 関連の商標およびロゴは、Sun Microsystems, Inc. の米国およびその他の国における商標です。 他の会社名、製品名およびサービス名等はそれぞれ各社の商標です。 |