このトピックでは、Nacos スレッド数が過剰に多い問題の解決方法について説明します。
問題の説明
監視システムから取得したデータ、またはその他の方法で取得したデータから、アプリケーションのスレッド数が過剰に多く、ほとんどのスレッド名に nacos が含まれていることがわかります。
考えられる原因
システム環境の問題が発生しています。アプリケーションによって読み取られる CPU コア数が無効です。その結果、スレッドプールの コア スレッド数または最大スレッド数が過剰に多くなります。
NacosNamingService インスタンスや NacosConfigService インスタンスなどの Nacos クライアントインスタンスがアプリケーションに対して過剰に多く作成されています。
アプリケーションが誤って使用されています。Nacos クライアントインスタンスは継続的に作成されますが、新しく作成された Nacos クライアントインスタンスを使用して古い Nacos クライアントインスタンスを置き換えるときに、シャットダウンメソッドを使用してスレッドプールをシャットダウンしていません。
解決策
このセクションでは、Java アプリケーションの問題を解決する方法について説明します。他のプログラミング言語のアプリケーションには、同様のコマンドを使用してください。
Nacos クライアントインスタンスが過剰に多く作成されているかどうかを確認します。Nacos クライアントインスタンスの数を確認するには、
jmap -histo ${pid} > histo.logコマンドを実行して、アプリケーション内のメモリインスタンスオブジェクトをログファイルに出力し、ログファイル内のデータをフィルタリングします。# ログファイルから NacosNamingService インスタンスの数を取得します。通常のケースでは、NacosNamingService インスタンスの数は 3 を超えません。 grep "NacosNamingService" histo.log | awk '{print $2,$4}' # ログファイルから NacosConfigService インスタンスの数を取得します。通常のケースでは、NacosConfigService インスタンスの数は 3 を超えません。 grep "NacosConfigService" histo.log | awk '{print $2,$4}'Nacos クライアントインスタンスの数が 10 を超えるなど、過剰に多い場合は、Nacos クライアントインスタンスの数が過剰に多いことが原因である可能性があります。アプリケーションコードを確認して、毎回異なる Nacos クライアントインスタンスが作成されているかどうかを確認します。通常のケースでは、既存の Nacos クライアントインスタンスが再利用されます。詳細については、「dubbo create nacos multiple identical NamingService」をご参照ください。
Nacos クライアントインスタンスの数が正常な場合は、スレッドの数が想定どおりかどうかを確認します。
jstack ${pid} > jstack.logコマンドを実行して、現在のスレッド情報をログファイルに出力し、ログファイル内のデータをフィルタリングして、使用されているスレッドの数を取得します。# Nacos クライアントインスタンスによって使用されているスレッドプール内のスレッドの数を取得します。この数は、次の式で得られる値以下であることが想定されます。Nacos クライアントインスタンスの数 × CPU コア数 × 8。 grep "nacos-grpc-client-executor" jstack.log | wc -l # Nacos クライアントインスタンスの内部イベント通知メカニズムによって使用されているスレッドプール内のスレッドの数を取得します。合計数は 5 以下であることが想定されます。 grep "nacos.publisher-" jstack.log | wc -l # Nacos クライアントインスタンスが Nacos サーバーに再接続し、ping-pong ハートビートを送信するために使用されるスレッドの数を取得します。合計数は、Nacos クライアントインスタンスの数に 2 を掛けた値以下であることが想定されます。 grep "com.alibaba.nacos.client.remote.worker" jstack.log | wc -l # NacosNamingService インスタンスがキャッシュを更新するために使用されるスレッドプール内のスレッドの数を取得します。合計数は、次の式で得られる値以下であることが想定されます。NacosNamingService インスタンスの数 × (CPU コア数/2)。 grep "com.alibaba.nacos.client.naming.updater" jstack.log | wc -l # NacosNamingService インスタンスが UDP を使用してプッシュされたデータを受信するために使用されるスレッドプール内のスレッドの数を取得します。合計数は、NacosNamingService インスタンスの数以下であることが想定されます。 grep "com.alibaba.nacos.naming.push.receiver" jstack.log | wc -l # NacosNamingService インスタンスが切断され、再接続された後に、非永続サービスデータの補償に使用されるスレッドの数を取得します。合計数は、NacosNamingService インスタンスの数以下であることが想定されます。 grep "com.alibaba.nacos.client.naming.grpc.redo" jstack.log | wc -l # NacosConfigService インスタンスのリスニング設定で使用されるスレッドプール内のスレッドの数を取得します。合計数は、NacosConfigService インスタンスの数以下であることが想定されます。 grep "com.alibaba.nacos.client.Worker" jstack.log | grep -v "longPolling" | wc -l # NacosConfigService インスタンスがリスナーをコールバックするために使用されるスレッドプール内のスレッドの数を取得します。合計数は、NacosConfigService インスタンスの数に 5 を掛けた値以下であることが想定されます。 grep "nacos.client.config.listener.task" jstack.log | wc -l # NacosConfigService インスタンスがロングポーリングをリッスンするために使用されるスレッドプール内のスレッドの数を取得します。合計数は、NacosConfigService インスタンスの数に CPU コア数を掛けた値以下であることが想定されます。 grep "com.alibaba.nacos.client.Worker.longPolling" jstack.log | wc -l上記のすべてのスレッド数が上限を超えている場合は、Nacos クライアントインスタンスが継続的に作成されているにもかかわらず、新しく作成された Nacos クライアントインスタンスを使用して古い Nacos クライアントインスタンスを置き換えるときに、シャットダウンメソッドを使用してスレッドプールを無効にしていない可能性があります。その結果、古いスレッドプールが想定どおりに無効になりません。詳細については、「Connection leak risk when using Nacos data-source」をご参照ください。
nacos-grpc-client-executor や com.alibaba.nacos.client.naming.updater など、CPU コア数に関連するスレッドの数のみが上限を超えている場合は、アプリケーションによって読み取られる現在のノードの CPU コア数が無効である可能性があります。ほとんどの場合、この問題はコンテナシナリオで発生します。 Runtime.getRuntime().availableProcessors() メソッドを呼び出すと、アプリケーションによって読み取られる CPU コア数を取得できます。アプリケーションによって読み取られる CPU コア数が過剰に多い場合は、有効な環境を使用して障害のある環境を置き換えることができます。
-Dnacos.common.processorsパラメーターまたはNACOS_COMMON_PROCESSORS環境変数を使用して、環境を強制的に指定することもできます。説明-Dnacos.common.processorsパラメーターとNACOS_COMMON_PROCESSORS環境変数は、Nacos クライアント 2.1.1 以降で有効です。上記のすべてのスレッド数が上限を超えていない場合は、スレッドプールはリークしておらず、スレッド数は過剰に多くありません。この場合、スレッド数を減らすには、
-Dnacos.remote.client.grpc.pool.core.sizeパラメーターと-Dnacos.remote.client.grpc.pool.max.sizeパラメーターを使用して、スレッドプール内の nacos-grpc-client-executor スレッドの数を指定します。説明-Dnacos.remote.client.grpc.pool.core.sizeパラメーターと-Dnacos.remote.client.grpc.pool.max.sizeパラメーターは、Nacos クライアント 2.1.1 以降で有効です。nacos-grpc-client-executor スレッドプールは再利用メカニズムを提供します。Nacos クライアントが長時間リクエストを持たない場合、Nacos クライアントは自動的に余分なスレッドを再利用します。再利用メカニズムには最小スレッド数が指定されています。デフォルトの最小スレッド数は、CPU コア数に 2 を掛けた値です。大量のリクエストが開始されると、スレッド数は自動的に増加します。再利用メカニズムには最大スレッド数も指定されています。デフォルトの最大スレッド数は、CPU コア数に 8 を掛けた値です。一部の監視システムでは、同じスレッド名に対応するスレッド ID の数が増加します。これは正常な現象です。