1

受信したリクエストと送信したレスポンスを追跡するメカニズムとして参照カウントを使用するアプリケーション コンテナに取り組んでいます。参照カウントは、コンテナーの正常なシャットダウンを許可するために使用されます。つまり、if (refCount == 0) shutdown;

参照カウントは、リクエストごとにインクリメントされ、保留中のレスポンスに対してもインクリメントされます。参照カウントは、アプリケーションが要求を受け入れた場合と、アプリケーションが有効な応答を送信した場合にのみ減分されます。だからここに私の質問がRequestContextあります.アプリケーション/コンテナが応答を送信したときにのみ閉じられる a を保持するのと比較して、参照カウントはこのシナリオで良い設計上の決定ですか?

ソフトウェアは Java で実装されているため、Java の他のオプションを調べていたところ、 http://weblogs.java.net/blog/2006/05/04/understanding-weak-referencesという記事に出くわしました。を活用するReferenceQueueことは、これを行うための別のアプローチになる可能性があります。

4

2 に答える 2

1

それは実際にそれを行うための本当にきちんとした方法です。さらに、ThreadLocalを使用する必要があります(要求-応答パイプラインが単一のスレッドによって処理される場合)

基本的に、リクエストを受け取ったとき。リクエストオブジェクト(またはユーザーIDなどのリクエストの属性)へのWeakRefernceを使用してThreadLocalを設定します。次にget()、処理パイプライン内のどこにでもオブジェクトを配置できます。

ワーカーのThreadPoolを使用してリクエストを処理している場合は、そのオブジェクトの参照が存在しないように、スレッドのThreadLocalから弱参照オブジェクトの設定を解除してください。リクエストごとに新しいスレッドを生成する場合は、それを行う必要はありません。スレッドが終了すると、オブジェクトは自動的にreferenceQueueに戻されます(そのオブジェクトを指すライブ参照がないため)

于 2011-08-03T21:05:16.017 に答える
1

パフォーマンスヒットでそのカウンターの料金を支払うことに注意してください。事実上、リクエストを処理するために同時スレッドを使用しているすべてのリクエストIFFに対してメモリバリアが必要です。(メモリ バリア命令は通常、最大 200 命令のコストがかかります。)

あなたの質問によると、カウンターではなく、フラグなどのアクティブなリクエストがあるかどうかを示すバイナリフラグが必要なようrequestsInProgressです。フラグの値が のときに「正常にシャットダウン」するという考えですfalse

コンテナが主にネットワーク エンドポイント (REST/HTTP など) を公開している場合は、NIO を検討し、シングル スレッドのディスパッチ メカニズムを使用して、コンテナの周辺で要求/担当者を線形化することを強くお勧めします。(これらをキューに入れ、 の同時キューを使用して N 個の処理スレッドにファンアウトできますjava.util.concurrent

[NIO subsystem] <-{poll}-[Selector(accept/read)/dispatch thread] => [Q:producer/consumer pattern 1:N]
[NIO subystem] <-{poll}-[Selector(write)/responder thread] <= [Q:producer/consumer N:1]

利点?

ディスパッチとレスポンダーに同じスレッドを使用する場合、メモリ バリアは関与しません。スレッドはコアに固定され、フラグはそのキャッシュ ラインに排他的になります。

例えば

ディスパッチ キュー リクエストの後: req_in_progress をインクリメントします。

レスポンダがレスポンスをデキューした後: req_in_progress をデクリメントします。

シャットダウン時に共有メモリの同期が必要になりますが、実際に必要な場合にのみ料金が発生するため、リクエストごとにそのコストが発生するよりもはるかに優れています。

パフォーマンスがまったく問題にならない場合はAtomicInteger、カウンタに を使用して、それをグローバル コンテキストに配置してみませんか?

于 2011-08-03T21:58:27.813 に答える