2015-10-04 13 views
13

一部のNettyモジュールの問題を理解するために、Nettyイベントループキューの監視を実装しました。 モニターはほとんどのモジュールで有効なio.netty.util.concurrent.SingleThreadEventExecutor#pendingTasksメソッドを使用しますが、毎秒数千のHTTP要求を処理するモジュールでは、ハングアップしているか非常に遅いようです。 私はこのドキュメントを厳密に指定して問題になると認識しています。Nettyイベントループキューのサイズの監視

あなたがここに古いコードを見ることができます: https://github.com/outbrain/ob1k/blob/6364187b30cab5b79d64835131d9168c754f3c09/ob1k-core/src/main/java/com/outbrain/ob1k/common/metrics/NettyQueuesGaugeBuilder.java

public static void registerQueueGauges(final MetricFactory factory, final EventLoopGroup elg, final String componentName) { 

    int index = 0; 
    for (final EventExecutor eventExecutor : elg) { 
     if (eventExecutor instanceof SingleThreadEventExecutor) { 
     final SingleThreadEventExecutor singleExecutor = (SingleThreadEventExecutor) eventExecutor; 
     factory.registerGauge("EventLoopGroup-" + componentName, "EventLoop-" + index, new Gauge<Integer>() { 
      @Override 
      public Integer getValue() { 
      return singleExecutor.pendingTasks(); 
      } 
     }); 

     index++; 
     } 
    } 
    } 

私の質問は、あるキューのサイズを監視するための良い方法はありますか?

これは、レイテンシを理解するために使用することができ、場合によってはバックプレッシャーを適用するためにも使用できるため、非常に有用なメトリックになります。

答えて

1

SingleThreadEventExecutorインスタンスから追加または削除されたタスクとして、変更を追跡する必要があります。

これを行うには、SingleThreadEventExecutorをラップして拡張するクラスを作成することができます。その後、新しいタスクが追加されるたびにincrementAndGet()と呼ぶjava.util.concurrent.atomic.AtomicIntegerと、削除/終了するたびにdecrementAndGet()と表示されます。

そのAtomicIntegerは現在保留中のタスクの数を示します。代わりにその値を代わりに使用するには、pendingTasks()を上書きすることができます(しかし、注意してください - 私は副作用がない100%ではありません)。

実行中のすべてのタスクに少しのオーバーヘッドが追加されますが、一定の速度に近い保留中のタスクの数を取得することになります。

もちろん、これは、さまざまなイベントエグゼキュータを使用するようにアプリを設定する必要があるため、現時点ではより侵略的です。

NB。これは、問題を回避する方法に関する単なる提案です - 私は特にこれをNettyで行っていません。私は過去にこの種のことを他のコードと一緒に行ってきましたが。

+0

私は内部の詳細をあまりにも頼りにしたくないと思っています。私は、イベントループスレッド内からキューサイズをチェックするタスクを定期的にスケジュールすることを考えると思います。正確ではありませんが、監視には問題ありません。 –