Update the client registry

There are two types of registry download: full download and incremental download

private boolean fetchRegistry(boolean forceFullRegistryFetch) {
  try {
    // For the first time, applications is empty or the size of the application registered in Eureka is 0
    // Disable incremental update, force full fetch, and local registry number
    // Or vipAddress is configured
    Applications applications = getApplications();
    if(clientConfig.shouldDisableDelta() || (! Strings.isNullOrEmpty(clientConfig.getRegistryRefreshSingleVipAddress())) || forceFullRegistryFetch || (applications ==null)
        || (applications.getRegisteredApplications().size() == 0)
        || (applications.getVersion() == -1)) //Client application does not have latest library supporting delta
    {
      // Full download
      getAndStoreFullRegistry();
    } else {
      // Incremental updategetAndUpdateDelta(applications); }}// Notify about cache refresh before updating the instance remote status
  onCacheRefreshed();
  // Update remote status based on refreshed data held in the cache
  updateInstanceRemoteStatus();
  // registry was fetched successfully, so return true
  return true;
}
Copy the code

Full amount to download

A full download is relatively simple

private void getAndStoreFullRegistry(a) throws Throwable {
  Applications apps = null;
  EurekaHttpResponse<Applications> httpResponse = 
    clientConfig.getRegistryRefreshSingleVipAddress() == null
    ? eurekaTransport.queryClient.getApplications(remoteRegionsRef.get())
    : eurekaTransport.queryClient.getVip(clientConfig.getRegistryRefreshSingleVipAddress(), remoteRegionsRef.get());
  if (httpResponse.getStatusCode() == Status.OK.getStatusCode()) {
    // Get all registration information from EurekaServer
    apps = httpResponse.getEntity();
  }
  if (fetchRegistryGeneration.compareAndSet(currentUpdateGeneration, currentUpdateGeneration + 1)) {
    // Add to the local cache (order the returned data to be processed, and filter out services that are not online to remain online
    / / in (through the config shouldFilterOnlyUpInstances configured to true))
    localRegionApps.set(this.filterAndShuffle(apps)); }}Copy the code

Incremental download

private void getAndUpdateDelta(Applications applications) throws Throwable {
  Applications delta = null;
  // Get delta registry information
  EurekaHttpResponse<Applications> httpResponse = eurekaTransport.queryClient.
  getDelta(remoteRegionsRef.get());
  if (httpResponse.getStatusCode() == Status.OK.getStatusCode()) {
    delta = httpResponse.getEntity();
  }
  // If the incremental request data is empty, the full download is performed
  if (delta == null) {
    getAndStoreFullRegistry();
  } else if (fetchRegistryGeneration.compareAndSet(currentUpdateGeneration, currentUpdateGeneration + 1)) {
    String reconcileHashCode = "";
    if (fetchRegistryUpdateLock.tryLock()) {
      try {
        // Update the local registry
        updateDelta(delta);
        // Get the hashcode information from the registry
        reconcileHashCode = getReconcileHashCode(applications);
      } finally{ fetchRegistryUpdateLock.unlock(); }}// If the amount of instance data obtained by delta is inconsistent with the number of local registries, the full download is performed
    if(! reconcileHashCode.equals(delta.getAppsHashCode()) || clientConfig.shouldLogDeltaDiff()) { reconcileAndLogDifference(delta, reconcileHashCode);// this makes a remoteCall}}}Copy the code
private void updateDelta(Applications delta) {
  int deltaCount = 0;
  for (Application app : delta.getRegisteredApplications()) {
    for (InstanceInfo instance : app.getInstances()) {
      // Local registry information
      Applications applications = getApplications();
      // Get the region of the instance
      String instanceRegion = instanceRegionChecker.getInstanceRegion(instance);
      // Check whether it is a local region
      if(! instanceRegionChecker.isLocalRegion(instanceRegion)) { Applications remoteApps = remoteRegionVsApps.get(instanceRegion);if (null == remoteApps) {
          remoteApps = new Applications();
          remoteRegionVsApps.put(instanceRegion, remoteApps);
        }
        // Assign the remote Apps to applications if it is a non-local region
        applications = remoteApps;
      }
      ++deltaCount;
      if (ActionType.ADDED.equals(instance.getActionType())) {
        // Get the Application from the local registry
        Application existingApp = applications.getRegisteredApplications(instance.getAppName());
        // If it does not exist, add the app to which the increment was updated to applications
        if (existingApp == null) {
          // Add application to the registry
          applications.addApplication(app);
        }
        // Add the app instance information to the instance list
        // Look at the addInstance comment below
        applications.getRegisteredApplications(instance.getAppName()).addInstance(instance);
      } else if (ActionType.MODIFIED.equals(instance.getActionType())) {
        Application existingApp = applications.getRegisteredApplications(instance.getAppName());
        if (existingApp == null) {
          applications.addApplication(app);
        }
        applications.getRegisteredApplications(instance.getAppName()).addInstance(instance);
      } else if (ActionType.DELETED.equals(instance.getActionType())) {
        Application existingApp = applications.getRegisteredApplications(instance.getAppName());
        if(existingApp ! =null) {
          // Remove the instance from the local registry
          existingApp.removeInstance(instance);
          // If there is no instance information under the application in the local registry, remove the application
       if (existingApp.getInstancesAsIsFromEureka().isEmpty()) {
            applications.removeApplication(existingApp);
          }
        }
      }
    }
  }
}
Copy the code
public void addInstance(InstanceInfo i) {
  instancesMap.put(i.getId(), i);
  synchronized (instances) {
    //instances are of set type, and instanceInfo overrides equals,
    // If instanceId is not changed at the time of update, it will not be overwritten without removal.
    // So remove first and then add
    instances.remove(i);
    instances.add(i);
    isDirty = true; }}Copy the code

conclusion

Full download time or condition

  • Get the registry for the first time
  • Disabling incremental download
  • Configure the VIPaddress
  • Incremental update Full download if no data is retrieved
  • The hashcode(or inconsistent number of instances) of the incremental data and the local registry data is downloaded in full