1. 程式人生 > >springboot eureka 註冊服務探索

springboot eureka 註冊服務探索

執行時日誌
2018-03-09 13:16:42.132  INFO 13652 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms
2018-03-09 13:17:42.141  INFO 13652 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 7ms
2018
-03-09 13:18:42.147 INFO 13652 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : Running the evict task with compensationTime 5ms 2018-03-09 13:19:42.155 INFO 13652 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : Running the evict task with compensationTime 6ms 2018-03-09 13
:20:03.562 INFO 13652 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration 2018-03-09 13:20:42.159 INFO 13652 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : Running the evict task with compensationTime 2ms 2018-03-09 13:21:42.160 INFO 13652
--- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : Running the evict task with compensationTime 0ms 2018-03-09 13:22:42.163 INFO 13652 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : Running the evict task with compensationTime 1ms 2018-03-09 13:23:42.165 INFO 13652 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : Running the evict task with compensationTime 0ms 2018-03-09 13:24:42.165 INFO 13652 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : Running the evict task with compensationTime 0ms 2018-03-09 13:25:03.584 INFO 13652 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration 註冊服務日誌 2018-03-09 13:25:42.169 INFO 13652 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : Running the evict task with compensationTime 2ms 2018-03-09 13:26:37.169 INFO 13652 --- [ XNIO-2 task-32] c.n.e.registry.AbstractInstanceRegistry : Registered instance EES-HOTEL/16101164-15-PC:ees-hotel:8119 with status UP (replication=[true/false]) 2018-03-09 13:26:42.169 INFO 13652 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry : Running the evict task with compensationTime 0ms PATH: AbstractInstanceRegistry : com.netflix.eureka:eureka-core 1.6.2
#跟程式碼
com.netflix.eureka.registry.AbstractInstanceRegistry.register(InstanceInfo registrant, int leaseDuration, boolean isReplication)//註冊資訊,註冊資訊持續時間 預設120,是否複製
1.加同步鎖讀取鎖
2.在該類的常量registry(ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>>)根據取服務名(spring:  application:  name: eureka )獲取所有註冊機( rtn:Map<String, Lease<InstanceInfo>> gMap)
3.=====(監聽)EurekaMonitors.REGISTER.increment(isReplication);  監聽註冊服務的個數,增加服務計數(EurekaMonitors的myZoneCounter屬性),isReplication為falses時才進行計數增長。//主要是對 AtomicLong[extends Number implements java.io.Serializable]內的unsafe常量
4.判斷2是否獲取到有效eureka服務,若沒有則
if (gMap == null) {
    ConcurrentHashMap<String, Lease<InstanceInfo>> gNewMap = new ConcurrentHashMap();
    gMap = (Map)this.registry.putIfAbsent(registrant.getAppName(), gNewMap);
    if (gMap == null) {
        gMap = gNewMap;
    }
}
5.獲取existingLease(生存週期)資訊,從2返回的map內,根據註冊資訊(instanceId[16101164-15-PC:eureka:8001]或eureka.instance.hostName[eureka1]),Lease<InstanceInfo> existingLease = (Lease)((Map)gMap).get(registrant.getId());
if (existingLease != null && existingLease.getHolder() != null) {
    Long existingLastDirtyTimestamp = ((InstanceInfo)existingLease.getHolder()).getLastDirtyTimestamp();
    Long registrationLastDirtyTimestamp = registrant.getLastDirtyTimestamp();
    logger.debug("Existing lease found (existing={}, provided={}", existingLastDirtyTimestamp, registrationLastDirtyTimestamp);
    if (existingLastDirtyTimestamp > registrationLastDirtyTimestamp) {
        logger.warn("There is an existing lease and the existing lease's dirty timestamp {} is greater than the one that is being registered {}", existingLastDirtyTimestamp, registrationLastDirtyTimestamp);
        logger.warn("Using the existing instanceInfo instead of the new instanceInfo as the registrant");
        registrant = (InstanceInfo)existingLease.getHolder();
    }
} else {
    Object var6 = this.lock;
    synchronized(this.lock) {
        if (this.expectedNumberOfRenewsPerMin > 0) {
            this.expectedNumberOfRenewsPerMin += 2;
            this.numberOfRenewsPerMinThreshold = (int)((double)this.expectedNumberOfRenewsPerMin * this.serverConfig.getRenewalPercentThreshold());
        }
    }

    logger.debug("No previous lease information found; it is new registration");
}
Lease<InstanceInfo> lease = new Lease(registrant, leaseDuration);
if (existingLease != null) {
        lease.setServiceUpTimestamp(existingLease.getServiceUpTimestamp());
}
6.獲取最近註冊佇列recentRegisteredQueue【AbstractInstanceRegistry.CircularQueue<Pair<Long, String>>】,
對佇列加鎖,將待註冊的服務資訊註冊(當前系統時間戳 ,當前待註冊服務名eg:ees-hotel + id(instanceId/hostName)),
synchronized(this.recentRegisteredQueue) {
    this.recentRegisteredQueue.add(new Pair(System.currentTimeMillis(), registrant.getAppName() + "(" + registrant.getId() + ")"));
}

7.註冊資訊的overriddenStatus狀態不是InstanceStatus.UNKNOWN時,將當前服務註冊資訊內的此狀態維護到overriddenInstanceStatusMap,key為id.
8.將overriddenInstanceStatusMap內的OverriddenStatus同步到註冊資訊registrant內,當overriddenStatusFromMap記憶體在此狀態時。
9.當註冊資訊registrant的狀態為InstanceStatus.UP時,更新lease的存活【租約】時間,服務開始時間為當前時間戳。
10.註冊資訊的actionType設定為在發現服務中新增,將當前註冊的服務新增到服務發現內。
11.將新註冊(更改)的服務資訊(lease)新增到最近更改佇列(recentlyChangedQueue)
12.設定新註冊的服務的最後更新時間
13.this.invalidateCache(registrant.getAppName(), registrant.getVIPAddress(), registrant.getSecureVipAddress());  使快取無效
快取使用的是Google的private final LoadingCache<Key, ResponseCacheImpl.Value> readWriteCacheMap; 該介面繼承Cache,存在invalidate抽象方法,實際呼叫LocalCache.LocalManualCache.invalidate,如下
public void invalidate(Object key) {
    Preconditions.checkNotNull(key);
    this.localCache.remove(key);
}
其中使用Preconditions的checkNotNull做非空校驗
最後在final LocalCache<K, V> localCache;內刪除快取的資訊。
LoadingCache extends Cache,Function 
LocalCache implements Cache
LocalManualCache implements Cache
Manual內操作

此處刪除快取是迴圈操作,在初次啟動時會刪除
this.invalidate(new Key(EntityType.Application, appName, type, v, EurekaAccept.full), new Key(EntityType.Application, appName, type, v, EurekaAccept.compact), new Key(EntityType.Application, "ALL_APPS", type, v, EurekaAccept.full), new Key(EntityType.Application, "ALL_APPS", type, v, EurekaAccept.compact), new Key(EntityType.Application, "ALL_APPS_DELTA", type, v, EurekaAccept.full), new Key(EntityType.Application, "ALL_APPS_DELTA", type, v, EurekaAccept.compact));

ResponseCacheImpl構造方法會初始化readWriteCacheMap,initialCapacity=1000
this.readWriteCacheMap = CacheBuilder.newBuilder().initialCapacity(1000).expireAfterWrite(serverConfig.getResponseCacheAutoExpirationInSeconds(), TimeUnit.SECONDS).removalListener(new RemovalListener<Key, ResponseCacheImpl.Value>() {
    public void onRemoval(RemovalNotification<Key, ResponseCacheImpl.Value> notification) {
        Key removedKey = (Key)notification.getKey();
        if (removedKey.hasRegions()) {
            Key cloneWithNoRegions = removedKey.cloneWithoutRegions();
            ResponseCacheImpl.this.regionSpecificKeys.remove(cloneWithNoRegions, removedKey);
        }

    }
}).build(new CacheLoader<Key, ResponseCacheImpl.Value>() {
    public ResponseCacheImpl.Value load(Key key) throws Exception {
        if (key.hasRegions()) {
            Key cloneWithNoRegions = key.cloneWithoutRegions();
            ResponseCacheImpl.this.regionSpecificKeys.put(cloneWithNoRegions, key);
        }

        ResponseCacheImpl.Value value = ResponseCacheImpl.this.generatePayload(key);
        return value;
    }
});

未完待續