Make writing a habit together! This is the third day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details

Eureka Server registry cache logic

To protect the coral from the pounding waves? That would ruin their beauty

Eureka Server start process analysis diagram + source code explain Eureka Client start process analysis

Flowchart of client pull registry

The eureka Server core highlights are constructedRead and write cacheandA read-only cacheOperation, the 30 s cache comparison operation, so that is the logic of the client pull the registry is, if opened read-only cache first from a read-only cache registry, if only the registry does not exist under the condition of read and write from the cache, if you to read and write cache and no words from registry after pull synchronization to read and write cache, In sync to read-only cache

Registry core logic flow chart

Where to start

Servercontext.initialize () performs the cache operation when the serverContext is initialized. The registry.init() method is the core operation, and the main initialization cache logic is init

@PostConstruct
@Override
public void initialize(a) {
    logger.info("Initializing ...");
    try{...Mysql > select * from eureka server; mysql > select * from eureka server; mysql > select * from eureka server
        registry.init(peerEurekaNodes);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    logger.info("Initialized");
}
Copy the code

Eureka Server Registry core process

1. The init method

This method is the registry class init method, PeerAwareInstanceRegistryImpl# init () method, the initialization core method is the local cache initializedResponseCache ()

@Override
public void init(PeerEurekaNodes peerEurekaNodes) throws Exception {
    this.numberOfReplicationsLastMin.start();
    this.peerEurekaNodes = peerEurekaNodes;
    /** * Initialize the cache */initializedResponseCache(); . }Copy the code

2. Construct the read and write cache

If the responseCache object is empty, then we’ll create a ResponseCacheImpl object that contains a cache called readWriteCacheMap, which is created by the constructor. The generatePayload(key) method inside gets the registry information

ResponseCacheImpl(EurekaServerConfig serverConfig, ServerCodecs serverCodecs, 
                  AbstractInstanceRegistry registry) {
    / / shouldUseReadOnlyResponseCache whether to use a read-only cache is true by default
    this.shouldUseReadOnlyResponseCache = serverConfig.shouldUseReadOnlyResponseCache();
    this.registry = registry;
    // Cache update interval (30 x 1000) = 30s
    long responseCacheUpdateIntervalMs = serverConfig.getResponseCacheUpdateIntervalMs();
    this.readWriteCacheMap =
            / / serverConfig. GetInitialCapacityOfResponseCache () to initialize the capacity is 1000
          CacheBuilder.newBuilder().initialCapacity(
            serverConfig.getInitialCapacityOfResponseCache())
        // Set the automatic expiration time to 180s, so after you put a data into readWriteCacheMap,
        // Automatically wait 180 seconds before the data expires
           .expireAfterWrite(serverConfig.getResponseCacheAutoExpirationInSeconds(), 
                             TimeUnit.SECONDS)
            ...
    .build(new CacheLoader<Key, Value>() {
        @Override
        public Value load(Key key) throws Exception {
            if (key.hasRegions()) {
                Key cloneWithNoRegions = key.cloneWithoutRegions();
                regionSpecificKeys.put(cloneWithNoRegions, key);
            }
            // Get the full registry
            Value value = generatePayload(key);
            returnvalue; }}); }Copy the code

The flow chart

3. Scheduled task getCacheUpdateTask()

if (shouldUseReadOnlyResponseCache) {
    /** * Update every 30 seconds read-only cache retrives data from the read/write cache * by default, executes a scheduled thread task, TimerTask, which has a logic that every 30 seconds, * Compare readOnlyCacheMap with readWriteCacheMap. * If they are inconsistent, add readWriteCacheMap to readOnlyCacheMap */
   timer.schedule(getCacheUpdateTask(),
     new Date(((System.currentTimeMillis() / responseCacheUpdateIntervalMs) *
    responseCacheUpdateIntervalMs) + responseCacheUpdateIntervalMs),
    responseCacheUpdateIntervalMs);
}
Copy the code

A task is scheduled every 30 seconds for read/write cache and read-only cache synchronization

private TimerTask getCacheUpdateTask(a) {
   return new TimerTask() {
    @Override
    public void run(a) {
        for (Key key : readOnlyCacheMap.keySet()) {
            // Get the key value in the read/write cache
            Value cacheValue = readWriteCacheMap.get(key);
            // Get the key value in the read-only cache
            Value currentCacheValue = readOnlyCacheMap.get(key);
           If the read/write cache key is different from the read/write cache key, the read/write cache key is put into the read/write cache
            if(cacheValue ! = currentCacheValue) { readOnlyCacheMap.put(key, cacheValue); }}}}; }Copy the code

The flow chart

summary

  1. The server initializes the context
  2. Construct the read/write cache readWriteMap through the constructor pattern
  3. Define a scheduler getCacheUpdateTask() that executes a task for 30 seconds for task comparison