コンシューマーは、レジストリからプロバイダーのリストをサブスクライブします。レジストリが変更された場合、予期しない問題が発生した場合、またはネットワークや CPU 負荷などの要因によりプロバイダーとレジストリ間の接続が切断された場合、サブスクリプション例外が発生する可能性があります。その結果、コンシューマーは空のプロバイダーリストを取得する可能性があります。 Nacos クライアントまたは Microservices Engine (MSE) Nacos サーバーで空のリスト保護を有効にして、システム全体の可用性を向上させることができます。
前提条件
MSE がアクティブ化されていること。詳細については、MSE のアクティブ化 をご参照ください。
Nacos エンジンが作成されていること。詳細については、Nacos エンジンの作成 をご参照ください。
クライアントでの空のリスト保護の有効化
制限事項
1.4.1 以降の Nacos Java クライアントは、空のリスト保護をサポートしています。
特定のバージョンに起因するリスクを防ぐために、推奨バージョン に基づいて、クライアント、Spring Cloud アプリケーション、および Dubbo アプリケーションに適切なバージョンを選択することをお勧めします。
手順
Nacos Java クライアントを使用する場合は、次の操作を実行します。
次の
Nacos クライアントの依存関係を追加します。<!-- ${nacos-client.version} は 1.4.1 以降である必要があります。 --> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>${nacos-client.version}</version> </dependency>アプリケーションコードで次の設定を構成します。
Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, "${MSE Nacos インスタンスのエンドポイント}"); // エンドポイントを設定 properties.put(PropertyKeyConst.NAMING_PUSH_EMPTY_PROTECTION, "true"); // 空のリスト保護を有効にする NamingService naming = NamingFactory.createNamingService(properties);
アプリケーションが Spring Cloud Alibaba アプリケーションの場合は、アプリケーションの構成ファイルに次の構成を追加します。
spring.cloud.nacos.discovery.namingPushEmptyProtection=trueアプリケーションが Dubbo アプリケーションの場合は、Dubbo アプリケーションの構成ファイルに次のレジストリ URL 構成を追加します。
dubbo.registry.address=nacos://${MSE Nacos インスタンスのエンドポイント}:8848?namingPushEmptyProtection=true
サーバーでの空のリスト保護の有効化
多数の非 Java クライアントと 1.4.1 より前のバージョンの Nacos Java クライアントがまだ使用されています。 MSE は、オープンソースの Nacos に基づいて Nacos サーバーの機能を最適化し、Nacos サーバーに空のリスト保護を提供します。
制限事項
Nacos エンジンバージョンは 2.1.0.0 以降である必要があります。 Nacos エンジンバージョンのアップグレード方法の詳細については、Nacos バージョンの更新 をご参照ください。
手順
空のリスト保護を有効にする方法は、MSE Nacos エンジンのバージョンによって異なります。
MSE Nacos エンジンのバージョンが 2.1.0.0 または 2.1.0.1 の場合、操作は必要ありません。これらのバージョンでは、空のリスト保護が自動的に有効になります。
MSE Nacos エンジンのバージョンが 2.1.0.2 以降の場合は、次の手順を実行して空のリスト保護を有効にします。
MSE コンソール にログインし、上部のナビゲーションバーでリージョンを選択します。
左側のナビゲーションペインで、マイクロサービスの登録 > インスタンス を選択します。
インスタンス ページで、インスタンスの名前をクリックします。
左側のナビゲーションペインで、Parameter Settings をクリックします。 Parameter Settings ページの Real-time Effective Parameters セクションで、forcePushEmptyProtectionForAllService パラメーターの 操作 列の Edit をクリックします。
Edit Parameters ダイアログボックスで、Value に Yes を選択し、OK をクリックします。
説明最高のサービス可用性を確保するために、すべての場合において forcePushEmptyProtectionForAllService パラメーターの Value に Yes を選択することをお勧めします。
結果の確認
サービスが空リスト保護をトリガーすると、コンシューマーが存在するノードの ${user.home}/logs/nacos ディレクトリにある naming.log ファイルに /* サービスの空のプッシュ保護をトリガーする */ と表示されます。
通常、このような情報は頻繁に表示されません。このような情報が頻繁に表示される場合は、次の考えられる原因に基づいてこの問題のトラブルシューティングを行うことができます。
コンシューマーがサブスクライブしているプロバイダーが存在しません。
コンシューマーが既存ではないプロバイダーにサブスクライブしている場合は、アプリケーションの依存関係が必要かどうかを確認する必要があります。アプリケーションの依存関係が必要ない場合は、無効な依存関係を削除します。アプリケーションの依存関係が必要な場合は、プロバイダーを再公開する必要があります。
インスタンスリストにプロバイダーが表示されません。
コンシューマーがサブスクライブしているプロバイダーが頻繁に切断されているかどうかを確認します。
各プロバイダーと MSE Nacos インスタンス間のネットワーク接続が正常かどうかを確認します。ネットワーク接続が異常な場合、MSE Nacos インスタンスはプロバイダーが切断されていると判断します。
空のリスト保護をトリガーするサービスの特定
エラーメッセージには、空のリスト保護をトリガーしたサービスに関する情報が含まれています。Service{namespace='XXX', group='xx', name='xxxxxxx', ephemeral=true, revision=0} に基づいて、コンシューマーがサブスクライブしている空のサービスを特定できます。
既知のトリガーシナリオ
シナリオ | 原因 | 解決策 |
Dubbo 2 バージョンに互換性のあるマルチサブスクリプションシナリオでは、サービス名が古い形式のプロバイダーはインスタンスリストに表示されません。 | 2.7.6 より前のバージョンのプロバイダーのサービス名形式は、Dubbo 2.7.6 以降のプロバイダーのサービス名形式とは異なります。 Dubbo 2.7.6 以降のプロバイダーが使用されるマルチサブスクリプションシナリオでは、コンシューマーはサービス名が古い形式のプロバイダーとサービス名が新しい形式のプロバイダーの両方にサブスクライブします。すべてのプロバイダーのバージョンが Dubbo 2.7.6 以降の場合、サービス名が古い形式のプロバイダーは Nacos インスタンスに登録できません。その結果、コンシューマーがサービス名が古い形式のプロバイダーにサブスクライブすると、空のリスト保護がトリガーされます。 | エンジンバージョンを 2.1.0.1 以降にアップグレードするか、Dubbo バージョンを 2.7.17 以降にアップグレードします。詳細については、エンジンバージョンのアップグレード をご参照ください。 |
Dubbo 3 バージョンに互換性のあるマルチサブスクリプションシナリオでは、サービス名がインターフェースレベルのサービス名であるプロバイダーはインスタンスリストに表示されません。 | Dubbo 3 はアプリケーションレベルのサービスディスカバリをサポートしています。登録されているサービス名は、インターフェースレベルのサービス名ではなく、アプリケーションレベルのサービス名です。 Dubbo バージョンのスムーズなアップグレードを確実にするために、コンシューマーはサービス名がアプリケーションレベルのサービス名であるプロバイダーとサービス名がインターフェースレベルのサービス名であるプロバイダーの両方にサブスクライブします。すべてのプロバイダーのバージョンが Dubbo 3 の場合、サービス名がインターフェースレベルのサービス名であるプロバイダーは Nacos インスタンスに登録できません。その結果、コンシューマーがサービス名がインターフェースレベルのサービス名であるプロバイダーにサブスクライブすると、空のリスト保護がトリガーされます。 | 構成 |
Spring Cloud Alibaba アプリケーションで NacosWatch 機能が初めて有効になり、インスタンスレプリカが存在しない場合、コンシューマーは空のインスタンスリストを受信します。 | NacosWatch 機能は、アプリケーションのサービス状態を監視するために、新しいバージョンの Spring Cloud Alibaba アプリケーションで提供されています。 NacosWatch 機能を使用すると、Spring Cloud Alibaba アプリケーションは、アプリケーションの起動時にそのサービスを監視できます。 Spring Cloud Alibaba アプリケーションで NacosWatch 機能が初めて有効になり、インスタンスレプリカが存在しない場合、アプリケーションインスタンスが Nacos インスタンスに登録されていないため、空のリスト保護がトリガーされます。アプリケーションインスタンスが起動した後、空のリスト保護はトリガーされなくなります。 | Spring Cloud Alibaba アプリケーションで NacosWatch 機能が初めて有効になり、インスタンスレプリカが存在しない場合は、この問題を無視してください。 |
Spring Cloud Gateway のサービスが完全に無効になっているシナリオでは、サービスの状態は同期されません。 | Spring Cloud Gateway が起動されると、Spring Cloud Gateway は Nacos インスタンスからすべてのサービスをクエリし、すべてのサービスにサブスクライブします。たとえば、Spring Cloud Gateway が起動された後、Nacos インスタンスがすべてのアプリケーションインスタンスを自動的に削除するため、サービスが完全に無効になります。ただし、Spring Cloud Gateway はサービスの状態を検出せず、サービスのサブスクライブを続けます。その結果、空のリスト保護がトリガーされます。 | Spring Cloud Gateway は、サービスの状態を動的に検出し、サービスが無効になっている場合にサービスのサブスクライブを解除することはできません。 Spring Cloud Gateway を再起動することをお勧めします。 |
空のリスト保護が強制的に有効になるシナリオ
MSE Nacos 2.1.0.2 以降では、空のリスト保護を有効にするロジックが最適化されています。この最適化により、forcePushEmptyProtectionForAllService パラメーターの値に [はい] が選択されている場合にのみ、空のリスト保護が有効になります。ただし、forcePushEmptyProtectionForAllService パラメーターの値に [いいえ] が選択されている場合でも、次のシナリオでは、可用性と安定性を確保するために、システムは引き続き自動的に空のリスト保護を有効にします。
エンジンノードがアップグレード、再起動、または障害から回復した場合、ノードはすべてのアプリケーションに対して 2 分間の空のリスト保護を自動的に有効にして、その期間中のサービスの可用性を確保します。
アプリケーションのすべてのインスタンスが MSE インスタンスのアプリケーションインスタンスリストから削除された場合、MSE インスタンスはアプリケーションに対して 1 分間の空のリスト保護を自動的に有効にします。この操作により、ネットワークパフォーマンスの不安定化やサービスプロバイダーの一時的な障害などの問題が発生した場合に、空のリスト保護が予期せずトリガーされるのを防ぎます。このようにして、このシナリオでサービスの可用性が提供されます。
最高のサービス可用性を確保するために、forcePushEmptyProtectionForAllService パラメーターの値に [はい] を選択して、すべての場合において空のリスト保護を有効にすることをお勧めします。
関連情報
MSE のマイクロサービスレジストリによって提供される高可用性機能を使用して、アプリケーションのリスク処理機能を大幅に向上させることができます。詳細については、MSE マイクロサービスレジストリの高可用性機能の実装 をご参照ください。