zoukankan      html  css  js  c++  java
  • eureka注册原理

    https://www.jianshu.com/p/84d0b7eea882
    eureka注册原理:
    注册地址:POST 对象com.netflix.appinfo.InstanceInfo
    http://localhost:8761/eureka/apps/HELLO-SERVICE

    {Accept-Encoding=[gzip], Content-Type=[application/json], Accept=[application/json], DiscoveryIdentity-Name=[DefaultClient], DiscoveryIdentity-Version=[1.4], DiscoveryIdentity-Id=[192.168.1.106]}

    AbstractJerseyEurekaHttpClient.register
    ApacheHttpClient4Handler.handle

    HttpRequestExecutor.doSendRequest

    org.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServiceRegistration.start-->this.serviceRegistry.register(this.registration);

    org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry.register-->// 通过应用信息管理器去设置实例的状态 reg.getApplicationInfoManager().setInstanceStatus(reg.getInstanceConfig().getInitialStatus()); 取消注册deregister

    com.netflix.appinfo.ApplicationInfoManager.setInstanceStatus(InstanceStatus status)-->

    com.netflix.discovery.DiscoveryClient构造器里:

        // 这里是重点,开始定义定时任务调度器 scheduler
        try {
            // default size of 2 - 1 each for heartbeat and cacheRefresh
            scheduler = Executors.newScheduledThreadPool(2,
                    new ThreadFactoryBuilder()
                            .setNameFormat("DiscoveryClient-%d")
                            .setDaemon(true)
                            .build());
    
            // 定义心跳检测执行器,线程池核心线程数1个,最大线程数为配置参数HeartbeatExecutorThreadPoolSize
            heartbeatExecutor = new ThreadPoolExecutor(
                    1, clientConfig.getHeartbeatExecutorThreadPoolSize(), 0, TimeUnit.SECONDS,
                    new SynchronousQueue<Runnable>(),
                    new ThreadFactoryBuilder()
                            .setNameFormat("DiscoveryClient-HeartbeatExecutor-%d")
                            .setDaemon(true)
                            .build()
            );  // use direct handoff
    
            // 定义缓存刷新执行器,线程池核心线程数1个,最大线程数为配置参数CacheRefreshExecutorThreadPoolSize的值
            cacheRefreshExecutor = new ThreadPoolExecutor(
                    1, clientConfig.getCacheRefreshExecutorThreadPoolSize(), 0, TimeUnit.SECONDS,
                    new SynchronousQueue<Runnable>(),
                    new ThreadFactoryBuilder()
                            .setNameFormat("DiscoveryClient-CacheRefreshExecutor-%d")
                            .setDaemon(true)
                            .build()
            );  // use direct handoff
    
            // 初始化一个eureka请求传输器
            eurekaTransport = new EurekaTransport();
            scheduleServerEndpointTask(eurekaTransport, args);
    
            AzToRegionMapper azToRegionMapper;
            if (clientConfig.shouldUseDnsForFetchingServiceUrls()) {
                azToRegionMapper = new DNSBasedAzToRegionMapper(clientConfig);
            } else {
                azToRegionMapper = new PropertyBasedAzToRegionMapper(clientConfig);
            }
            if (null != remoteRegionsToFetch.get()) {
                azToRegionMapper.setRegionsToFetch(remoteRegionsToFetch.get().split(","));
            }
            instanceRegionChecker = new InstanceRegionChecker(azToRegionMapper, clientConfig.getRegion());
        } catch (Throwable e) {
            throw new RuntimeException("Failed to initialize DiscoveryClient!", e);
        }
    
        if (clientConfig.shouldFetchRegistry() && !fetchRegistry(false)) {
            fetchRegistryFromBackup();
        }
    
        // call and execute the pre registration handler before all background tasks (inc registration) is started
        if (this.preRegistrationHandler != null) {
            this.preRegistrationHandler.beforeRegistration();
        }
        // 注意这里如果开启初始化强制注册开关的话,会直接注册到    
        // eureka server,
        if (clientConfig.shouldRegisterWithEureka() && clientConfig.shouldEnforceRegistrationAtInit()) {
            try {
                if (!register() ) {
                    throw new IllegalStateException("Registration error at startup. Invalid server response.");
                }
            } catch (Throwable th) {
                logger.error("Registration error at startup: {}", th.getMessage());
                throw new IllegalStateException(th);
            }
        }
    
        // 重点是这里,初始化定时任务调度器
        initScheduledTasks();
    

    com.netflix.discovery.DiscoveryClient.initScheduledTasks()

    // 初始化定时任务调度器
    private void initScheduledTasks() {
    
        // 配置开启获取注册表信息开关,则调度器去调度CacheRefreshThread 任务,调度频率为registryFetchIntervalSeconds,首次延迟时间也是registryFetchIntervalSeconds ,即默认30秒
        if (clientConfig.shouldFetchRegistry()) {
            // registry cache refresh timer
            int registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds();
            int expBackOffBound = clientConfig.getCacheRefreshExecutorExponentialBackOffBound();
            scheduler.schedule(
                    new TimedSupervisorTask(
                            "cacheRefresh",
                            scheduler,
                            cacheRefreshExecutor,
                            registryFetchIntervalSeconds,
                            TimeUnit.SECONDS,
                            expBackOffBound,
                            new CacheRefreshThread()
                    ),
                    registryFetchIntervalSeconds, TimeUnit.SECONDS);
        }
    
        // 配置开启是否注册到server的开关,则调度器去调度HeartbeatThread 任务,调度频率为renewalIntervalInSecs,首次延迟时间也是renewalIntervalInSecs ,即默认30秒
        if (clientConfig.shouldRegisterWithEureka()) {
            int renewalIntervalInSecs = instanceInfo.getLeaseInfo().getRenewalIntervalInSecs();
            int expBackOffBound = clientConfig.getHeartbeatExecutorExponentialBackOffBound();
            logger.info("Starting heartbeat executor: " + "renew interval is: {}", renewalIntervalInSecs);
    
            // Heartbeat timer
            scheduler.schedule(
                    new TimedSupervisorTask(
                            "heartbeat",
                            scheduler,
                            heartbeatExecutor,
                            renewalIntervalInSecs,
                            TimeUnit.SECONDS,
                            expBackOffBound,
                            new HeartbeatThread()
                    ),
                    renewalIntervalInSecs, TimeUnit.SECONDS);
    
            // 实例信息复制定时器
            instanceInfoReplicator = new InstanceInfoReplicator(
                    this,
                    instanceInfo,
                    clientConfig.getInstanceInfoReplicationIntervalSeconds(),
                    2); // burstSize
    
            // 创建实例状态变化监听器
            statusChangeListener = new ApplicationInfoManager.StatusChangeListener() {
                @Override
                public String getId() {
                    return "statusChangeListener";
                }
    
                @Override
                public void notify(StatusChangeEvent statusChangeEvent) {
                    if (InstanceStatus.DOWN == statusChangeEvent.getStatus() ||
                            InstanceStatus.DOWN == statusChangeEvent.getPreviousStatus()) {
                        // log at warn level if DOWN was involved
                        logger.warn("Saw local status change event {}", statusChangeEvent);
                    } else {
                        logger.info("Saw local status change event {}", statusChangeEvent);
                    }
                    instanceInfoReplicator.onDemandUpdate();
                }
            };
    
            // 注意这里是开启了在需要的时候更新状态变化的开关才会添加监听器,此处当开关开启时,当状态发生变化,会立即收到通知,即调用onDemandUpdate方法
            if (clientConfig.shouldOnDemandUpdateStatusChange()) {
                applicationInfoManager.registerStatusChangeListener(statusChangeListener);
            }
    
            // 启动周期性实例信息复制到远程定时器,默认延迟40秒执行
            instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds());
        } else {
            logger.info("Not registering with Eureka server per configuration");
        }
    

    com.netflix.discovery.InstanceInfoReplicator.run()-->discoveryClient.register();

    com.netflix.discovery.DiscoveryClient.register()-->httpResponse = eurekaTransport.registrationClient.register(instanceInfo);

    AbstractJerseyEurekaHttpClient.register--> response = resourceBuilder.header("Accept-Encoding", "gzip").type(MediaType.APPLICATION_JSON_TYPE).accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, info);

    com.sun.jersey.api.client.WebResource.Builder.post(Class<T> c, Object requestEntity) 


    Daemon Thread [DiscoveryClient-HeartbeatExecutor-1] (Suspended (breakpoint at line 48 in AbstractJerseyEurekaHttpClient))
    JerseyApplicationClient(AbstractJerseyEurekaHttpClient).register(InstanceInfo) line: 48
    EurekaHttpClientDecorator$1.execute(EurekaHttpClient) line: 59
    MetricsCollectingEurekaHttpClient.execute(RequestExecutor<R>) line: 73
    MetricsCollectingEurekaHttpClient(EurekaHttpClientDecorator).register(InstanceInfo) line: 56
    EurekaHttpClientDecorator$1.execute(EurekaHttpClient) line: 59
    RedirectingEurekaHttpClient.executeOnNewServer(RequestExecutor<R>, AtomicReference<EurekaHttpClient>) line: 118
    RedirectingEurekaHttpClient.execute(RequestExecutor<R>) line: 79
    RedirectingEurekaHttpClient(EurekaHttpClientDecorator).register(InstanceInfo) line: 56
    EurekaHttpClientDecorator$1.execute(EurekaHttpClient) line: 59
    RetryableEurekaHttpClient.execute(RequestExecutor<R>) line: 119
    RetryableEurekaHttpClient(EurekaHttpClientDecorator).register(InstanceInfo) line: 56
    EurekaHttpClientDecorator$1.execute(EurekaHttpClient) line: 59
    SessionedEurekaHttpClient.execute(RequestExecutor<R>) line: 77
    SessionedEurekaHttpClient(EurekaHttpClientDecorator).register(InstanceInfo) line: 56
    CloudEurekaClient(DiscoveryClient).register() line: 815
    CloudEurekaClient(DiscoveryClient).renew() line: 837
    DiscoveryClient$HeartbeatThread.run() line: 1396
    Executors$RunnableAdapter<T>.call() line: 511
    FutureTask<V>.run() line: 266
    ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1149
    ThreadPoolExecutor$Worker.run() line: 624
    Thread.run() line: 748


    Daemon Thread [DiscoveryClient-InstanceInfoReplicator-0] (Suspended)
    HttpRequestExecutor.doSendRequest(HttpRequest, HttpClientConnection, HttpContext) line: 238
    HttpRequestExecutor.execute(HttpRequest, HttpClientConnection, HttpContext) line: 123
    DefaultRequestDirector.tryExecute(RoutedRequest, HttpContext) line: 686
    DefaultRequestDirector.execute(HttpHost, HttpRequest, HttpContext) line: 488
    DefaultHttpClient(AbstractHttpClient).doExecute(HttpHost, HttpRequest, HttpContext) line: 884
    DefaultHttpClient(CloseableHttpClient).execute(HttpHost, HttpRequest) line: 117
    DefaultHttpClient(CloseableHttpClient).execute(HttpHost, HttpRequest) line: 55
    ApacheHttpClient4Handler.handle(ClientRequest) line: 173
    GZIPContentEncodingFilter.handle(ClientRequest) line: 123
    EurekaIdentityHeaderFilter.handle(ClientRequest) line: 27
    ApacheHttpClient4(Client).handle(ClientRequest) line: 652
    WebResource.handle(Class<T>, ClientRequest) line: 682
    WebResource.access$200(WebResource, Class, ClientRequest) line: 74
    WebResource$Builder.post(Class<T>, Object) line: 570
    JerseyApplicationClient(AbstractJerseyEurekaHttpClient).register(InstanceInfo) line: 56
    EurekaHttpClientDecorator$1.execute(EurekaHttpClient) line: 59
    MetricsCollectingEurekaHttpClient.execute(RequestExecutor<R>) line: 73
    MetricsCollectingEurekaHttpClient(EurekaHttpClientDecorator).register(InstanceInfo) line: 56
    EurekaHttpClientDecorator$1.execute(EurekaHttpClient) line: 59
    RedirectingEurekaHttpClient.executeOnNewServer(RequestExecutor<R>, AtomicReference<EurekaHttpClient>) line: 118
    RedirectingEurekaHttpClient.execute(RequestExecutor<R>) line: 79
    RedirectingEurekaHttpClient(EurekaHttpClientDecorator).register(InstanceInfo) line: 56
    EurekaHttpClientDecorator$1.execute(EurekaHttpClient) line: 59
    RetryableEurekaHttpClient.execute(RequestExecutor<R>) line: 119
    RetryableEurekaHttpClient(EurekaHttpClientDecorator).register(InstanceInfo) line: 56
    EurekaHttpClientDecorator$1.execute(EurekaHttpClient) line: 59
    SessionedEurekaHttpClient.execute(RequestExecutor<R>) line: 77
    SessionedEurekaHttpClient(EurekaHttpClientDecorator).register(InstanceInfo) line: 56
    CloudEurekaClient(DiscoveryClient).register() line: 815
    InstanceInfoReplicator.run() line: 104
    InstanceInfoReplicator$1.run() line: 88
    Executors$RunnableAdapter<T>.call() line: 511
    ScheduledThreadPoolExecutor$ScheduledFutureTask<V>(FutureTask<V>).run() line: 266
    ScheduledThreadPoolExecutor$ScheduledFutureTask<V>.access$201(ScheduledThreadPoolExecutor$ScheduledFutureTask) line: 180
    ScheduledThreadPoolExecutor$ScheduledFutureTask<V>.run() line: 293
    ScheduledThreadPoolExecutor(ThreadPoolExecutor).runWorker(ThreadPoolExecutor$Worker) line: 1149
    ThreadPoolExecutor$Worker.run() line: 624
    Thread.run() line: 748


    Daemon Thread [DiscoveryClient-InstanceInfoReplicator-0] (Suspended)
    EurekaJacksonCodec.writeTo(T, OutputStream) line: 191
    CodecWrappers$LegacyJacksonJson.encode(T, OutputStream) line: 304
    DiscoveryJerseyProvider.writeTo(Object, Class, Type, Annotation[], MediaType, MultivaluedMap, OutputStream) line: 135
    RequestWriter$RequestEntityWriterImpl.writeRequestEntity(OutputStream) line: 231
    ApacheHttpClient4Handler$2.writeTo(OutputStream) line: 289
    EntityEnclosingRequestWrapper$EntityWrapper(HttpEntityWrapper).writeTo(OutputStream) line: 94
    EntityEnclosingRequestWrapper$EntityWrapper.writeTo(OutputStream) line: 112
    EntitySerializer.serialize(SessionOutputBuffer, HttpMessage, HttpEntity) line: 118
    DefaultClientConnection(AbstractHttpClientConnection).sendRequestEntity(HttpEntityEnclosingRequest) line: 263
    BasicPooledConnAdapter(AbstractClientConnAdapter).sendRequestEntity(HttpEntityEnclosingRequest) line: 241
    HttpRequestExecutor.doSendRequest(HttpRequest, HttpClientConnection, HttpContext) line: 238
    HttpRequestExecutor.execute(HttpRequest, HttpClientConnection, HttpContext) line: 123
    DefaultRequestDirector.tryExecute(RoutedRequest, HttpContext) line: 686
    DefaultRequestDirector.execute(HttpHost, HttpRequest, HttpContext) line: 488
    DefaultHttpClient(AbstractHttpClient).doExecute(HttpHost, HttpRequest, HttpContext) line: 884
    DefaultHttpClient(CloseableHttpClient).execute(HttpHost, HttpRequest) line: 117
    DefaultHttpClient(CloseableHttpClient).execute(HttpHost, HttpRequest) line: 55
    ApacheHttpClient4Handler.handle(ClientRequest) line: 173
    GZIPContentEncodingFilter.handle(ClientRequest) line: 123
    EurekaIdentityHeaderFilter.handle(ClientRequest) line: 27
    ApacheHttpClient4(Client).handle(ClientRequest) line: 652
    WebResource.handle(Class<T>, ClientRequest) line: 682
    WebResource.access$200(WebResource, Class, ClientRequest) line: 74
    WebResource$Builder.post(Class<T>, Object) line: 570
    JerseyApplicationClient(AbstractJerseyEurekaHttpClient).register(InstanceInfo) line: 56
    EurekaHttpClientDecorator$1.execute(EurekaHttpClient) line: 59
    MetricsCollectingEurekaHttpClient.execute(RequestExecutor<R>) line: 73
    MetricsCollectingEurekaHttpClient(EurekaHttpClientDecorator).register(InstanceInfo) line: 56
    EurekaHttpClientDecorator$1.execute(EurekaHttpClient) line: 59
    RedirectingEurekaHttpClient.executeOnNewServer(RequestExecutor<R>, AtomicReference<EurekaHttpClient>) line: 118
    RedirectingEurekaHttpClient.execute(RequestExecutor<R>) line: 79
    RedirectingEurekaHttpClient(EurekaHttpClientDecorator).register(InstanceInfo) line: 56
    EurekaHttpClientDecorator$1.execute(EurekaHttpClient) line: 59
    RetryableEurekaHttpClient.execute(RequestExecutor<R>) line: 119
    RetryableEurekaHttpClient(EurekaHttpClientDecorator).register(InstanceInfo) line: 56
    EurekaHttpClientDecorator$1.execute(EurekaHttpClient) line: 59
    SessionedEurekaHttpClient.execute(RequestExecutor<R>) line: 77
    SessionedEurekaHttpClient(EurekaHttpClientDecorator).register(InstanceInfo) line: 56
    CloudEurekaClient(DiscoveryClient).register() line: 815
    InstanceInfoReplicator.run() line: 104
    InstanceInfoReplicator$1.run() line: 88
    Executors$RunnableAdapter<T>.call() line: 511
    ScheduledThreadPoolExecutor$ScheduledFutureTask<V>(FutureTask<V>).run() line: 266
    ScheduledThreadPoolExecutor$ScheduledFutureTask<V>.access$201(ScheduledThreadPoolExecutor$ScheduledFutureTask) line: 180
    ScheduledThreadPoolExecutor$ScheduledFutureTask<V>.run() line: 293
    ScheduledThreadPoolExecutor(ThreadPoolExecutor).runWorker(ThreadPoolExecutor$Worker) line: 1149
    ThreadPoolExecutor$Worker.run() line: 624
    Thread.run() line: 748

  • 相关阅读:
    js的style.width取不到元素的宽度值
    git bush 无法使用箭头进行选择
    exports module.exports export export default之间的关系
    vue前端项目中excel文件下载
    vue -- router路由跳转错误 , NavigationDuplicated
    node url模块
    SSO CAS 单点系列
    离线电脑搭建开发环境
    Shader的语法
    NavMesh名字、层索引、层值之间的转换
  • 原文地址:https://www.cnblogs.com/yaoyu1983/p/12688656.html
Copyright © 2011-2022 走看看