compute a compensation time defined as the actual time this task was executed since the prev iteration, vs the configured amount of time for execution. This is useful for cases where changes in time (due to clock skew or gc for example) causes the actual eviction task to execute later than the desired time according to the configured cycle.
1: publicvoidevict(long additionalLeaseMs){
2: logger.debug("Running the evict task");
3:
4: if (!isLeaseExpirationEnabled()) {
5: logger.debug("DS: lease expiration is currently disabled.");
6: return;
7: }
8:
9: // 獲得 所有過期的租約10: // We collect first all expired items, to evict them in random order. For large eviction sets,11: // if we do not that, we might wipe out whole apps before self preservation kicks in. By randomizing it,12: // the impact should be evenly distributed across all applications.13: List<Lease<InstanceInfo>> expiredLeases = new ArrayList<>();
14: for (Entry<String, Map<String, Lease<InstanceInfo>>> groupEntry : registry.entrySet()) {
15: Map<String, Lease<InstanceInfo>> leaseMap = groupEntry.getValue();
16: if (leaseMap != null) {
17: for (Entry<String, Lease<InstanceInfo>> leaseEntry : leaseMap.entrySet()) {
18: Lease<InstanceInfo> lease = leaseEntry.getValue();
19: if (lease.isExpired(additionalLeaseMs) && lease.getHolder() != null) { // 過期20: expiredLeases.add(lease);
21: }
22: }
23: }
24: }
25:
26: // 計算 最大允許清理租約數量27: // To compensate for GC pauses or drifting local time, we need to use current registry size as a base for28: // triggering self-preservation. Without that we would wipe out full registry.29: int registrySize = (int) getLocalRegistrySize();
30: int registrySizeThreshold = (int) (registrySize * serverConfig.getRenewalPercentThreshold());
31: int evictionLimit = registrySize - registrySizeThreshold;
32:
33: // 計算 清理租約數量34: int toEvict = Math.min(expiredLeases.size(), evictionLimit);
35: if (toEvict > 0) {
36: logger.info("Evicting {} items (expired={}, evictionLimit={})", toEvict, expiredLeases.size(), evictionLimit);
37:
38: // 逐個過期39: Random random = new Random(System.currentTimeMillis());
40: for (int i = 0; i < toEvict; i++) {
41: // Pick a random item (Knuth shuffle algorithm)42: int next = i + random.nextInt(expiredLeases.size() - i);
43: Collections.swap(expiredLeases, i, next);
44: Lease<InstanceInfo> lease = expiredLeases.get(i);
45:
46: String appName = lease.getHolder().getAppName();
47: String id = lease.getHolder().getId();
48: EXPIRED.increment();
49: logger.warn("DS: Registry: expired lease for {}/{}", appName, id);
50: internalCancel(appName, id, false);
51: }
52: }
53: }
複製程式碼
Note that due to renew() doing the 'wrong" thing and setting lastUpdateTimestamp to +duration more than what it should be, the expiry will actually be 2 * duration. This is a minor bug and should only affect instances that ungracefully shutdown. Due to possible wide ranging impact to existing usage, this will not be fixed.