in foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java [277:335]
public void run() {
try {
Map<String, Map<String, List<String>>> removed = new HashMap<>();
for (Entry<String, Map<String, Map<String, StatefulDiscoveryInstance>>> apps : DiscoveryManager.this.allInstances.entrySet()) {
for (Entry<String, Map<String, StatefulDiscoveryInstance>> services : apps.getValue().entrySet()) {
boolean changed = false;
for (StatefulDiscoveryInstance instance : services.getValue().values()) {
// check isolated time
if (instance.getIsolationStatus() == IsolationStatus.ISOLATED &&
instance.getIsolatedTime() + instance.getIsolateDuration() < System.currentTimeMillis()) {
instance.setIsolationStatus(IsolationStatus.NORMAL);
changed = true;
}
// check ping status
if (System.currentTimeMillis() - instance.getPingTime() > 60_000L) {
boolean pingResult = DiscoveryManager.this.ping.ping(instance);
if (pingResult && instance.getPingStatus() != PingStatus.OK) {
instance.setPingStatus(PingStatus.OK);
changed = true;
} else if (!pingResult && instance.getPingStatus() != PingStatus.FAIL) {
instance.setPingStatus(PingStatus.FAIL);
changed = true;
}
instance.setPingTime(System.currentTimeMillis());
}
// check unused
if (instance.getHistoryStatus() == HistoryStatus.HISTORY) {
if (instance.getStatus() != MicroserviceInstanceStatus.UP ||
instance.getPingStatus() == PingStatus.FAIL ||
instance.getIsolationStatus() == IsolationStatus.ISOLATED) {
removed.computeIfAbsent(apps.getKey(), k -> new HashMap<>())
.computeIfAbsent(services.getKey(), k -> new ArrayList<>()).add(instance.getInstanceId());
LOGGER.info("Remove instance {}/{}/{}/{}/{}/{}/{}/{}",
apps.getKey(), services.getKey(), instance.getRegistryName(),
instance.getInstanceId(), instance.getHistoryStatus(),
instance.getStatus(), instance.getPingStatus(), instance.getIsolationStatus());
changed = true;
}
}
}
if (changed) {
rebuildVersionCache(apps.getKey(), services.getKey());
}
}
}
// remove unused
for (Entry<String, Map<String, List<String>>> apps : removed.entrySet()) {
for (Entry<String, List<String>> services : apps.getValue().entrySet()) {
for (String instance : services.getValue()) {
DiscoveryManager.this.allInstances.get(apps.getKey()).get(services.getKey()).remove(instance);
}
}
}
} catch (Throwable e) {
LOGGER.error("discovery manager task error. ", e);
} finally {
DiscoveryManager.this.task.schedule(this, 3, TimeUnit.SECONDS);
}
}