top / index / prev / next / target / source

2005-07-27 diary: リッチクライアント時代のフレームワークのあるべき姿とは? を考察中…

いがぴょんの日記 日記形式でつづる いがぴょんコラム ウェブページです。

old-v2

リッチクライアント時代のフレームワークのあるべき姿とは? を考察中…

リッチクライアント時代のフレームワークって、何なんだろう、というのをゼロベースで考察中です。、、、私が考えると、どうしても汎用機的な実装を連想してしまいがちなのですけれどもね…。 , 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

端末側に業務系の場合に必要な項目バリデーション処理として、下記のようなものがあります。(ゼロベースで思いつきで書いている点に注意!)

これらを、サーバで処理するのか、クライアントで処理するのか、あるいは両方で処理しなくてはならないのか… 奥が深いです。両方Javaだったら、同じクラスが両方で動作すると、すごくクレバーっぽいです。さて、こういったチェックについてどこまでが自動化(ノンプログラミング化)可能なのかも悩ましい(興味深い)ところです。

次に入力支援機能について つれづれに考えてみました。

気になるのは、ここに書いたような内容の大部分について、単純に開発環境の力を使って ばしばし設定していったら良いのか、あるいは別途 Excelや XMLなどを利用して表形式で管理すべきなのか、という点が気になります。最適解がどれなのか、難しすぎて即答できません。

通信 その2

認証とセッションの仕組みも、リッチクライアントでは考えなくてはなりません。通信そのものは httpsで盗聴をガードしたとしても、それに加えてユーザID+乱数をMD5化して返送して、これを認証トークンとして扱う、などの仕組みの作り込みが欲しいようにも思えます。認証トークンを作り込むと、今度はそれをクリアする処理も併せて作り込まないといけないのが、あたまのいたいところです。 (これは一般的な方法だと 私は思っています)

あるユーザが どのメニューを起動できる、あるいは どのサーバ処理を起動できる、という実行権限まわりについて、クライアント・サーバともにチェックを行わないといけないのかどうかについても、興味深いところです。ちゃんとクラックを防止するには、両方チェックが必須なのでしょうね…

なんとなくありそうな電文イメージ

こうやって考えていくと、Webサービスだけでは いろいろ不足していて、加えて作り込みを実施する必要がある雰囲気ですね。(最近の Webサービス動向は追い切れておりません。)通信の信頼性(接続エラーの際の再接続とか…)とかはどうなっているのかも、把握していません。加えて Apache AXIS最新動向も追っておかないといけないような雰囲気がしてきましたです。

Apache Axis の現状

いまどきの Axisの状況が知りたくなったので Axisのページを見ました。

…私が知らないうちに 1.2正式版がリリースされた上に、加えて 1.2.1までリリースされていました (苦笑)日本語訳サイトがあったのは嬉しかったです。

動作させるには、下記の手順を行いました。(Tomcat 4.1 + Axis 1.2)

Apache Axis の簡単動作確認サンプル

とりあえず動作確認を取ってみました。

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

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呼び出しの高速化

ふと、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開発環境のオンラインヘルプの機能に驚きました。ヘルプ画面上で プログラムを書いて、それをオンラインヘルプ上で実行できるのですから これはびっくりです。、、、文字だけではうまく表現できませんね (苦笑)

Curlとイントラマートとの連動を調査中…

Curlとイントラマートとの連動について これを調査中…。

世間のニュースから


この日記について