ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録
メインメニュー
フォーラム一覧   -   トピック一覧
   超ビギナー
     RemoteClassを使用したAMF通信のパフォーマンス改善方法
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 トピック
vvata
投稿日時: 2009-12-3 23:31
お馴染みさん
登録日: 2009-2-6
居住地: 千葉
投稿: 18
RemoteClassを使用したAMF通信のパフォーマンス改善方法
RemoteClassを使用してFlexとJavaの通信を行っています。
が、通信量が多く、パフォーマンスがかなり悪化しています。
ByteArrayを使用してDeflate圧縮を行う方法はあるようですが、
RemoteClassを使用した場合に通信を圧縮させる方法はあるのでしょうか。

なお、フレームワークとしてCairngormを使用しており、
FlexとJavaの通信はAMFで行っています。
dsh
投稿日時: 2009-12-4 14:49
ご主人様
登録日: 2006-3-29
居住地: 東京
投稿: 296
Re: RemoteClassを使用したAMF通信のパフォーマンス改善方法
こんにちは、

サーバサイドの構成がわからないのですが、
サーバサイドで、HTTP/1.1のgzip圧縮を有効にするのはどうですか?


----------------
http://shield.jp/blog/
Twitter: @dseg

k-matsumot
投稿日時: 2009-12-4 23:10
ご主人様
登録日: 2009-7-5
居住地: 愛知県一宮市
投稿: 79
Re: RemoteClassを使用したAMF通信のパフォーマンス改善方法
皆様、お疲れ様です。

AIRであればmod_deflate等のGZip圧縮は有効だと思います。が、FlexだとError #2032: Stream Error.でハマるかもです。

http://blog.webkai.net/?tag=/deflate

ググってみると、結局ActionScriptのByteArray.compress();とJava側での DataInputStream#readUTF();になるかもです。

http://un-q.net/2009/07/as3_zip_bytearray_compress.html
http://digitechlog.com/2008/11/01/how-to-use-zip-compression-in-adobe-air-with-actionscript-and-java.html

私もデータ圧縮の検証をやってみようと思っているのですが、自前の鯖が逝きまして。まだ手をつけおりません。
Web上の資料だけで。申し訳無いです。

追って検証できると…いいなぁ。orz
それでは。


----------------
-----
name: k-matsumoto
twitter: @tw_hoehoe
hp: http://community.giga-works.com/

vvata
投稿日時: 2009-12-7 10:12
お馴染みさん
登録日: 2009-2-6
居住地: 千葉
投稿: 18
Re: RemoteClassを使用したAMF通信のパフォーマンス改善方法
反応が遅れて申し訳ありません。
APサーバーにはWebSphereを使用しております。
HTTPサーバーはおそらくIHS(Apache)です。
そして、残念ながらAIRではなくFlexです。
将来的にAIRに変更する可能性はありますが。

自分で調べてはみたものの、ByteArray.compress()を使用する方法しか見つからず、
RemoteClassを使用している場合どうしたら良いのか見当もつかず、お尋ねした次第です。
実際に通信を行っている箇所すら見つけられず…。

ByteArray.compress()を使用する方法に変更した場合の修正量等調べてみたいと思います。
k-matsumot
投稿日時: 2009-12-7 21:39
ご主人様
登録日: 2009-7-5
居住地: 愛知県一宮市
投稿: 79
Re: RemoteClassを使用したAMF通信のパフォーマンス改善方法
ちょっと色々と弄ってみました。
まぁやっつけですが。圧縮・非圧縮のサンプル…です?
長文です。ごめんなさい。

[ CompressFlex.mxml ]
---
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundColor="white">
<mx:Script source="CompressFlex.as"/>

<mx:RemoteObject id="srv" destination="flexService" endpoint="{'http://{server.name}:{server.port}/messagebroker/amf'}" showBusyCursor="true">
<mx:method name="sendData" result="sendDataResult()"/>
<mx:method name="sendDatastr" result="sendDataResult()"/>
</mx:RemoteObject>

<mx:Button x="224" y="47" label="圧縮" click="send();"/>
<mx:TextInput x="56" y="47" id="txtbox"/>
<mx:Button x="280" y="47" label="非圧縮" click="send2();"/>
</mx:Application>
[EOF]
---

[ CompressFlex.as ]
---
// ActionScript file
import flash.utils.ByteArray;
import mx.controls.Alert;

private var start:Date;
private var end:Date;

public function send():void{
start = new Date();
var testString:String = txtbox.text;//"Test - Alice in Wonderland";
var bytes:ByteArray = new ByteArray();
bytes.writeUTF((testString));
bytes.compress();

srv.sendData(bytes);
}
public function send2():void{
var start:Date = new Date();

var testString:String = txtbox.text;//"Test - Alice in Wonderland";
srv.sendDatastr(testString);
}
public function sendDataResult():void{
end = new Date();
Alert.show((end.getTime() - start.getTime()).toString());
}
[EOF]
---

[ WEB-INF\src\com\chocbanana\flex ]
---
package com.chocbanana.flex;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.util.zip.Inflater;

public class CompressFlex {

public void sendData(byte[] bytes) throws Exception {
Inflater decompresser = new Inflater();
decompresser.setInput(bytes, 0, bytes.length);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
byte[] result = new byte[1024];
while (!decompresser.finished()) {
int resultLength = decompresser.inflate(result);
bos.write(result, 0, resultLength);
}
decompresser.end();
DataInputStream ddd = new DataInputStream(new ByteArrayInputStream(bos.toByteArray()));
try {
while (true) {
System.out.println(ddd.readUTF());
}
} catch (EOFException e) {
}
}
public void sendDataStr(String str){
System.out.println(str);
}
}
[EOF]
---

えーっと、FlexとJavaでGZip使う場合は、J2EEのPJL Compressing Filter(http://sourceforge.net/projects/pjl-comp-filter/)がオススメかな?
そーいや自分でも使ってたのを忘れてました。orz
http://blog.dclick.com.br/?s=amf 辺りとか?

web.xmlを

<!-- Filter config with GZIP -->
<filter>
<filter-name>CompressingFilter</filter-name>
<filter-class>
com.planetj.servlet.filter.compression.CompressingFilter
</filter-class>
<init-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>statsEnabled</param-name>
<param-value>true</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>CompressingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

としておけば、全部のパターンでGzipが有効になるハズ…。
スニッファ(Microsoft Network Monitor 3.2)で確認取ったんですけどねぇ。
ヘッダにはdeflateとかgzipなのがくっ付いてたから、多分有効になってるはずなんですけどね…。

というか、これ以上は如何しようも無いような気もしますが。
本当のボトルネックを探す方が大事だと思いますよ。

FlashPlayerはもっさりしか動きませんし、本当に通信部分のデータ量が逼迫しているのか改めて検証されてみては如何でしょうか?
ウチの場合は、VMware ESXiで仮想化していますのでDB鯖のディスクアクセスが恐ろしく遅いのです。

あとは、DBのインデックス使わずに、『全データ表示』ってやって、「遅いんだけどなんとかして」って…。
どーしろと?…みたいなね。はぁ。素引無視スンナぁ!

速いJ2EEコンテナ使うとか、ディスクはSCSIに…とか言い出したらキリが無い話ですが、一応↑のとかアレンジして検証してみてください。


###…本業はPGじゃないんですがね。趣味です完全に。
それでは。


----------------
-----
name: k-matsumoto
twitter: @tw_hoehoe
hp: http://community.giga-works.com/

vvata
投稿日時: 2009-12-9 18:03
お馴染みさん
登録日: 2009-2-6
居住地: 千葉
投稿: 18
Re: RemoteClassを使用したAMF通信のパフォーマンス改善方法
お世話になっております。
わざわざサンプルプログラムまで提示いただき、ありがとうございます。
こちらでもByteArray.compress()の方法で調査していたのですが、
項目が最大数百個あるデータオブジェクトで通信していたりするので、
修正量を考えると現実的ではないな、と考えています。
(データオブジェクトのクラスも数百個あります)

現在、教えていただいたPJL Compressing Filterの方法で検証しており、
フィルターを設定するだけでレスポンスが改善されていることは確認できました。

ただ、初期画面を開く時にJavaを呼んでDBにアクセスしているのですが、
ここがうまく動いたり動かなかったりという状態になってしまい、
初期画面が表示されないケースが多発してしまいました。
直接は関係なさそうな気もしますが、フィルターを外すと正常に動作するので、
どこに問題があるのか調査中です。

とりあえず、Flex-Java間の通信については、PJL Compressing Filterを使う方向で
検討したいと思います。
良い情報を教えていただき、ありがとうございました。
vvata
投稿日時: 2009-12-10 13:41
お馴染みさん
登録日: 2009-2-6
居住地: 千葉
投稿: 18
Re: RemoteClassを使用したAMF通信のパフォーマンス改善方法
引用:
ただ、初期画面を開く時にJavaを呼んでDBにアクセスしているのですが、
ここがうまく動いたり動かなかったりという状態になってしまい、
初期画面が表示されないケースが多発してしまいました。


この原因が判明しました。
正常ケース:IE7
異常ケース:IE6

つまりは↓でした。

引用:
AIRであればmod_deflate等のGZip圧縮は有効だと思います。が、FlexだとError #2032: Stream Error.でハマるかもです。

http://blog.webkai.net/?tag=/deflate

ググってみると、結局ActionScriptのByteArray.compress();とJava側での DataInputStream#readUTF();になるかもです。


エンドユーザーの環境はIE6ですので、残念ながら今回は
この方法は使えなさそうです…。
k-matsumot
投稿日時: 2009-12-11 0:21
ご主人様
登録日: 2009-7-5
居住地: 愛知県一宮市
投稿: 79
Re: RemoteClassを使用したAMF通信のパフォーマンス改善方法
引き続き。

IE6でしたか。
これは回避しようが無いですね…。

ちょいApacheにmod_deflate, mod_headers, mod_rewriteを入れてリコンパイル後、試してみましたが…、NGでした。
あとIE8からIE6にダウングレードとか。

deflate圧縮を使わない(Apache側でIEだったらGZip圧縮をOFFにする-mod_deflate.cにて-)か、もしくはIEのオプションにてHTTP1.1を使用するのチェックをOFFにするかで、deflateを切っちゃうしかないですね。

というか『IE6の仕様』なんですよね、これ。IE6 + GZipで検索かけると沢山沢山出てきますけど。
「IE6を使うなら、GZip圧縮は出来ません。GZip使うならIE7以降を使って下さい」って仕様にするしかないと思います。

回避方法は無いですが、仮にパフォーマンスを上げるならJ2EEコンテナやお使いのFrameworkでキャッシュするってのも1つの手段ではあります。
SpringFramework + iBATIS + PostgreSQLで稼動させてますが、iBATISに検索結果をキャッシュさせて、INSERT/UPDATEもしくは最後に検索してから2時間経っていたらキャッシュは破棄させるようにしておりまして。PostgreSQLも多少パラメータ弄ってるかな?

Classの数も多いので、AOPで(ByteArrayの変換処理を)Injectionしたとしてもかなりキツそうですし。

暗号化処理とかもそうですが、仕様が変更になる場合とかも大いにありえると思うので、コードで対応ってのは作業的に割に合わない(っていうか無駄になる)と思います。(経験済みだったり)

あぁ、回答になってないですね。すみません。orz


----------------
-----
name: k-matsumoto
twitter: @tw_hoehoe
hp: http://community.giga-works.com/

k-matsumot
投稿日時: 2009-12-28 1:46
ご主人様
登録日: 2009-7-5
居住地: 愛知県一宮市
投稿: 79
Re: RemoteClassを使用したAMF通信のパフォーマンス改善方法
GZip compression + Flash Player + IE6 = Nightmare

えー、洒落になってませんが解決しましたので自己レスを兼ねてご報告を。
先に参考にさせて頂いたURLをペタっと。

http://www.google.com/search?hl=ja&safe=off&rlz=1B3GGGL_jaJP336JP336&num=100&q=add-no-cache-headers&btnG=%E6%A4%9C%E7%B4%A2&lr=lang_ja&aq=&oq=
http://www.riaservice.com/?p=526
http://help.adobe.com/ja_JP/LiveCycleDataServicesES/3.0/Developing/WSc3ff6d0ea77859461172e0811f00f6e876-7fd6.html
http://www.adobe.com/support/documentation/jp/flex/2/releasenotes_flex2_fds.html



んで、解決策の方を。

結果としてはHTTPS + IEでの解決策と同様の手順になりました。
BlazeDS側にある WEB-INF\flex\services-config.xml を編集します。


<channels>
<channel-definition id="my-amf"
class="mx.messaging.channels.AMFChannel">
<!--
ここで構成されたエンドポイントURLを mx:RemoteObjectのendpoint プロパティにセットする
{}内は実行時に自動で置き換えられるのでこの記述のままで良い。
-->
<endpoint
url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf"
class="flex.messaging.endpoints.AMFEndpoint" />
</channel-definition>

の中に

<properties>
<add-no-cache-headers>false</add-no-cache-headers>
</properties>

を記述するだけです。これで、mod_deflateやpjl-comp-filterなどによるGZip圧縮を有効にしても、ちゃんと動作するようになると思います。
下記の様に(endpoint以下に)properties部分を加えてWebコンテナを再起動して下さい。

<channels>
<channel-definition id="my-amf"
class="mx.messaging.channels.AMFChannel">
<!--
ここで構成されたエンドポイントURLを mx:RemoteObjectの
endpoint プロパティにセットする
{}内は実行時に自動で置き換えられるのでこの記述のままで良い。
-->
<endpoint
url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf"
class="flex.messaging.endpoints.AMFEndpoint" />
<properties>
<add-no-cache-headers>false</add-no-cache-headers>
</properties>
</channel-definition>

IEオプションのHTTP1.1を有効にして、URLにアクセスした時に動作すればOKかと。
IE6でもOKでしたよ。

結局パケットをキャプチャしてもダメだったので、デバッグ版FlashPlayerをIE6にインストールしてエラーメッセージを読みました。
エラーメッセージの内容は「NetConnection.Call.Failed: HTTP: Status 200」でしたので、それをキーワードにググったところIE + HTTPSの解決策と同じであることが判明致しましたので、ご報告とさせて頂きます。
あ、編集する部分はAMFChannelの方ですよ。念のため。

以上。ご参考までに。


----------------
-----
name: k-matsumoto
twitter: @tw_hoehoe
hp: http://community.giga-works.com/

vvata
投稿日時: 2010-1-7 11:57
お馴染みさん
登録日: 2009-2-6
居住地: 千葉
投稿: 18
Re: RemoteClassを使用したAMF通信のパフォーマンス改善方法
お世話になっております。
しばらく見ていなかったので、反応が遅れてしまいました。

早速教えていただいた方法を試してみたのですが、
見事IE6でも正常に動作し、期待通りの効果も出ているようです。

データ通信部分のパフォーマンス改善はこれで落ち着きそうです。
いろいろと調べていただき、ありがとうございました。
(1) 2 »
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を