top / index / prev / next / target / source
日記形式でつづる いがぴょんコラム ウェブページです。
リッチクライアント時代のフレームワークって、何なんだろう、というのをゼロベースで考察中です。、、、私が考えると、どうしても汎用機的な実装を連想してしまいがちなのですけれどもね…。 , Apache Axisを久しぶりに調べました。ちょっとしたサンプルを書いて動作確認を取りました。
リッチクライアント時代のフレームワークとは何なのでしょうね。ゼロベースで考察中です。ゼロベースに加えて、つれづれ考察中です。
通信
リッチクライアントの通信を考える上で、すぐに連想するのは従来型のクライアント/サーバ型システムです。しかし 少なくとも 従来型のクライアント/サーバ型システムで良く行われていた、データベース・ミドルウェアによる通信をベースとしたシステムとは根本的に異なるアプローチを取る必要があるのでしょうね。いろいろな理由はあるのですが、データベースミドルウェアを使うと、クライアント側に設定が必要になりがちだったり、ソケットのポートを開かないといけなかったりしますから。ではデータベース/ミドルウェアを使わないとすると、何かミドルウェアを作るか使うかすることになる必要が出てくることでしょう。イマドキだから HTTPベースで実装しないといろいろな問題が噴出しそうなことは これは確かです。というのも、大きな企業においては、HTTPしか通過できないネットワーク上の制約がある場合が多いからです。ということで、HTTP (またはHTTPS) による通信は MUST であるようですね。
安直に考えたら、HTTPベースというと Webサービスというテクノロジが もっとも最初に思いつく通信ミドルウェアです。Webサービスの一般的な実装においては型チェックや名称のコンパイル時チェックができる点も魅力です。これにより、単体バグが結合バグへと誤流入するのを防いでくれます。Webサービスの一般的な実装が少し CPUを食い過ぎる例が多い、というのを我慢したら、Webサービスはもっとも安定感を感じる 魅力的な通信方法です。
そうではなくって もっと ずっと大げさに考えると、汎用機で提供されているような端末プロトコルと似た機能を実現する通信ミドルウェアを作り込むのが、最適解であるように考えられます。(負荷がかかりすぎない範囲で、という条件付きで)常に通信を行い、端末の動作状況を常にサーバ上で監視します。むろん、端末からのポスト時には伝送を行います。端末の動作状況確認に合わせて、メッセージを載せるなどのプッシュ型の機能の実装の余地が出来るのは嬉しいです。このように一般的な汎用機的な端末制御を行うことができるような通信を実装すれば、汎用機であたりまえのことがオープン系でも実現できます。サーバ上でクライアントの各種管理は当然行うことが出来るようになります。とにかく汎用機的な通信を実装すると、完全な端末管理が可能であったり、あるいはプッシュを実現できるというのは大きな魅力です。
何にせよ要件次第なのでしょうけれども、あまりWeb的な発想にとらわれることなく、(しかし古典をひもといて汎用機的な発想も行いながら) ベストな通信手段を考えることが肝要なのでしょう。
端末 (クライアント)
とりあえずクライアント側は 汎用機時代の実装とは異なり インテリジェントな仕組みとして実装するのでしょう。(むろんサーバから画面を送出するというのもおもしろいアイデアには違いないのですけれども…) Visual Basicとかの良いところは、サーバ無しで単に動作可能であるところなのでしょう。
ymotoさんと話していて気づかされたのですが、中途半端なフレームワーク化は 開発生産性の障害となることが多いようです。クライアントは純にクライアントとして単体で動作するよう気をつけて、あまりフレームワークで押さえない、というのもひとつである一方、やるならやるで、そこいら中をフレームワークでカバーするというのも良い模様です。徹底的ではない中途半端なモジュール化が、もっとも開発生産性を阻害するようです。(作ることが不可能な画面がたやすく登場してしまいがちになる模様) Java + SWTベースで例えると、Eclipse Visual Editor が十分に成熟したら 基本路線として Visual Editorで開発してツナギのところだけ何か共通部品を呼び出す、というのも選択肢の一つであるもようです。一方で、こってこてに作り込みまくって、Visual Editorが実現する領域と同等な画面設計ツールを提供してしまうのも作戦上は ありえる選択肢である模様です。…ちなみに 最新版の Eclipse Visual Editor 1.1 の威力がどの程度のものなのかは私には不明です。Eclipse Visual Editor が Visual Basicと同等の操作性・生産性を提供してくれるものであれば、世間動向に大きなインパクトを与えそうです。…ああ、横道にそれています (苦笑)
そもそもフレームワークって何なんだろう… (苦笑)
ゼロベースで考えていると、じゃあ、そもそもフレームワークって何なんだろう、という根源的なところに疑問を感じだしました。ふむ、考察はいったん中断。
…昼飯を食べた後、考察を再開。
端末 (クライアント) その2
端末側に業務系の場合に必要な項目バリデーション処理として、下記のようなものがあります。(ゼロベースで思いつきで書いている点に注意!)
必須入力項目のバリデーション処理
フォーマット指定付き項目のバリデーション処理
数値、半角文字、全角文字、日付、MAX、MIN、正規表現 など
単項目に対するバリデーション処理(データベース入出力処理を伴わないもの)
業務っぽい入力チェック処理
複数項目処理に対する組み合わせチェック処理(データベース入出力処理を伴わないもの)
業務っぽい入力チェック処理
これらを、サーバで処理するのか、クライアントで処理するのか、あるいは両方で処理しなくてはならないのか… 奥が深いです。両方Javaだったら、同じクラスが両方で動作すると、すごくクレバーっぽいです。さて、こういったチェックについてどこまでが自動化(ノンプログラミング化)可能なのかも悩ましい(興味深い)ところです。
次に入力支援機能について つれづれに考えてみました。
かな漢字変換機能の ON/OFF
ファンクションキー、ENTERキー、矢印キーによる入力操作支援
必須入力項目のハイライト表示。カレント項目のハイライト表示。エラー項目のハイライト表示。
エラー時にカレント項目をエラー項目にコントロール。
コードを途中まで入力した際に動作する入力補完機能
コードが不明な際にポップアップでコードを入力する入力便利機能
気になるのは、ここに書いたような内容の大部分について、単純に開発環境の力を使って ばしばし設定していったら良いのか、あるいは別途 Excelや XMLなどを利用して表形式で管理すべきなのか、という点が気になります。最適解がどれなのか、難しすぎて即答できません。
通信 その2
認証とセッションの仕組みも、リッチクライアントでは考えなくてはなりません。通信そのものは httpsで盗聴をガードしたとしても、それに加えてユーザID+乱数をMD5化して返送して、これを認証トークンとして扱う、などの仕組みの作り込みが欲しいようにも思えます。認証トークンを作り込むと、今度はそれをクリアする処理も併せて作り込まないといけないのが、あたまのいたいところです。 (これは一般的な方法だと 私は思っています)
あるユーザが どのメニューを起動できる、あるいは どのサーバ処理を起動できる、という実行権限まわりについて、クライアント・サーバともにチェックを行わないといけないのかどうかについても、興味深いところです。ちゃんとクラックを防止するには、両方チェックが必須なのでしょうね…
なんとなくありそうな電文イメージ
リクエスト
共通ヘッダ
レスポンス
共通ヘッダ
こうやって考えていくと、Webサービスだけでは いろいろ不足していて、加えて作り込みを実施する必要がある雰囲気ですね。(最近の Webサービス動向は追い切れておりません。)通信の信頼性(接続エラーの際の再接続とか…)とかはどうなっているのかも、把握していません。加えて Apache AXIS最新動向も追っておかないといけないような雰囲気がしてきましたです。
いまどきの Axisの状況が知りたくなったので Axisのページを見ました。
Apache: WebServices - Axis http://ws.apache.org/axis/ 1.2.1 最終版がリリース済み
WebServices - Axis 日本語訳 http://ws.apache.org/axis/ja/index.html
…私が知らないうちに 1.2正式版がリリースされた上に、加えて 1.2.1までリリースされていました (苦笑)日本語訳サイトがあったのは嬉しかったです。
動作させるには、下記の手順を行いました。(Tomcat 4.1 + Axis 1.2)
解凍して得られる webapps\axis を C:\Program Files\Apache Group\Tomcat 4.1\webapps にコピー
jaxrpc.jar と saaj.jar を C:\Program Files\Apache Group\Tomcat 4.1\common\lib にコピー
JavaBeans Activation Framework (JAF) の activation.jar を C:\Program Files\Apache Group\Tomcat 4.1\common\lib にコピー http://java.sun.com/products/javabeans/glasgow/jaf.html
とりあえず動作確認を取ってみました。
Apache Axis 1.2.1
Sun Java SE 5
Jakarta Tomcat 4.1 KantanHello.jws
public class KantanHello {
public String hello(String arg) {
return "こんにちは[" + arg + "]";
}
}
このファイルを C:\Program Files\Apache Group\Tomcat 4.1\webapps\axis にコピーします。 http://localhost:8080/axis/KantanHello.jws?wsdl に接続して得られた WSDLをファイルに保存します。ファイル名は KantanHello.wsdl としました。※他にもっとクレバーな方法はあるかと思います。
WSDL2Javaを実行して Javaソースコードを生成します。 java -classpath axis.jar;commons-logging-1.0.4.jar;commons-discovery-0.2.jar;jaxrpc.jar;saaj.jar;wsdl4j-1.5.1.jar org.apache.axis.wsdl.WSDL2Java -t -s KantanHello.wsdl
生成後のソースコードをサンプルソースコードから呼び出すようにして実行します。 TestCaller.java
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
import localhost.axis.KantanHello_jws.KantanHello;
import localhost.axis.KantanHello_jws.KantanHelloServiceLocator;
public class TestCaller {
private static final int COUNT = 500;
private static void callMethod(boolean isSysout) throws ServiceException,
RemoteException {
KantanHello hello = new KantanHelloServiceLocator().getKantanHello();
String result = hello.hello("疎通試験");
if (isSysout) {
System.out.println(result);
}
}
public static void main(String[] args) {
try {
long start = System.currentTimeMillis();
callMethod(true);
long end = System.currentTimeMillis();
System.out.println("初回呼出の所用時間:" + (end - start) + "ミリ秒");
start = System.currentTimeMillis();
for (int index = 0; index < COUNT; index++) {
callMethod(false);
}
end = System.currentTimeMillis();
System.out.println("" + COUNT + "件処理するための所用時間:" + (end - start)
+ "ミリ秒");
System.out.println("1件あたり:" + (end - start) / COUNT + "ミリ秒");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
実行に必要なライブラリ * axis.jar
commons-discovery-0.2.jar
commons-logging-1.0.4.jar
jaxrpc.jar
saaj.jar
wsdl4j-1.5.1.jar 実行のサンプル・コマンドラインjava -classpath bin;lib/axis.jar;lib/jaxrpc.jar;lib/commons-logging-1.0.4.jar;lib/commons-discovery-0.2.jar;lib/saaj.jar;lib/wsdl4j-1.5.1.jar TestCaller
Intel PentiumM 1.10GHz マシンでローカル接続動作させた際の参考値を下記に示します。 呼出回数初回呼出の処理時間1件あたり処理時間1 1121ミリ秒 30ミリ秒 10 1212ミリ秒 24ミリ秒 100 1202ミリ秒 39ミリ秒 1000 1162ミリ秒 19ミリ秒
初回のオーバーヘッドがかなり大きいのですが、次回以降は 少なめになるようです。(本当の初回にはコンパイルが行われるので、もっと時間がかかります)とりあえず ローカルホストであれば、SOAPのオーバーヘッドは Axis 1.2では 当初私が予想していたほどは大きくはない模様です。1件あたり 30ミリ秒前後程度であれば、処理時間という観点だけでいえば なんとかぎりぎり許容できる場面もあることでしょう。(ローカル接続とはいえ TCP/IP+HTTPで接続を行っているのですから、ある程度のフットプリントはやむを得ないようにも思えます) むろん、過負荷環境下での動作や メモリ消費量など、まだまだ調査しなくてはならない観点はありそうですけれどもね…
SOAとかいうキーワードが流行っているので、Axisを マジメに学んでおいた方が良いように感じる今日この頃…
ふと、SOAPのソケットをKeep Aliveの話題を思い出し、それじゃあということで、オブジェクトを使い回す版を作成して再度計測してみました。 TestCaller.java
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
import localhost.axis.KantanHello_jws.KantanHello;
import localhost.axis.KantanHello_jws.KantanHelloServiceLocator;
public class TestCaller {
private static final int COUNT = 1000;
private static void callMethod(boolean isSysout) throws ServiceException,
RemoteException {
KantanHello hello = new KantanHelloServiceLocator().getKantanHello();
String result = hello.hello("疎通試験");
if (isSysout) {
System.out.println(result);
}
}
public static void main(String[] args) {
try {
long start = System.currentTimeMillis();
callMethod(true);
long end = System.currentTimeMillis();
System.out.println("初回呼出の所用時間:" + (end - start) + "ミリ秒");
start = System.currentTimeMillis();
KantanHello hello = new KantanHelloServiceLocator()
.getKantanHello();
for (int index = 0; index < COUNT; index++) {
String result = hello.hello("疎通試験");
}
end = System.currentTimeMillis();
System.out.println("" + COUNT + "件処理するための所用時間:" + (end - start)
+ "ミリ秒");
System.out.println("1件あたり:" + (end - start) / COUNT + "ミリ秒");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
これが 予想通り、高速化につながることがわかりました。 呼出回数1件あたり処理時間1 30ミリ秒 10 19ミリ秒 100 16ミリ秒 1000 11ミリ秒
これは、「サンプルのためのサンプル」ではないと私は考えます。Webサービスをうまく設計すれば、速度向上につながりうるのです。「Webサービスを利用する場合の効果的な物理設計指針」につながる結果であると判断しています。Webサービスを何か業務領域などの単位によって ファサード化して提供することによって、Webサービス呼び出しの速度向上につながるのだ、という強いメッセージがこの試験結果から感じ取られます。
ここまでくると、あと直感的に実施していなくて具合が悪いと感じられるものに、RMIとSOAPとの速度比較があります。EJBとの速度比較も意義があることでしょうが、私は EJBに疎いので、こちらはパスするでしょう…。重要な点は「SOAPは本当に遅い(重い)のか?」というところを 実証して検証していくことに価値がありそうなのです。
2005.07.28追記 後日談。Java RMIに比べて、SOAPは桁違いに遅いということが分かりました。一方で Java Servletという仕組みである上でのオーバーヘッドの存在も見逃せないことが分かりました。
関連する日記
Curl開発環境のオンラインヘルプの機能に驚きました。ヘルプ画面上で プログラムを書いて、それをオンラインヘルプ上で実行できるのですから これはびっくりです。、、、文字だけではうまく表現できませんね (苦笑)
Curlとイントラマートとの連動について これを調査中…。
情報・通信・IT (0200) [One Topic All View / 最新のWeb開発環境で業務提携 http://www.vxc.jp/cbbs/cbbs.cgi?mode=al2&namber=315&rev=&no=2&KLOG=14 http, https, SOAP接続で連動を実現しているようです。
CURL関連情報リンク集 http://www.hyuki.com/yukiwiki/wiki.cgi?CURL%B4%D8%CF%A2%BE%F0%CA%F3%A5%EA%A5%F3%A5%AF%BD%B8
NTTデータ イントラマートとカール・アジアパシフィックは最新のWeb開発環境で業務提携しました 2004年9月30日 http://www.scs.co.jp/news/10new/20040930.htm