2011-01-04 5 views
1

更新:プレストンが指摘したように、次の問題はオブジェクトの直列化に関連している可能性があります。どのようにこれを最適化するための任意のアイデア?アプリケーションクライアント<-> EJBコールのラウンドトリップが遅いようです


私は現在、古いJavaEEアプリケーションでいくつかのことを修正しています。これは、EJBモジュールとアプリケーションクライアントモジュールを使用しています。 EJBはすべてのデータベースクエリを処理します。この例では、特定の年の "エンタープライズ"エンティティを返すメソッドgetEnterprises(int year)を考えてみましょう。現在、それは約2500のエントリです。

注:「エンタープライズ」という単語は、説明の目的でのみ使用しています。 )

ここでは、エンタープライズエンティティには、codenameという2つのフィールドしかないとしましょう。リモート豆の内部メソッドは次のようになります。アプリケーションクライアントで

public List<Enterprise> getEnterprises(int year){ 
    return em.createQuery("SELECT e FROM Enterprise e WHERE e.year=:year") 
     .setParameter("year", year) 
     .getResultList(); 
} 

、このような行があります:

List<Enterprise> result = requestBean.getEnterprises(1996); 

は、これは私には正しいようです。私にとって奇妙なことは、クライアントの呼び出しには約15秒かかります!だから私はいくつかのログを追加しました:クライアント上で、それはとりながら、結果のタイムスタンプから

public List<Enterprise> getEnterprises(int year){ 
    logger.finest("Begin fetch on remote"); 
    List<Enterprise> output = em.createQuery("SELECT e FROM Enterprise e WHERE e.year=:year") 
     .setParameter("year", year) 
     .getResultList(); 
    logger.finest("End fetch on remote"); 
    return output; 
} 

と...

logger.finest("Begin fetch on client"); 
List<Enterprise> result = requestBean.getEnterprises(1996); 
logger.finest("End fetch on client"); 

を、私は、サーバー上のコールが1秒未満で完了したことに気づきました15秒以上。

手書きトレース:

2011-01-04 12:00 | FINEST | Begin fetch on client 
2011-01-04 12:00 | FINEST | Begin fetch on remote 
2011-01-04 12:01 | FINEST | End fetch on remote 
2011-01-04 12:17 | FINEST | End fetch on client 

だから私はこの問題は、クライアント/サーバ間の通信にあると推測しています。上記の例では、クライアント - >サーバ通信が遅いか、サーバ - >クライアント通信かをチェックしなかったことに注意してください。私が気づいたのは、サーバーログが "期待される"実行時間を示すのに対し、クライアントでは遅いということです。私はそのくらいに掘っていない

2011-01-04 12:00 | FINEST | Begin fetch on client 
2011-01-04 12:07 | FINEST | Begin fetch on remote 
2011-01-04 12:08 | FINEST | End fetch on remote 
2011-01-04 12:17 | FINEST | End fetch on client 

2011-01-04 12:00 | FINEST | Begin fetch on client 
2011-01-04 12:15 | FINEST | Begin fetch on remote 
2011-01-04 12:16 | FINEST | End fetch on remote 
2011-01-04 12:17 | FINEST | End fetch on client 

あるいは:他の言葉では、それは同様に、同様にこのようなものかもしれません。

私はJavaEEについて多くの経験をしていないので、私はジャングルで少し失われています。あまりにも多くの設定、コンポーネントがあり、どこから始めたらいいかわからないことがあります。それはサーバー設定ですか? Bean自体の問題?私が豆と呼ぶ方法は?私は知らない...

...ああ...それはグラスフィッシュで実行され、テストのために、localhostで実行されます。だからネットワーク自体は問題ではありません...

答えて

2

このようなネットワーク関連のものについては、私の最初の呼び出し先は、時刻がの場合、実際にはになります。Wiresharkはあなたの友人です。ログステートメントをネットワークトラフィックにマップしてみてください。完了したサーバーログとネットワーク上で配信されるデータとの間に大きな遅延がある場合は、サーバー側の構成などをさらに調べる必要があります。データがクライアントに配信されていても、完了するために呼び出し、クライアントを見てください。データがサーバーとクライアント間で15秒間に渡ってゆっくりと転送されている場合、それは完全に別のものになる可能性があります(また、両側を見る必要があります)。

異なるマシンでサーバーとクライアントを実行したい場合、物理的なインターフェイスを経由する必要がある場合は、ネットワークトレースを簡単に行うことができます。

+0

お電話ください。準備が整ったらテストサーバーがあります。私はそこに展開し、それがどのように進むのかを見てみましょう... – exhuma

+0

私は午後全体で2番目のサーバーで作業しているログを取得しようとしています。私の人生にとって、私はログ出力を得ることはできません。私は今、私のメッセージを「厳しい」ものにしました。まだ出力はありません... 'S.o.println()'で 'start-domain --verbose = true'を試みました。運がない...これは私の頭を傷つける。ここで働いているので、localhostから 'domain.xml'をコピーしようとします。 – exhuma

1

2番目の手書きトレース(低速接続、高速リターン)のようなプロファイルは、DNSルックアップに関連する可能性があります。私は最近、同様の問題を抱えていました - 高速なping、ローカルホストへの接続が非常に遅い(45秒)。/etc/hostsに名前エントリを追加すると、完全修飾ホスト名を高速に検索できました。

1

クライアントがリストを受け取るためには、リストを送信する前にシリアル化する必要があります。それをサーバー上でシリアル化して、どれくらい時間がかかるかを確認してください。その後、あなたの15秒間からその時間を差し引いて、まだ問題があるかどうかを確認してください。

+0

私はこれがCPUとメモリだけであると仮定していますか?それで、私はこれが問題ではないと思います。しかし、オフチャンスでは、これはその場合でしょう:どのようにそれをテストするつもりですか? – exhuma

+0

シリアライズにはたくさんの方法がありますが、1行しか返さないようにクエリを変更する方がよい場合もあります。 – Preston

+0

これはそうだ。 1つのエントリだけに制限することで、メソッド呼び出しにかかる時間が大幅に短縮されました。どのようにこれを最適化するための任意のアイデア? – exhuma

関連する問題