【春のクラウド】Nacosレジストリサーバー登録サービスプロセスのソースコード

1.クライアントリクエストの処理

InstanceControllerを検索します

@RequestMapping(UtilsAndCommons.NACOS_NAMING_CONTEXT + "/instance")

画像-20220403201854097

画像-20220403225439877

このアドレスは、カスタマーサービス登録サービスのアドレスです。カスタマーサービスサービスの登録プロセスは、このブログ投稿[SpringCloud]Nacosサービス登録プロセスのソースコード_AutumnSunsetブログ-CSDNブログで確認できます。

画像-20220403202018706

コントローラ方式を参照

画像-20220403202126755

最初にnamespaceIdとserviceNameを取得してください

画像-20220403211359081

デフォルトの名前空間:public

グループ:DEFAULT_GROUP@@+クライアントによって登録されたサービス名

解析インスタンスオブジェクトは、サービスプロバイダーのパラメーターをカプセル化します

画像-20220403211543798

次に、サービスを登録し、registerInstanceメソッドを呼び出します

serviceManager.registerInstance(namespaceId, serviceName, instance);

ファローアップ

com.alibaba.nacos.naming.core.ServiceManager。registerInstance

2.インスタンスを登録します

com.alibaba.nacos.naming.core.ServiceManager。registerInstance

画像-20220403211736900

最初にcreateEmptyServiceを呼び出して、レジストリに空のサービス構造を作成します

createServiceIfAbsentメソッドのフォローアップ

画像-20220403211850798

初めてサービスにアクセスするときservice=getService(namespaceId、serviceName)はnullである必要があります

ifロジックを入力します

変更時刻を記録するためのサービス名、名前空間、グループ名を設定するための新しいサービスオブジェクトを作成しました

画像-20220403212012868

putServiceAndInit(service)に来てください

画像-20220403212208988

ファローアップ

画像-20220403212312468

`serviceMap二重層マップ

画像-20220403212330991

putServiceを実行した後、serviceMapのデータを確認します

画像-20220403212509535

外側のマップのキーは名前空間の値であり、マップでもあります。内側のマップのキーはgroupNameであり、グループ名の値はサービスオブジェクトです。

画像-20220403213220448

3.サービスインスタンスのハートビートチェック

putServiceAndInitメソッドに戻る

次に、service.init()メソッドを実行します

画像-20220403213346275

com.alibaba.nacos.naming.core.Service.initメソッドにアクセスしてください

画像-20220403213427424

最初の5秒後にスケジュールされたタスクを実行し、その後5秒ごとに実行して、スレッドタスクが実行されたときのフォローアップタスクを確認します。

画像-20220403213506026

スレッドタスク

com.alibaba.nacos.naming.healthcheck.ClientBeatCheckTask.run()

画像-20220403214111904

`instance.getInstanceHeartBeatTimeOut()の値は15秒です

現在の時刻からインスタンスの最後のハートビート時刻を引いた値が15秒を超える場合は、if判定を入力し、ヘルスステータスをfalseに設定します。

つまり、HealthCheckReactor.scheduleCheck(clientBeatCheckTask)を使用すると、ハートビートですべてのインスタンスのヘルスステータスを検出できます。最後のハートビート検出からの時間が15秒を超えると、ヘルスステータスはfalseに設定されます。

4.キューにメッセージを送信します

registerInstanceメソッドに戻る

addInstance(namespaceId、serviceName、instance.isEphemeral()、instance)を引き続き確認します

com.alibaba.nacos.naming.core.ServiceManager.addInstanceにフォローアップします

画像-20220403215331621

まず、インスタンスキー値com.alibaba.nacos.naming.iplist.ephemeral.public ## DEFAULT_GROUP@@nacos-testを生成します

String key = KeyBuilder.buildInstanceListKey(namespaceId, serviceName, ephemeral);

インスタンスのコレクションを生成する

List<Instance> instanceList = addIpAddresses(service, ephemeral, ips)

新しいインスタンスはコレクションデータをカプセル化します

Instances instances = new Instances();
            instances.setInstanceList(instanceList);

画像-20220403215727082

ConsistencyService.put(key、instances)メソッドに来てください

来到com.alibaba.nacos.naming.consistency.ephemeral.distro.DistroConsistencyServiceImpl.put

画像-20220403215853870

`レコード値は、インスタンスをカプセル化するインスタンスの実施形態ですインスタンスインスタンスインスタンスはレコードポリモーフィズムを継承します

画像-20220403215936351

onPutメソッドのフォローアップ

com.alibaba.nacos.naming.consistency.ephemeral.distro.DistroConsistencyServiceImpl.onPutメソッドにアクセスしてください

画像-20220403220259020

もう1つの新しいデータムオブジェクト。データム値はインスタンスキーです。これは以前に生成されたインスタンスキーです。

画像-20220403220335697

次に、データストアをデータストアのマップにスローします

画像-20220403220530440

最後に、notifier.addTaskメソッドを呼び出して、addTaskメソッドをフォローアップします

画像-20220403220713239

キーをサービスに配置するのはdatumKey値は空の文字列です

private ConcurrentHashMap<String, String> services = new ConcurrentHashMap<>(10 * 1024)

最後に、呼び出しtask.offerはキーと実行されたアクションをメモリキューにスローし、nullを返します。メソッドは終了しました。

ここの難しさはありますか?

5.キューをリッスンし、新しいサービスインスタンスを取り出します

このタスクが属するクラスを見てみましょう

画像-20220403221239669

`Notifierはスレッドタスククラスでもあるので、そのスレッドタスクを見てみましょう

画像-20220403221332029

キューからdatumKeyを取得し、handleメソッドを呼び出します

画像-20220403221711873

ブレークポイントに到達し、実行フローを確認して、サービスを再登録します

listener.onChangeに来てください

画像-20220403221823581

onChangeメソッドの2つのパラメーターの1つはdatumKeyで、もう1つはインスタンスです。

サービスインスタンスコレクションがdatumKeyを介してデータストアから取り出されていることがわかります。

com.alibaba.nacos.naming.core.Service.onChangeメソッドをフォローアップします

すべてのインスタンスインスタンスをトラバースして、適切な重みを設定します

画像-20220403221940620

次に、updateIPsメソッドを呼び出してフォローアップします

私は新しいipMapとたくさんの地図を思いついた

画像-20220403222121424

すべてのインスタンスを反復処理します

画像-20220403222745703

clusterIPに追加

トラバーサルのために次へ

画像-20220403222856196

clusterMap.get(entry.getKey())。updateIps(entryIPs、ephemeral)を呼び出してクラスターを取得し、updateIpsメソッドを呼び出します

com.alibaba.nacos.naming.core.Cluster.updateIpsにアクセスしてください

6.コピーオンライト、新しいサービスインスタンスをレジストリに登録します

画像-20220403223050216

ephemeral前のメソッドで渡されたパラメーターがtrueの場合、ephemeralInstancesの値をSettoUpdateInstancesに割り当てます

Set<Instance> toUpdateInstances = ephemeral ? ephemeralInstances : persistentInstances;

では、このephemeralInstancesとは何ですか?

これは、クラスターストレージサービスインスタンスの古いセットです。

private Set<Instance> ephemeralInstances = new HashSet<>();

古いインスタンスセットをtoUpdateInstancesに割り当てます次のステップは、新しく登録されたサービスインスタンスを操作し、最後にすべての最新インスタンスをtoUpdateInstancesに割り当てます。

次に、toUpdateInstancesの値をephemeralInstancesに割り当てます。この時点で、新しいサービスインスタンスが登録されます。

画像-20220403223554758

これは、コピーオンライトのアイデアであり、登録されたサービスインスタンスをコピーし、コピーされたデータを操作し、操作の完了後に元の古いデータをコピーされたデータに置き換えます。

目的は、同時実行の競合を解決することです。書き込みプロセス中に、他のスレッドが古いデータを読み取り、実際の書き込みが完了した後にデータを更新し直します。ダーティデータは読み取られません。読み取られたすべてのサービスインスタンスが使用可能であることを確認してください

おすすめ

転載: blog.csdn.net/JAVAlife2021/article/details/123946613