Eurekaクライアントサービスの登録プロセスを説明する図とソースコード

一緒に書く習慣をつけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して5日目です。クリックしてイベントの詳細をご覧ください。

Eurekaクライアントサービスの登録プロセス

決意は成功の始まりです

関連記事
図+ソースコードの説明Eurekaサーバー起動プロセス分析
図+ソースコードの説明Eurekaクライアント起動プロセス分析
図+ソースコードの説明Eurekaサーバーレジストリキャッシュロジック
図+ソースコードの説明Eurekaクライアントプルレジストリプロセス

登録コアフローチャート

image.png

分析を開始する場所

クライアントが初期化されると、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);
            }
        }
    }
}
复制代码

まとめ

  1. ハートビートを介して登録を開始します
  2. 現在のインスタンスを登録キューと最近の変更キューに入れます
  3. サーバー側のキャッシュを無効にする

おすすめ

転載: juejin.im/post/7082929115703017486