5

私が使用する重要なテクノロジは、Glassfish v3、JSF 2.0、JPA 2.0、EclipseLink 2.0.2、log4j 1.2.16、commons-logging 1.1.1 です。

私の問題は、アプリケーションの一部がかなり遅いことです。これをnetbeans 6.8 プロファイリング機能で分析しました。

I. ロギング- log4j と apache commons ロギングを使用して、ロギング ファイルとコンソールにログを生成します。ログは、glassfish のサーバー ログにも表示されます。次のようにロガーを使用します。

    private static Log logger = LogFactory.getLog(X.class);
    ...
    if (logger.isDebugEnabled()) {
        ...
        logger.debug("Log...");
    }

問題は、このような短いステートメントに時間がかかる場合があることです (約 800 ミリ秒)。java.util.logging に切り替えると、それほど悪くはありませんが、非常に遅くなります (200 ミリ秒帯域)。どうしたの?ロギングが必要です...更新- Netbeans 6.8 から Netbeans 6.9.1 に切り替えた後、ロギングが遅いという問題が解決されました。- ログがコンソールに出力されると、Netbeans 6.8 が非常に遅くなる可能性があります?! したがって、Log4J やコモンズのロギングとは何の関係もありませんでした。

Ⅱ.DB 操作: 次の EJB の find メソッドを初めて呼び出すと、2,4 秒かかります。追加の呼び出しは数ミリ秒しか持続しません。では、なぜ最初の操作にそれほど時間がかかるのでしょうか? これは (単に) 接続の確立によるものですか、それとも XFacade の依存性インジェクションと関係がありますか? これらのインジェクションはいつ実行されますか?:

@Stateless
@PermitAll
public class XFacade {
    @PersistenceContext(unitName = "de.x.persistenceUnit")
    private EntityManager em;
    // Other DI's
    ...

    public List<News> find(int maxResults) {
      return em.createQuery(
      "SELECT n FROM News n ORDER BY n.published DESC").setMaxResults(maxResults).getResultList() 
    }
}

III. 依存性注入、JNDI ルックアップ: DI のような ( @EJB ...) とパフォーマンスに関する InitialContext ルックアップに違いはありますか? ローカル、リモート、およびインターフェースなしの EJB の注入に違い (パフォーマンス ビュー) はありますか?

IV. Managed Beans - ViewScope は非常にバグが多く、Request Scoped は常に実用的であるとは限らないため、多くの Session Scoped Bean を使用しています。代替手段はありますか?- これらの Bean は低速で​​はありませんが、セッション全体でサーバー側のメモリに負荷がかかるためです。また、ユーザーがログアウトすると、しばらく時間がかかります!

V. EJB - MDB のみのセッション Bean とシングルトン Bean は使用しません。多くの場合、@EJBアノテーションを使用して他の Bean を注入します。1 つの Singleton Bean は、@Scheduleアノテーションを使用して繰り返し操作を開始します。私が見つけた興味深いことは、EJB 3.1 以降、@Asynchronousアノテーションを使用してセッション Bean メソッドを非同期にすることができるということです。パフォーマンスに関して EJB を実装する場合、一般的に何を考慮する必要がありますか?

特に上記の問題に関して、javaeeアプリケーションのパフォーマンスを向上させるための一般的および/または特定のヒントを誰かが教えてくれるかもしれません。ありがとう!

4

2 に答える 2

4

まず、負荷テスト ツールを使用して実際の環境でアプリケーションをテストする必要があります。IDE で観察した動作からは、実際に有効な結論を出すことはできません。その上、プロファイリングが実際にパフォーマンスを変更することを忘れないでください。

I. ロギング (...) Netbeans 6.8 から Netbeans 6.9.1 に切り替えた後、ロギングが遅いという問題が解決されました。

これは、IDE 内の動作を信頼して使用できない最初の証拠です。

Ⅱ.DB 操作: 次の EJB の find メソッドを初めて呼び出すと、2,4 秒かかります。追加の呼び出しは数ミリ秒しか持続しません。では、なぜ最初の操作にそれほど時間がかかるのでしょうか?

おそらく、一部の GlassFish サービスが (遅延) ロードされているため、ステートレス セッション Bean (SLSB) をインスタンス化する必要があるため、またはEntityManagerFactoryを作成する必要があるためです。プロファイリングは何を言ったのですか?アプリ サーバーのログ記録を有効にすると、なぜ表示されるのですか? その後の呼び出しは問題ないので、何が問題なのですか?

III. 依存性注入、JNDI ルックアップ: DI のような (@EJB ...) とパフォーマンスに関する InitialContext ルックアップに違いはありますか?

JNDI ルックアップは高価であり、古き良きサービスロケーターでキャッシングを使用することが事実上の慣例でした。したがって、DI を使用するときにパフォーマンスが最悪になるとは思いません (実際には、コンテナーがそれを得意としていることを期待しています)。そして正直なところ、それは私にとって懸念事項ではありませんでした。

パフォーマンスの最適化に取り組むときの典型的なワークフローは、1) 遅い操作を検出する、2) ボトルネックを見つける、2) ボトルネックに取り組む、3) それでも操作が十分に速くない場合は、2) に戻る、というものです。私の経験では、ボトルネックは DAL の 90% の時間です。ボトルネックが DI の場合、IMO のパフォーマンスに問題はありません。言い換えれば、あなたは心配しすぎていて、「時期尚早の最適化」に非常に近づいていると思います。

IV. マネージド Bean - ViewScope には非常にバグがあり、Request Scoped は常に実用的であるとは限らないため、多くの Session Scoped Bean を使用しています。代替手段はありますか?- これらの Bean は低速で​​はありませんが、セッション全体でサーバー側のメモリに負荷がかかるためです。また、ユーザーがログアウトすると、しばらく時間がかかります!

質問がありません:)だから、何も言うことはありません。更新(コメントへの回答):会話スコープを使用すると、実際には費用がかからない場合があります。しかし、いつものように、測定します。

V. EJB - MDB のみのセッション Bean とシングルトン Bean は使用しません。多くの場合、@EJB アノテーションを使用して他の Bean を注入します。1 つの Singleton Bean は、@Schedule アノテーションを使用して繰り返し操作を開始します。私が見つけた興味深いことは、EJB 3.1 以降、@Asynchronous アノテーションを使用してセッション Bean メソッドを非同期にすることができるということです。パフォーマンスに関して EJB を実装する場合、一般的に何を考慮する必要がありますか?

SLSB (および MDB) は、一般的に非常に優れたパフォーマンスを発揮します。ただし、SLSB を使用する際に留意すべき点がいくつかあります。

  • リモート呼び出しのオーバーヘッドを回避するために、クライアントと EJB が同じ場所に配置されている場合は、インターフェースより優先Localしてください。Remote
  • ステートフル セッション Bean (SFSB) は必要な場合にのみ使用してください (SFSB は使いにくく、状態の管理にはパフォーマンス コストがかかり、本質的にあまりうまくスケーリングしません)。
  • EJB を過度に連鎖させないようにし (特にリモートの場合)、複数の細粒度メソッド呼び出しよりも粗粒度メソッドを優先します。
  • SLSB プールを調整します (同時クライアントにサービスを提供するのに十分な量の Bean があり、リソースの浪費を避けるために多すぎないようにします)。
  • トランザクションを適切に使用します (たとえば、読み取り専用メソッドには NOT_SUPPORTED を使用します)。

また、その機能が本当に必要で、実際に解決すべき問題 (@Asynchronous など) がない限り、何かを使用しないことをお勧めします。

特に上記の問題に関して、javaeeアプリケーションのパフォーマンスを向上させるための一般的および/または特定のヒントを誰かが教えてくれるかもしれません。ありがとう!

データ アクセス コードに注目してください。これは、ほとんどのビジネス フローの実行時間の 80% を占めると確信しています。

そして、すでにほのめかしたように、実際にパフォーマンスの問題があると確信していますか? 確信が持てません。しかし、もしそうなら、IDE の外でパフォーマンスを測定してください。

于 2010-08-22T01:14:38.603 に答える
1

「時期尚早の最適化」は悪いという点で、Pascal Thivent に同意しました。コードを適切に設計してから、パフォーマンスについて心配してください。

また、パフォーマンスやメモリ節約のために最適化することもできます。朝に頭痛の原因となっているものを選び、それを最適化します。

私は実際、NetBeans のプロファイラーがとても気に入っています。それは最高の無料のものの1つです。

私がお勧めします:

  1. パフォーマンスのためにプロファイリングしますが、範囲を独自のパッケージ (例: de.x) または Java コア クラスを除外するように制限します。これは、アプリケーションがプロファイリングで行き詰まらず、誤解を招くようなパフォーマンス数値が得られないようにするためです。基本的に、下部のバーで示されているように、「オーバーヘッド」をできるだけ低くするようにしてください。

代替テキスト

  1. しばらく Web アプリをブラウズして、CPU 時間のほとんどを占めているものを確認します。また、一部のオブジェクトは遅延ロードされるため、最初にコードにアクセスするときは遅くなる可能性があるという事実にも注意してください。また、JIT コンパイラを使用しているため、最初 (または 2 回目) はコードの実行が遅くなる可能性がありますが、そのコードを頻繁に使用するほど速くなります。要するに、しばらくウェブアプリを使用してください。Seleniumを使用して Web セッションを「記録」し、それを「再生」できます。これにより、「ウォームアップ タイム」を測定する代わりに、より優れたパフォーマンス メトリックを取得し、アプリケーションが実際に遅い場所を確認できます。

  2. 問題の原因となっている特定のコードまたはクラスがある場合は、プロファイリング ポイントを使用して、そのコードが遅くなる原因を正確に確認します。

問題の原因となっている特定のコードがある場合は、遠慮なく投稿してください。

于 2010-08-23T12:45:47.313 に答える