Dromara[新しいオープンソースプロジェクト]DynamicTp、Meituanの動的スレッドプールのアイデアの実践!

ニュース、オープンソースの軽量動的スレッドプール監視-DynamicTp Dromaraコミュニティに参加してください!ようこそ!

以下は、DynamicTpの作成者によるDynamicTpの紹介です。

みなさん、こんにちは。今日は、より実用的なトピックである動的で監視可能なスレッドプールの実践についてお話します。新しいオープンソースプロジェクト(DynamicTp)のアドレスは、記事の最後にあります。交換と学習へようこそ。


バックグラウンド

ThreadPoolExecutorを使用する場合、次の問題点がありますか?

1. ThreadPoolExecutorがコードで作成されますが、適切なコアパラメーター設定の数がわかりません

2.経験に基づいてパラメータ値を設定します。オンラインにした後、サービスを再起動するためにコードを調整および変更する必要があることがわかりました。これは非常に面倒です。

3.スレッドプールは開発者にとってブラックボックスであり、問​​題が発生するまで実行状況を検知することはできません。

上記の問題点がある場合は、動的監視可能スレッドプール(DynamicTp)が役立つ場合があります。

ThreadPoolExecutorのソースコードを見たことがあれば、実行時に対応する値を動的に変更できるいくつかのsetメソッドが実際に提供されていることをおそらくご存知でしょう。これらのメソッドは次のとおりです。

public void setCorePoolSize(int corePoolSize);
public void setMaximumPoolSize(int maximumPoolSize);
public void setKeepAliveTime(long time, TimeUnit unit);
public void setThreadFactory(ThreadFactory threadFactory);
public void setRejectedExecutionHandler(RejectedExecutionHandler handler);

現在、ほとんどのインターネットプロジェクトは実際にはマイクロサービスとしてデプロイされ、独自のサービスガバナンスシステムを備えています。マイクロサービスコンポーネントの分散構成センターは、構成を動的に変更し、リアルタイムで有効にする役割を果たします。では、構成センターを組み合わせて、実行時にスレッドプールのパラメーターを動的に調整できますか?答えは「はい」であり、構成センターの可用性は比較的高くなっています。これを使用すると、構成プッシュの問題についてあまり心配する必要がなくなり、動的スレッドプールコンポーネントの開発の難しさと作業負荷を軽減できます。

要約すると、以下の背景を要約します

  • 広範な:Java開発では、システムパフォーマンスを向上させたい場合、スレッドプールはすでに基本的なツールであり、90%以上の人が使用することを選択します

  • 不確実性:プロジェクトには、IO集約型とCPU集約型の両方の多くのスレッドプールが作成される可能性がありますが、スレッドプールのパラメーターは十分に決定されていません。操作中にパラメーターを動的に調整するメカニズムが必要です。

  • スレッドプールの実行プロセス中の非知覚的でさまざまなインジケーターは、通常は認識できません。開発者がイベントの前および最中にスレッドプールの実行ステータスを認識し、それに対処できるようにするには、一連の監視およびアラームメカニズムが必要です。時間内に

  • 高可用性、構成変更を時間内にクライアントにプッシュする必要があります。高可用性構成管理プッシュサービスが必要です。構成センターは現在ほとんどのインターネットシステムで使用されているコンポーネントであり、それらを組み合わせることで開発量を大幅に削減できます。アクセスの難しさ。


序章

構成センターに基づいてスレッドプールThreadPoolExecutorにいくつかの拡張を行い、実行中のスレッドプールパラメーターの動的な変更を実現します。これはリアルタイムで有効になります。また、スレッドプールの実行ステータスをリアルタイムで監視し、アラームをトリガーします。アラームポリシーが設定されている場合のポリシー。アラーム情報はオフィスプラットフォーム(Dingding、Qiweiなど)にプッシュされます。アラームのディメンションには、(キュー容量、スレッドプールアクティビティ、トリガーの拒否、タスクタイムアウトなど)が含まれます。同時に、監視プラットフォームで視覚的に使用できるように、スレッドプールインジケーターデータも定期的に収集されます。これにより、スレッドプールの負荷を常に把握し、状況に応じて調整し、オンラインビジネスに影響を与える問題を回避することができます。

    |  __ \                            (_) |__   __|
    | |  | |_   _ _ __   __ _ _ __ ___  _  ___| |_ __
    | |  | | | | | '_ \ / _` | '_ ` _ | |/ __| | '_ \
    | |__| | |_| | | | | (_| | | | | | | | (__| | |_) |
    |_____/ __, |_| |_|__,_|_| |_| |_|_|___|_| .__/
             __/ |                              | |
            |___/                               |_|
     :: Dynamic Thread Pool ::

特性

  • Meituanスレッドプールの実践を参照し、スレッドプールパラメータを動的に管理し、監視およびアラーム機能を追加します

  • Springフレームワークに基づいており、SpringBootプロジェクトの使用のみをサポートしています。軽量で、スターターを導入することで使用できます。

  • リアルタイムで有効になる構成センターに基づくスレッドプールパラメーターの動的調整。主流の構成センターと統合され、すでにNacos、Apollo、Zookeeper、Consulをサポートし、カスタム拡張機能の実装用のSPIインターフェイスも提供します。

  • 複数のアラームディメンション(構成変更通知、アクティビティアラーム、容量しきい値アラーム、拒否トリガーアラーム、タスク実行または待機タイムアウトアラーム)を提供する組み込みの通知アラーム機能、エンタープライズWeChat、DingTalkアラーム、およびSPIインターフェイスのデフォルトサポートが提供されます拡張実装をカスタマイズする

  • 組み込みのスレッドプールインジケーター収集機能は、MicroMeter、JsonLogログ出力、およびエンドポイントの3つのメソッドをサポートします。これらは、SPIインターフェイスを介したカスタム拡張によって実装できます。

  • 一般的なサードパーティコンポーネントのスレッドプールを統合および管理し、SpringBootの組み込みWebサーバー(Tomcat、Undertow、Jetty)のスレッドプール管理を統合します。

  • タスクラッピング機能を提供し、TtlTask​​WrapperなどのTaskWrapperインターフェイスを実装するだけでスレッドプールコンテキスト情報の転送をサポートできます

  • JUC共通スレッドプールはフレームワーク(@DynamicTp)によって監視することもできます。Tomcatスレッドプールを参照して、IO集約型のシナリオにEagerDtpExecutorを提供します。


建築デザイン

主に4つのモジュールに分かれています

  • 構成変更監視モジュール:

    1.特定の構成センター(Nacos、Apollo、Zookeeper、Consulが実装されている)の指定された構成ファイルを監視し、他の実装は内部で提供されるSPIインターフェースを介して拡張できます

    2.構成ファイルのコンテンツ、ymlおよびプロパティ構成ファイルの組み込み解析を解析し、内部で提供されるSPIインターフェースを介して他の実装を拡張できます

    3.更新を実行するようにスレッドプール管理モジュールに通知します

  • スレッドプール管理モジュール:

    1.サービスの開始時に構成センターから構成をプルし、スレッドプールインスタンスを生成して、内部スレッドプールレジストリとSpringコンテナに登録します。

    2.監視モジュールは、構成の変更を監視するときに、変更情報を管理モジュールに送信して、スレッドプールパラメーターを更新します。

    3.コードの依存性注入(推奨)またはgetExecutor()メソッドを使用して、スレッドプール名に従ってスレッドプールインスタンスを取得します。

  • 監視モジュール:

    モニタリングインジケータの収集と出力を実現するために、次の3つの方法がデフォルトで提供されており、他の実装も内部で提供されるSPIインターフェイスを介して拡張できます。

    1.デフォルトでは、JsonLogはディスクに出力され、ログを自分で収集および分析し、保存および表示できます。

    2. MicroMeterの収集、MicroMeterに関連する依存関係の導入、および関連するエンドポイントの公開

    3.Thunderstormカスタムエンドポイントエンドポイント。httpからリアルタイムでアクセスできます。

  • 通知アラームモジュール:

    オフィスプラットフォームに接続して、通知とアラーム機能を実現します。デフォルトでは、DingdingとQiweiが実装されています。その他の実装は、内部で提供されるSPIインターフェイスを介して拡張できます。通知とアラームの種類は次のとおりです。

    1.スレッドプールのメインパラメータ変更通知

    2.ブロッキングキューの容量が設定されたアラームしきい値に達しました

    3.スレッドプールアクティビティが設定されたアラームしきい値に達しました

    4.トリガー拒否ポリシーアラーム、形式:A / B、A:アラーム項目の前後の2つのアラーム間隔の累積数、B:アラーム項目の累積合計

    5.タスク実行タイムアウトアラーム、形式:A / B、A:アラーム項目前後の2つのアラーム間隔の累積数、B:アラーム項目の累積合計

    6.タスク待機タイムアウトアラーム、形式:A / B、A:アラーム項目前後の2つのアラーム間隔の累積数、B:アラーム項目の累積合計


使用する

1.対応する構成センターの依存関係を紹介します

2.構成センターでスレッドプールインスタンスを構成します。構成については、以下を参照してください(すべての構成項目が示され、構成項目にはデフォルト値があります)。

3.@EnableDynamicTpアノテーションをスタートアップクラスに追加します

4. @Resourceまたは@Autowiredアノテーションを使用して注入するか、DtpRegistry.getExecutor( "name")を通過します

5.通常のJUCスレッドプールを監視する場合は、@Beanが定義されているときに@DynamicTpアノテーションを追加できます。

6.ヒント:動的スレッドプールインスタンスサービスが開始されると、構成センターの構成に従ってSpringコンテナに動的に登録されます。同じスレッドプールインスタンスを繰り返し宣言するためにプログラムで@Beanを使用しないことをお勧めします。構成センターで直接構成します。

7.詳細については、例の例を参照してください

  • スレッドプール構成(ymlタイプ)

    spring:
      dynamic:
        tp:
          enabled: true
          enabledBanner: true        # 是否开启banner打印,默认true
          enabledCollect: false      # 是否开启监控指标采集,默认false
          collectorType: logging     # 监控数据采集器类型(JsonLog | MicroMeter),默认logging
          logPath: /home/logs        # 监控日志数据路径,默认 ${user.home}/logs
          monitorInterval: 5         # 监控时间间隔(报警判断、指标采集),默认5s
          platforms:                 # 通知报警平台配置
            - platform: wechat
              urlKey: 3a7500-1287-4bd-a798-c5c3d8b69c  # 替换
              receivers: test1,test2                   # 接受人企微名称
            - platform: ding
              urlKey: f80dad441fcd655438f4a08dcd6a     # 替换
              secret: SECb5441fa6f375d5b9d21           # 替换,非sign模式可以没有此值
              receivers: 15810119805                   # 钉钉账号手机号
          tomcatTp:                                    # tomcat web server线程池配置
              minSpare: 100
              max: 400
          jettyTp:                                     # jetty web server线程池配置
              min: 100
              max: 400
          undertowTp:                                  # undertow web server线程池配置
              coreWorkerThreads: 100                   # 核心线程数
              maxWorkerThreads: 400                    # 最大线程数
              workerKeepAlive: 40                     
          executors:                                   # 动态线程池配置,都有默认值,采用默认值的可以不配置该项,减少配置量
            - threadPoolName: dtpExecutor1
              executorType: common                     # 线程池类型common、eager:适用于io密集型
              corePoolSize: 6
              maximumPoolSize: 8
              queueCapacity: 200
              queueType: VariableLinkedBlockingQueue   # 任务队列,查看源码QueueTypeEnum枚举类
              rejectedHandlerType: CallerRunsPolicy    # 拒绝策略,查看RejectedTypeEnum枚举类
              keepAliveTime: 50
              allowCoreThreadTimeOut: false
              threadNamePrefix: test                         # 线程名前缀
              waitForTasksToCompleteOnShutdown: false        # 参考spring线程池设计
              awaitTerminationSeconds: 5                     # 单位(s)
              preStartAllCoreThreads: false                  # 是否预热核心线程,默认false
              runTimeout: 200                                # 任务执行超时阈值,目前只做告警用,单位(ms)
              queueTimeout: 100                              # 任务在队列等待超时阈值,目前只做告警用,单位(ms)
              taskWrapperNames: ["ttl"]                          # 任务包装器名称,集成TaskWrapper接口
              notifyItems:                     # 报警项,不配置自动会按默认值配置(变更通知、容量报警、活性报警、拒绝报警、任务超时报警)
                - type: capacity               # 报警项类型,查看源码 NotifyTypeEnum枚举类
                  enabled: true
                  threshold: 80                # 报警阈值
                  platforms: [ding,wechat]     # 可选配置,不配置默认拿上层platforms配置的所以平台
                  interval: 120                # 报警间隔(单位:s)
    
  • スレッドプール名に従って、または依存性注入を介してDtpRegistryから取得されたコード呼び出し(推奨、よりエレガント)

    @Resource
    private ThreadPoolExecutor dtpExecutor1;
    
    public void exec() {
       dtpExecutor1.execute(() -> System.out.println("test"));
    }
    
    public static void main(String[] args) {
       DtpExecutor dtpExecutor = DtpRegistry.getExecutor("dtpExecutor1");
       dtpExecutor.execute(() -> System.out.println("test"));
    }
    
  • 詳細なユースケースリファレンスexampleプロジェクト


通知アラーム

  • アラームしきい値をトリガーすると、対応するアラームメッセージ(活性、容量、拒否、タイムアウト)がプッシュされ、対応するフィールドが強調表示されます

  • 構成を変更すると通知メッセージがプッシュされ、変更されたフィールドが強調表示されます


モニター

モニタリングデータ

モニタリングデータ

collectTypeプロパティを使用して監視インジケーターの収集タイプを構成します。デフォルトはロギングです。

  • MicroMeter:関連するMicroMeterの依存関係(Prometheus、InfluxDbなど)を導入して、対応するプラットフォームに収集します。

  • ロギング:インジケーターデータを定期的に収集し、Jsonログ形式でディスクに出力します。アドレスは{appName}.monitor.logです。

  • EndPointエンドポイント(dynamic-tp)を公開します。これは、httpからリクエストできます。

    [
        {
            "dtp_name""remoting-call",
            "core_pool_size"6,
            "maximum_pool_size"12,
            "queue_type""SynchronousQueue",
            "queue_capacity"0,
            "queue_size"0,
            "fair"false,
            "queue_remaining_capacity"0,
            "active_count"0,
            "task_count"21760,
            "completed_task_count"21760,
            "largest_pool_size"12,
            "pool_size"6,
            "wait_task_count"0,
            "reject_count"124662,
            "reject_handler_name""CallerRunsPolicy"
        }
    ]
    

プロジェクトをフォローする

プロジェクトに関するアイデアや提案がある場合は、問題を作成してプロジェクトを一緒に改善できます

倉庫の住所、プロジェクトを高く評価することを歓迎します!

https://github.com/dromara/dynamic-tp

https://gitee.com/dromara/dynamic-tp

おすすめ

転載: www.oschina.net/news/191407
おすすめ