1.クライアントリクエストの処理
InstanceControllerを検索します
@RequestMapping(UtilsAndCommons.NACOS_NAMING_CONTEXT + "/instance")
このアドレスは、カスタマーサービス登録サービスのアドレスです。カスタマーサービスサービスの登録プロセスは、このブログ投稿[SpringCloud]Nacosサービス登録プロセスのソースコード_AutumnSunsetブログ-CSDNブログで確認できます。
コントローラ方式を参照
最初にnamespaceIdとserviceNameを取得してください
デフォルトの名前空間:public
グループ:DEFAULT_GROUP@@+クライアントによって登録されたサービス名
解析インスタンスオブジェクトは、サービスプロバイダーのパラメーターをカプセル化します
次に、サービスを登録し、registerInstanceメソッドを呼び出します
serviceManager.registerInstance(namespaceId, serviceName, instance);
ファローアップ
com.alibaba.nacos.naming.core.ServiceManager。registerInstance
2.インスタンスを登録します
com.alibaba.nacos.naming.core.ServiceManager。registerInstance
最初にcreateEmptyServiceを呼び出して、レジストリに空のサービス構造を作成します
createServiceIfAbsentメソッドのフォローアップ
初めてサービスにアクセスするときservice=getService(namespaceId、serviceName)はnullである必要があります
ifロジックを入力します
変更時刻を記録するためのサービス名、名前空間、グループ名を設定するための新しいサービスオブジェクトを作成しました
putServiceAndInit(service)に来てください
ファローアップ
`serviceMap二重層マップ
putServiceを実行した後、serviceMapのデータを確認します
外側のマップのキーは名前空間の値であり、マップでもあります。内側のマップのキーはgroupNameであり、グループ名の値はサービスオブジェクトです。
3.サービスインスタンスのハートビートチェック
putServiceAndInitメソッドに戻る
次に、service.init()メソッドを実行します
com.alibaba.nacos.naming.core.Service.initメソッドにアクセスしてください
最初の5秒後にスケジュールされたタスクを実行し、その後5秒ごとに実行して、スレッドタスクが実行されたときのフォローアップタスクを確認します。
スレッドタスク
com.alibaba.nacos.naming.healthcheck.ClientBeatCheckTask.run()
`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にフォローアップします
まず、インスタンスキー値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);
ConsistencyService.put(key、instances)メソッドに来てください
来到com.alibaba.nacos.naming.consistency.ephemeral.distro.DistroConsistencyServiceImpl.put
`レコード値は、インスタンスをカプセル化するインスタンスの実施形態ですインスタンスインスタンスインスタンスはレコードポリモーフィズムを継承します
onPutメソッドのフォローアップ
com.alibaba.nacos.naming.consistency.ephemeral.distro.DistroConsistencyServiceImpl.onPutメソッドにアクセスしてください
もう1つの新しいデータムオブジェクト。データム値はインスタンスキーです。これは以前に生成されたインスタンスキーです。
次に、データストアをデータストアのマップにスローします
最後に、notifier.addTaskメソッドを呼び出して、addTaskメソッドをフォローアップします
キーをサービスに配置するのはdatumKey値は空の文字列です
private ConcurrentHashMap<String, String> services = new ConcurrentHashMap<>(10 * 1024)
最後に、呼び出しtask.offer
はキーと実行されたアクションをメモリキューにスローし、nullを返します。メソッドは終了しました。
ここの難しさはありますか?
5.キューをリッスンし、新しいサービスインスタンスを取り出します
このタスクが属するクラスを見てみましょう
`Notifierはスレッドタスククラスでもあるので、そのスレッドタスクを見てみましょう
キューからdatumKeyを取得し、handleメソッドを呼び出します
ブレークポイントに到達し、実行フローを確認して、サービスを再登録します
listener.onChangeに来てください
onChangeメソッドの2つのパラメーターの1つはdatumKeyで、もう1つはインスタンスです。
サービスインスタンスコレクションがdatumKeyを介してデータストアから取り出されていることがわかります。
com.alibaba.nacos.naming.core.Service.onChangeメソッドをフォローアップします
すべてのインスタンスインスタンスをトラバースして、適切な重みを設定します
次に、updateIPsメソッドを呼び出してフォローアップします
私は新しいipMapとたくさんの地図を思いついた
すべてのインスタンスを反復処理します
clusterIPに追加
トラバーサルのために次へ
clusterMap.get(entry.getKey())。updateIps(entryIPs、ephemeral)を呼び出してクラスターを取得し、updateIpsメソッドを呼び出します
com.alibaba.nacos.naming.core.Cluster.updateIpsにアクセスしてください
6.コピーオンライト、新しいサービスインスタンスをレジストリに登録します
ephemeral前のメソッドで渡されたパラメーターがtrueの場合、ephemeralInstancesの値をSettoUpdateInstancesに割り当てます
Set<Instance> toUpdateInstances = ephemeral ? ephemeralInstances : persistentInstances;
では、このephemeralInstancesとは何ですか?
これは、クラスターストレージサービスインスタンスの古いセットです。
private Set<Instance> ephemeralInstances = new HashSet<>();
古いインスタンスセットをtoUpdateInstancesに割り当てます次のステップは、新しく登録されたサービスインスタンスを操作し、最後にすべての最新インスタンスをtoUpdateInstancesに割り当てます。
次に、toUpdateInstancesの値をephemeralInstancesに割り当てます。この時点で、新しいサービスインスタンスが登録されます。
これは、コピーオンライトのアイデアであり、登録されたサービスインスタンスをコピーし、コピーされたデータを操作し、操作の完了後に元の古いデータをコピーされたデータに置き換えます。
目的は、同時実行の競合を解決することです。書き込みプロセス中に、他のスレッドが古いデータを読み取り、実際の書き込みが完了した後にデータを更新し直します。ダーティデータは読み取られません。読み取られたすべてのサービスインスタンスが使用可能であることを確認してください