一緒に書く習慣をつけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して5日目です。クリックしてイベントの詳細をご覧ください。
Eurekaクライアントサービスの登録プロセス
決意は成功の始まりです
関連記事
図+ソースコードの説明Eurekaサーバー起動プロセス分析
図+ソースコードの説明Eurekaクライアント起動プロセス分析
図+ソースコードの説明Eurekaサーバーレジストリキャッシュロジック
図+ソースコードの説明Eurekaクライアントプルレジストリプロセス
登録コアフローチャート
分析を開始する場所
クライアントが初期化されると、clientConfig.shouldEnforceRegistrationAtInit()初期化時に必須登録を有効にするかどうか、この値はデフォルトでfalseであるため、登録されません。後続の30秒のハートビートメカニズムタスクの送信でrenew()メソッドに登録されます。 。
if (clientConfig.shouldRegisterWithEureka() &&
// clientConfig.shouldEnforceRegistrationAtInit() 默认是false
clientConfig.shouldEnforceRegistrationAtInit()) {
if (!register()) {
throw new IllegalStateException("Registration error at startup. Invalid server response.");
}
}
复制代码
コアロジック
ハートビートがrenew()を介して送信されると、インスタンス情報が見つからないことが返されるため、登録操作が再度実行され、ハートビート要求操作がeurekaTransport.registrationClientクライアントを介して実行されます。
1.ハートビートタイミングタスクを介して登録を開始します
boolean renew() {
EurekaHttpResponse<InstanceInfo> httpResponse;
httpResponse = eurekaTransport.registrationClient.
sendHeartBeat(instanceInfo.getAppName(),
instanceInfo.getId(), instanceInfo, null);
if (httpResponse.getStatusCode() == Status.NOT_FOUND.getStatusCode()) {
REREGISTER_COUNTER.increment();
long timestamp = instanceInfo.setIsDirtyWithTime();
boolean success = register(); // 注册实例
if (success) {
instanceInfo.unsetIsDirty(timestamp);
}
return success;
}
return httpResponse.getStatusCode() == Status.OK.getStatusCode();
}
复制代码
インスタンスの登録はregister()メソッドを介して実行され、登録メソッドのアクセスはeurekaTransport.registrationClientを介して実行されます。このeurekaTransport.registrationClientは、AbstractJersey2EurekaHttpClientの登録メソッドにアクセスします。
boolean register() throws Throwable {
EurekaHttpResponse<Void> httpResponse;
httpResponse = eurekaTransport.registrationClient.register(instanceInfo);
....
}
复制代码
eureka-coreプロジェクトのAbstractInstanceRegistryのregisterメソッドには、jersey2フレームワークを介してアクセスします。
public void register(InstanceInfo registrant, int leaseDuration,
boolean isReplication) {
/**
* 通过服务名字从本地的 gMap 中获取一个服务实例信息
*/
Map<String, Lease<InstanceInfo>> gMap = registry.get(registrant.getAppName());
if (gMap == null) {
// 如果本地gMap中没有当前要注册的实例的话创建一个 gNewMap
// 也就是 registry 中的一个服务实例
final ConcurrentHashMap<String, Lease<InstanceInfo>> gNewMap =
new ConcurrentHashMap<String, Lease<InstanceInfo>>();
// 将当前服务名字为key并且服务名字,value就是当前要注册的 gNewMap
gMap = registry.putIfAbsent(registrant.getAppName(), gNewMap);
if (gMap == null) {
gMap = gNewMap;
}
}
// 说白了上面就是创建了一个gMap中的一个实例
gMap.put(registrant.getId(), lease);
}
复制代码
2.現在のインスタンスをキューに入れます
この登録キューと変更キューは、サービスの初期化時に作成されます。最近変更された状態は、この最近変更されたキューで監視できます。新しく登録されたキューとオフラインキューは、主にページに表示されます。最近変更されたキューが使用されます。インクリメンタル登録インスタンス情報を取得する場合。
/**
* 将当前实例放入到最近注册的队列
*/
recentRegisteredQueue.add(new Pair<Long, String>(System.currentTimeMillis(),
registrant.getAppName() + "(" + registrant.getId() + ")"));
// 设置类型为添加类型
registrant.setActionType(ActionType.ADDED);
/**
* 添加也属于改变所以创建一个最近的改变对象【RecentlyChangedItem】放入到最近的改变队列中,
* 时间戳是当前的系统时间
*/
recentlyChangedQueue.add(new RecentlyChangedItem(lease));
复制代码
3.ローカルキャッシュを無効にします
/**
* 当有新实例过来的时候无效当前读写缓存
*/
invalidateCache(registrant.getAppName(), registrant.getVIPAddress(),
registrant.getSecureVipAddress());
复制代码
ローカルキャッシュ操作を無効にするには、ResponseCacheImplのinvalidateメソッドを使用してキャッシュ内の一部のキーをキャッシュから削除し、読み取り/書き込みキャッシュ内のキー値を削除します。
public void invalidate(Key... keys) {
for (Key key : keys) {
// 移除读写缓存中的key
readWriteCacheMap.invalidate(key);
Collection<Key> keysWithRegions = regionSpecificKeys.get(key);
if (null != keysWithRegions && !keysWithRegions.isEmpty()) {
for (Key keysWithRegion : keysWithRegions) {
readWriteCacheMap.invalidate(keysWithRegion);
}
}
}
}
复制代码
まとめ
- ハートビートを介して登録を開始します
- 現在のインスタンスを登録キューと最近の変更キューに入れます
- サーバー側のキャッシュを無効にする