Search in sources :

Example 1 with Lease

use of com.netflix.eureka.lease.Lease in project eureka by Netflix.

the class AbstractInstanceRegistry method renew.

/**
 * Marks the given instance of the given app name as renewed, and also marks whether it originated from
 * replication.
 *
 * @see com.netflix.eureka.lease.LeaseManager#renew(java.lang.String, java.lang.String, boolean)
 */
public boolean renew(String appName, String id, boolean isReplication) {
    RENEW.increment(isReplication);
    Map<String, Lease<InstanceInfo>> gMap = registry.get(appName);
    Lease<InstanceInfo> leaseToRenew = null;
    if (gMap != null) {
        leaseToRenew = gMap.get(id);
    }
    if (leaseToRenew == null) {
        RENEW_NOT_FOUND.increment(isReplication);
        logger.warn("DS: Registry: lease doesn't exist, registering resource: {} - {}", appName, id);
        return false;
    } else {
        InstanceInfo instanceInfo = leaseToRenew.getHolder();
        if (instanceInfo != null) {
            // touchASGCache(instanceInfo.getASGName());
            InstanceStatus overriddenInstanceStatus = this.getOverriddenInstanceStatus(instanceInfo, leaseToRenew, isReplication);
            if (overriddenInstanceStatus == InstanceStatus.UNKNOWN) {
                logger.info("Instance status UNKNOWN possibly due to deleted override for instance {}" + "; re-register required", instanceInfo.getId());
                RENEW_NOT_FOUND.increment(isReplication);
                return false;
            }
            if (!instanceInfo.getStatus().equals(overriddenInstanceStatus)) {
                logger.info("The instance status {} is different from overridden instance status {} for instance {}. " + "Hence setting the status to overridden status", instanceInfo.getStatus().name(), overriddenInstanceStatus.name(), instanceInfo.getId());
                instanceInfo.setStatusWithoutDirty(overriddenInstanceStatus);
            }
        }
        renewsLastMin.increment();
        leaseToRenew.renew();
        return true;
    }
}
Also used : Lease(com.netflix.eureka.lease.Lease) InstanceStatus(com.netflix.appinfo.InstanceInfo.InstanceStatus) InstanceInfo(com.netflix.appinfo.InstanceInfo)

Example 2 with Lease

use of com.netflix.eureka.lease.Lease in project eureka by Netflix.

the class AbstractInstanceRegistry method getApplicationsFromMultipleRegions.

/**
 * This method will return applications with instances from all passed remote regions as well as the current region.
 * Thus, this gives a union view of instances from multiple regions. <br/>
 * The application instances for which this union will be done can be restricted to the names returned by
 * {@link EurekaServerConfig#getRemoteRegionAppWhitelist(String)} for every region. In case, there is no whitelist
 * defined for a region, this method will also look for a global whitelist by passing <code>null</code> to the
 * method {@link EurekaServerConfig#getRemoteRegionAppWhitelist(String)} <br/>
 * If you are not selectively requesting for a remote region, use {@link #getApplicationsFromAllRemoteRegions()}
 * or {@link #getApplicationsFromLocalRegionOnly()}
 *
 * @param remoteRegions The remote regions for which the instances are to be queried. The instances may be limited
 *                      by a whitelist as explained above. If <code>null</code> or empty no remote regions are
 *                      included.
 *
 * @return The applications with instances from the passed remote regions as well as local region. The instances
 * from remote regions can be only for certain whitelisted apps as explained above.
 */
public Applications getApplicationsFromMultipleRegions(String[] remoteRegions) {
    boolean includeRemoteRegion = null != remoteRegions && remoteRegions.length != 0;
    logger.debug("Fetching applications registry with remote regions: {}, Regions argument {}", includeRemoteRegion, remoteRegions);
    if (includeRemoteRegion) {
        GET_ALL_WITH_REMOTE_REGIONS_CACHE_MISS.increment();
    } else {
        GET_ALL_CACHE_MISS.increment();
    }
    Applications apps = new Applications();
    apps.setVersion(1L);
    for (Entry<String, Map<String, Lease<InstanceInfo>>> entry : registry.entrySet()) {
        Application app = null;
        if (entry.getValue() != null) {
            for (Entry<String, Lease<InstanceInfo>> stringLeaseEntry : entry.getValue().entrySet()) {
                Lease<InstanceInfo> lease = stringLeaseEntry.getValue();
                if (app == null) {
                    app = new Application(lease.getHolder().getAppName());
                }
                app.addInstance(decorateInstanceInfo(lease));
            }
        }
        if (app != null) {
            apps.addApplication(app);
        }
    }
    if (includeRemoteRegion) {
        for (String remoteRegion : remoteRegions) {
            RemoteRegionRegistry remoteRegistry = regionNameVSRemoteRegistry.get(remoteRegion);
            if (null != remoteRegistry) {
                Applications remoteApps = remoteRegistry.getApplications();
                for (Application application : remoteApps.getRegisteredApplications()) {
                    if (shouldFetchFromRemoteRegistry(application.getName(), remoteRegion)) {
                        logger.info("Application {}  fetched from the remote region {}", application.getName(), remoteRegion);
                        Application appInstanceTillNow = apps.getRegisteredApplications(application.getName());
                        if (appInstanceTillNow == null) {
                            appInstanceTillNow = new Application(application.getName());
                            apps.addApplication(appInstanceTillNow);
                        }
                        for (InstanceInfo instanceInfo : application.getInstances()) {
                            appInstanceTillNow.addInstance(instanceInfo);
                        }
                    } else {
                        logger.debug("Application {} not fetched from the remote region {} as there exists a " + "whitelist and this app is not in the whitelist.", application.getName(), remoteRegion);
                    }
                }
            } else {
                logger.warn("No remote registry available for the remote region {}", remoteRegion);
            }
        }
    }
    apps.setAppsHashCode(apps.getReconcileHashCode());
    return apps;
}
Also used : Applications(com.netflix.discovery.shared.Applications) Lease(com.netflix.eureka.lease.Lease) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) InstanceInfo(com.netflix.appinfo.InstanceInfo) Application(com.netflix.discovery.shared.Application)

Example 3 with Lease

use of com.netflix.eureka.lease.Lease in project eureka by Netflix.

the class AbstractInstanceRegistry method register.

/**
 * Registers a new instance with a given duration.
 *
 * @see com.netflix.eureka.lease.LeaseManager#register(java.lang.Object, int, boolean)
 */
public void register(InstanceInfo registrant, int leaseDuration, boolean isReplication) {
    read.lock();
    try {
        Map<String, Lease<InstanceInfo>> gMap = registry.get(registrant.getAppName());
        REGISTER.increment(isReplication);
        if (gMap == null) {
            final ConcurrentHashMap<String, Lease<InstanceInfo>> gNewMap = new ConcurrentHashMap<String, Lease<InstanceInfo>>();
            gMap = registry.putIfAbsent(registrant.getAppName(), gNewMap);
            if (gMap == null) {
                gMap = gNewMap;
            }
        }
        Lease<InstanceInfo> existingLease = gMap.get(registrant.getId());
        // Retain the last dirty timestamp without overwriting it, if there is already a lease
        if (existingLease != null && (existingLease.getHolder() != null)) {
            Long existingLastDirtyTimestamp = existingLease.getHolder().getLastDirtyTimestamp();
            Long registrationLastDirtyTimestamp = registrant.getLastDirtyTimestamp();
            logger.debug("Existing lease found (existing={}, provided={}", existingLastDirtyTimestamp, registrationLastDirtyTimestamp);
            // InstanceInfo instead of the server local copy.
            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 = existingLease.getHolder();
            }
        } else {
            // The lease does not exist and hence it is a new registration
            synchronized (lock) {
                if (this.expectedNumberOfClientsSendingRenews > 0) {
                    // Since the client wants to register it, increase the number of clients sending renews
                    this.expectedNumberOfClientsSendingRenews = this.expectedNumberOfClientsSendingRenews + 1;
                    updateRenewsPerMinThreshold();
                }
            }
            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());
        }
        gMap.put(registrant.getId(), lease);
        recentRegisteredQueue.add(new Pair<Long, String>(System.currentTimeMillis(), registrant.getAppName() + "(" + registrant.getId() + ")"));
        // This is where the initial state transfer of overridden status happens
        if (!InstanceStatus.UNKNOWN.equals(registrant.getOverriddenStatus())) {
            logger.debug("Found overridden status {} for instance {}. Checking to see if needs to be add to the " + "overrides", registrant.getOverriddenStatus(), registrant.getId());
            if (!overriddenInstanceStatusMap.containsKey(registrant.getId())) {
                logger.info("Not found overridden id {} and hence adding it", registrant.getId());
                overriddenInstanceStatusMap.put(registrant.getId(), registrant.getOverriddenStatus());
            }
        }
        InstanceStatus overriddenStatusFromMap = overriddenInstanceStatusMap.get(registrant.getId());
        if (overriddenStatusFromMap != null) {
            logger.info("Storing overridden status {} from map", overriddenStatusFromMap);
            registrant.setOverriddenStatus(overriddenStatusFromMap);
        }
        // Set the status based on the overridden status rules
        InstanceStatus overriddenInstanceStatus = getOverriddenInstanceStatus(registrant, existingLease, isReplication);
        registrant.setStatusWithoutDirty(overriddenInstanceStatus);
        // If the lease is registered with UP status, set lease service up timestamp
        if (InstanceStatus.UP.equals(registrant.getStatus())) {
            lease.serviceUp();
        }
        registrant.setActionType(ActionType.ADDED);
        recentlyChangedQueue.add(new RecentlyChangedItem(lease));
        registrant.setLastUpdatedTimestamp();
        invalidateCache(registrant.getAppName(), registrant.getVIPAddress(), registrant.getSecureVipAddress());
        logger.info("Registered instance {}/{} with status {} (replication={})", registrant.getAppName(), registrant.getId(), registrant.getStatus(), isReplication);
    } finally {
        read.unlock();
    }
}
Also used : Lease(com.netflix.eureka.lease.Lease) InstanceStatus(com.netflix.appinfo.InstanceInfo.InstanceStatus) AtomicLong(java.util.concurrent.atomic.AtomicLong) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) InstanceInfo(com.netflix.appinfo.InstanceInfo)

Example 4 with Lease

use of com.netflix.eureka.lease.Lease in project eureka by Netflix.

the class AbstractInstanceRegistry method statusUpdate.

/**
 * Updates the status of an instance. Normally happens to put an instance
 * between {@link InstanceStatus#OUT_OF_SERVICE} and
 * {@link InstanceStatus#UP} to put the instance in and out of traffic.
 *
 * @param appName the application name of the instance.
 * @param id the unique identifier of the instance.
 * @param newStatus the new {@link InstanceStatus}.
 * @param lastDirtyTimestamp last timestamp when this instance information was updated.
 * @param isReplication true if this is a replication event from other nodes, false
 *                      otherwise.
 * @return true if the status was successfully updated, false otherwise.
 */
@Override
public boolean statusUpdate(String appName, String id, InstanceStatus newStatus, String lastDirtyTimestamp, boolean isReplication) {
    read.lock();
    try {
        STATUS_UPDATE.increment(isReplication);
        Map<String, Lease<InstanceInfo>> gMap = registry.get(appName);
        Lease<InstanceInfo> lease = null;
        if (gMap != null) {
            lease = gMap.get(id);
        }
        if (lease == null) {
            return false;
        } else {
            lease.renew();
            InstanceInfo info = lease.getHolder();
            // This log statement is provided as a safeguard, in case this invariant is violated.
            if (info == null) {
                logger.error("Found Lease without a holder for instance id {}", id);
            }
            if ((info != null) && !(info.getStatus().equals(newStatus))) {
                // Mark service as UP if needed
                if (InstanceStatus.UP.equals(newStatus)) {
                    lease.serviceUp();
                }
                // This is NAC overridden status
                overriddenInstanceStatusMap.put(id, newStatus);
                // Set it for transfer of overridden status to replica on
                // replica start up
                info.setOverriddenStatus(newStatus);
                long replicaDirtyTimestamp = 0;
                info.setStatusWithoutDirty(newStatus);
                if (lastDirtyTimestamp != null) {
                    replicaDirtyTimestamp = Long.parseLong(lastDirtyTimestamp);
                }
                // it to the replica's.
                if (replicaDirtyTimestamp > info.getLastDirtyTimestamp()) {
                    info.setLastDirtyTimestamp(replicaDirtyTimestamp);
                }
                info.setActionType(ActionType.MODIFIED);
                recentlyChangedQueue.add(new RecentlyChangedItem(lease));
                info.setLastUpdatedTimestamp();
                invalidateCache(appName, info.getVIPAddress(), info.getSecureVipAddress());
            }
            return true;
        }
    } finally {
        read.unlock();
    }
}
Also used : Lease(com.netflix.eureka.lease.Lease) InstanceInfo(com.netflix.appinfo.InstanceInfo)

Example 5 with Lease

use of com.netflix.eureka.lease.Lease in project eureka by Netflix.

the class AbstractInstanceRegistry method getApplication.

/**
 * Get application information.
 *
 * @param appName The name of the application
 * @param includeRemoteRegion true, if we need to include applications from remote regions
 *                            as indicated by the region {@link URL} by this property
 *                            {@link EurekaServerConfig#getRemoteRegionUrls()}, false otherwise
 * @return the application
 */
@Override
public Application getApplication(String appName, boolean includeRemoteRegion) {
    Application app = null;
    Map<String, Lease<InstanceInfo>> leaseMap = registry.get(appName);
    if (leaseMap != null && leaseMap.size() > 0) {
        for (Entry<String, Lease<InstanceInfo>> entry : leaseMap.entrySet()) {
            if (app == null) {
                app = new Application(appName);
            }
            app.addInstance(decorateInstanceInfo(entry.getValue()));
        }
    } else if (includeRemoteRegion) {
        for (RemoteRegionRegistry remoteRegistry : this.regionNameVSRemoteRegistry.values()) {
            Application application = remoteRegistry.getApplication(appName);
            if (application != null) {
                return application;
            }
        }
    }
    return app;
}
Also used : Lease(com.netflix.eureka.lease.Lease) Application(com.netflix.discovery.shared.Application)

Aggregations

Lease (com.netflix.eureka.lease.Lease)10 InstanceInfo (com.netflix.appinfo.InstanceInfo)9 InstanceStatus (com.netflix.appinfo.InstanceInfo.InstanceStatus)4 Application (com.netflix.discovery.shared.Application)4 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)4 HashMap (java.util.HashMap)3 Map (java.util.Map)3 ConcurrentMap (java.util.concurrent.ConcurrentMap)3 Applications (com.netflix.discovery.shared.Applications)2 ArrayList (java.util.ArrayList)2 AtomicLong (java.util.concurrent.atomic.AtomicLong)2 Entry (java.util.Map.Entry)1 Random (java.util.Random)1