• Eureka服务注册发现原理


    Eureka服务注册发现原理

    客户端启动时如何注册到服务端

    Eureka客户端在启动时,首先会创建心跳的定时任务,默认每隔30s向向服务端发送心跳请求,服务端对心跳做出响应。如果响应状态码是404,表示服务端并没有该客户端的服务信息,那么客户端就会向服务端发送注册请求,注册信息包括服务名、IP端口、实例ID等信息。

    //DiscoveryClient.java
    //定时任务线程池默认有两个任务,一个用来心跳检测,一个用来刷新缓存
    scheduler = Executors.newScheduledThreadPool(2, new ThreadFactoryBuilder()
       .setNameFormat("DiscoveryClient-%d").setDaemon(true).build());
    //心跳检测线程池:核心线程1个,EurekaClientConfigBean中默认配置最大心跳线程2个
    heartbeatExecutor = new ThreadPoolExecutor(1, 	clientConfig.getHeartbeatExecutorThreadPoolSize(), 0, TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>(),
                new ThreadFactoryBuilder()
                .setNameFormat("DiscoveryClient-HeartbeatExecutor-%d")
                .setDaemon(true)
                .build()
    );  
    //缓存刷新线程池
    cacheRefreshExecutor = new ThreadPoolExecutor(1, clientConfig.getCacheRefreshExecutorThreadPoolSize(), 0, TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>(),
                new ThreadFactoryBuilder()
                .setNameFormat("DiscoveryClient-CacheRefreshExecutor-%d")
                .setDaemon(true)
                .build()
            ); 
    //...       
    //初始化所有的调度任务
    initScheduledTasks();
    //...
    //DiscoveryClient#initScheduledTasks
    //客户端默认shouldFetchRegistry为true,注册缓存刷新定时器,定时刷新缓存
    //默认shouldRegistryWithEureka为true,定时调用心跳线程
    private class HeartbeatThread implements Runnable {
        public void run() {
            if (renew()) {
                lastSuccessfulHeartbeatTimeStamp = = System.currentTimeMillis();
            }
        }
    }
    
    boolean renew() {
        EurekaHttpResponse<InstanceInfo> httpResponse;
        try {
            httpResponse = eurekaTransport.registrationClient.sendHeartBeat(instanceInfo.getAppName(), instanceInfo.getId(), instanceInfo, null);
            logger.debug(PREFIX + "{} - Heartbeat status: {}", appPathIdentifier, httpResponse.getStatusCode());
            if (httpResponse.getStatusCode() == Status.NOT_FOUND.getStatusCode()) {
                REREGISTER_COUNTER.increment();
                logger.info(PREFIX + "{} - Re-registering apps/{}", appPathIdentifier, instanceInfo.getAppName());
                long timestamp = instanceInfo.setIsDirtyWithTime();
                boolean success = register();
                if (success) {
                    instanceInfo.unsetIsDirty(timestamp);
                }
                return success;
            }
            return httpResponse.getStatusCode() == Status.OK.getStatusCode();
        } catch (Throwable e) {
            logger.error(PREFIX + "{} - was unable to send heartbeat!", appPathIdentifier, e);
            return false;
        }
    }	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    服务端存储客户端信息

    //AbstractInstanceRegistry#register方法把服务实例信息InstanceInfo注册到了ConcurrentHashMap中
    
    • 1

    ###客户端获取服务端信息

    客户端通过刷新缓存的定时任务拉取服务端的服务信息,每次拉取后刷新本地已保存的信息。

    心跳机制和服务剔除机制

    心跳机制:客户端启动后,定时任务默认每隔30s向服务端发送心跳数据保持活跃。

    服务剔除机制:如果开启了自我保护机制,所有的服务都不会被剔除;如果未开启自我保护机制,那么将判断最后一分钟收到的心跳数与前一分钟收到的心跳数临界值比较,如果前者大于后者,且后者大于零则启用服务剔除机制。一旦开启了服务剔除机制,Eureka服务端并不会直接剔除所有已过期的服务,而是通过随机数的方式进行剔除,避免自我保护开启之前将所有的服务给剔除。

  • 相关阅读:
    wpf listbox实现选中动画
    大学生端午节网页作业制作 学生端午节日网页设计模板 传统文化节日端午节静态网页成品代码下载 端午节日网页设计作品
    c++并行与并发
    【附源码】Python计算机毕业设计美食菜谱网站
    用C语言将无符号整数转换为字符串
    HJ26 字符串排序
    粒子群算法总结(保证受益匪浅)——针对多元函数的不同维度的速度和位置约束
    如何解决Smartsheet 登录时遇到的问题
    基于SpringBoot的精准扶贫管理系统
    mycat实现mysql读写分离
  • 原文地址:https://blog.csdn.net/dolly_baby/article/details/128026661