Nacos 構成センターのソース コード | JD Logistics 技術チーム

クライアント

入り口

構成センターの Maven 依存関係を導入する jar ファイル内で、構成ファイル内の NacosConfigBootstrapConfiguration 構成クラスを見つけます。このクラスは、nacos 構成センターのエントリー・クラスであり、このクラスには 3 つの Bean が登録されています。spring-cloud-starter-alibaba-nacos-config-2.2.5.RELEASE.jar!/META-INF/spring.factories





NacosConfigProperties:プロパティ構成クラス。構成ファイル内の spring.cloud.nacos.config というプレフィックスが付いたプロパティに対応します。

NacosConfigManager: NacosConfigProperties と ConfigService を管理します。

NacosPropertySourceLocator:構成センター構成情報をロードします。

NacosConfigManager

NacosConfigManager コンストラクターでは、createConfigService メソッドが呼び出されます。このメソッドは、ファクトリー クラスを通じて ConfigService 実装クラスのコンストラクターを呼び出し、ConfigService インスタンスを作成します。





ConfigService 実装クラス NacosConfigService のコンストラクタでは、 this.agent = new MetricsHttpAgent(new ServerHttpAgent(properties)); が初期化されます このエージェントは、サーバーにリクエストを送信するために使用されるエージェントです。



 

ServerHttpAgent クラスの NacosRestTemplate 属性は、リモート呼び出しを送信するためのツール クラスであり、HttpMethod.GET メソッドを呼び出してサーバー レスト要求を呼び出します。



NacosConfigService#NacosConfigService に戻るメソッドでは this.worker = new ClientWorker(this.agent, this.configFilterChainManager,properties); このプロパティはクライアント ワーカー スレッド クラスであり、クラス内には 2 つのスレッド プールがあります。

1. スレッドが 1 つだけあるスレッド プールは、スケジュールされたタスクの実行に使用されます。checkConfigInfo(); メソッドは 10 ミリ秒ごとに実行されます。ポーリングされるキャッシュデータ インスタンスは、3000 個の構成アイテムのバッチごとに取得され、LongPollingTask 送信にパッケージ化されます。処理のために 2 番目のスレッド プール executorService を入力します。this.executor = Executors.newScheduledThreadPool(1, new ThreadFactory()





2.プロセッサ数と同じスレッド数のスレッド プールを使用して、ClientWorker.LongPollingRunnable#LongPollingRunnable#run を実行します。更新する必要がある構成は、cacheMap にキャッシュされます。cacheMap 内の数をグループに分割します。構成の更新、LongPollingRunnable#run メソッドで checkLocalConfig(cacheData) を呼び出します; ローカル構成とフォールト トレラント処理を確認します; checkUpdateDataIds(cacheDatas, inInitializingCacheList) を呼び出します; このメソッドは、長い接続を送信することですnacos サーバーに 30 秒間のタイムアウト イベントを送信し、更新された dataid を返す getServerConfig(dataId, group, tenant, 3000L); このメソッドは、サーバー構成センター インターフェイスを呼び出して、返された dataid に基づいて構成属性を取得し、ローカルスナップショット; checkListenerMd5() を呼び出して、変更された構成を追加します 監視処理; 最後に executorService.execute(this); メソッドのポーリング処理を呼び出し続けます。







キャッシュデータ#checkListenerMd5





listener.receiveConfigInfo(contentTmp); メソッドで、AbstractSharedListener#receiveConfigInfo メソッドが呼び出され、RefreshEvent イベントが発行されます。





対応するイベント リスナーは: Spring Cloud によって実装された RefreshEventListener です。このリスナーでは、構成が更新され、@RefreshScope でマークされた構成がコンテナー内で更新されます。onApplicationEvent メソッド、ApplicationReadyEvent (スプリング ブート イベント、アプリケーションが初期化を完了する必要があることを示します)、RefreshEvent。





RefreshEvent: this.handle((RefreshEvent)event); このイベントを処理して、コンテナ org.springframework.cloud.context.refresh.ContextRefresher#refresh 内の @RefreshScope アノテーションでマークされた構成をリフレッシュします





freshEnvironment(); extract(this.context.getEnvironment().getPropertySources()) システム変数以外の変数を抽出します; addConfigFilesToEnvironment(); 元の環境のパラメータを新しい Spring コンテキスト コンテナに入れ、再ロードして閉じます完了後の新しいコンテナ。パラメータの新しい値は次のとおりです。





changes(before,extract(this.context.getEnvironment().getPropertySources())) 新しいパラメーター値を取得し、それを以前のパラメーター値と比較して、変更されたパラメーター値を見つけます。



this.context.publishEvent(newEnvironmentChangeEvent(this.context,keys)); 変更されたパラメーター値を使用して環境変更イベントを発行します。

ContextRefresher#refresh メソッドに戻り、this.scope.refreshAll(); を確認して、@RefreshScope アノテーションが付けられた Bean を更新します。





super.destroy(); メソッドを使用してスコープ内のキャッシュをクリアすると、次回 BeanFactory から新しいインスタンスが取得され、新しい設定が使用されます。

this.context.publishEvent(new RefreshScopeRefreshedEvent()); メソッドはイベントを公開します。

サーバ

ダンプサービス

DumpService クラスは、ストレージから構成をクエリしてディスクに保存する抽象クラスで、EmbeddedDumpService 組み込みストレージ (DERBY) と ExternalDumpService 拡張データ ストレージの 2 つのサブクラスがあります。



@PostConstruct アノテーションは、InitialDumpService 実装クラスの init メソッド上にあり、Spring による Bean の構築プロセス中に、@PostConstruct を使用した初期化メソッドが実行されます。

抽象親クラス DumpService#dumpOperate のメソッドを呼び出し、dumpConfigInfo メソッドを呼び出します。dumpConfigInfo メソッドは、完全に更新するか追加で更新するかを決定します。



isAllDumpがtrueの場合、フルアップデートを実行します クイックアップデート設定の有無、ハートビートチェックファイルの有無、最終チェック時間が6時間未満かどうかを判定します 上記判定を満たした場合の場合、完全な更新は実行されません。それ以外の場合、完全な更新が実行されます。



dumpAllProcessor.process(new DumpAllTask​​()); データベース内のすべての configInfo 構成情報をクエリし、それをサーバー側のディスク キャッシュに書き込みます。



persistService.findConfigMaxId(); ページング処理のためにデータベース内の最大の主キーをクエリします。



persistService.findAllConfigInfoFragment(lastMaxId, PAGE_SIZE); 1000 項目をクエリするたびに、ページ単位でデータベースのデータをクエリします。





ConfigCacheService.dump(cf.getDataId(), cf.getGroup(), cf.getTenant(), cf.getContent(), cf.getLastModified(),cf.getType()); ディスクへの書き込み



ファイルに保存する



updateMd5(groupKey, md5, lastModifiedTs); 構成情報の MD5 をメモリにキャッシュし、LocalDataChangeEvent イベントを発行します。



イベント リスナーは NotifyCenter.registerSubscriber で呼び出されます。



構成の取得

HttpMethod.GET /nacos/v1/cs/configs サーバー構成インターフェース ConfigController#getConfig を取得します。



inner.doGetConfig(request,response,dataId,group,tenant,tag,clientIp); は getConfig で呼び出されます。

doGetConfig メソッドでは、DiskUtil.targetBetaFile(dataId, group, tenant); メソッドが呼び出され、mysql からではなく、ローカル ディスクからデータを取得します。mysql データが直接変更された場合、変更は有効になりません。更新をトリガーするには公開する必要があります。



リスニング設定

HttpMethod.POST リクエストは、/nacos/v1/cs/configs/listener ポーリング インターフェイスを呼び出して、長い接続を呼び出します。



longPollingService.addLongPollingClient(request,response,clientMd5Map,probeRequestSize); 長時間接続のポーリング処理。



SwitchService.getSwitchInteger(SwitchService.FIXED_DELAY_TIME, 500); 最大処理時間は 29.5 秒です。タイムアウトを避けるために、クライアントへの応答に 0.5 秒を予約する必要があります。



MD5Util.compareMd5(req, rsp, clientMd5Map); クライアントの md5 が現在のサーバーの md5 と一致するかどうかを比較します。不一致は、changedGroups に返されます。



一貫性のないデータがある場合は、generateResponse(req, rsp,ChangedGroups); に直接応答します。



スレッド プールは、長時間接続タスク ConfigExecutor.executeLongPolling を実行します。



LongPollingService.ClientLongPolling#ロングポーリングを実行します。



ConfigExecutor.scheduleLongPolling により実行が 29.5 秒遅延する



遅延実行では、まずキュー内の独自のタスクが削除されます。



allSubs.add(this); キューに追加



inner.doPollingConfig(リクエスト、レスポンス、clientMd5Map、probeModify.length());



MD5Util.compareMd5(request, response, clientMd5Map); 現在の構成と比較し、変更された構成を返します

nacos管理側の設定変更

HttpMethod.POST /nacos/v1/cs/configs



persistService.insertOrUpdate(srcIp, srcUser, configInfo, time, configAdvanceInfo, true); データベースへの永続情報。









ConfigController#publishConfig に戻り、ConfigDataChangeEvent イベントをトリガーする ConfigChangePublisher.notifyConfigChange メソッドを確認します。





ConfigDataChangeEvent イベント リスナー。



ConfigExecutor.executeAsyncNotify(new AsyncTask(nacosAsyncRestTemplate, queue)); 他のノードを同期します。



さらに、LongPollingService は初期化時に LocalDataChangeEvent イベントをサブスクライブし、それもリッスンします。



ConfigExecutor.executeLongPolling(new DataChangeTask(evt.groupKey, evt.isBeta, evt.betaIps));

LongPollingService.DataChangeTask#run、プッシュ モードを確認し、allSubs を走査し、変更されたキーでクライアントに応答します。clientSub.sendResponse(Arrays.asList(groupKey));

 

著者: JD Logistics Zhang Shixin

出典:JD Cloud Developer Community Ziyuanqishuo Tech 転載の際は出典を明記してください

IntelliJ IDEA 2023.3 と JetBrains Family Bucket の年次メジャー バージョン アップデート 新しいコンセプト「防御型プログラミング」: 安定した仕事に就く GitHub.com では 1,200 を超える MySQL ホストが稼働していますが、8.0 にシームレスにアップグレードするにはどうすればよいですか? Stephen Chow の Web3 チームは来月、独立したアプリをリリースする予定ですが、 Firefox は廃止されるのでしょうか? Visual Studio Code 1.85 リリース、フローティング ウィンドウ Yu Chengdong: ファーウェイは来年破壊的な製品を発売し、業界の歴史を書き換えるだろう 米国 CISA はメモリ セキュリティの脆弱性を排除するために C/C++ の廃止を勧告 TIOBE 12 月: C# がプログラミングになると予想30年前 雷軍が書いた論文「コンピュータウイルス判定エキスパートシステムの原理と設計」
{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/u/4090830/blog/10320447