Eureka 源碼分析

來源:互聯網
上載者:User

標籤:status   tst   ecif   cache   except   cat   初始化   cep   div   

啟動server服務,或者探索服務都使用了@EnableDiscoveryClient註解和eureka.instance.client.service-url.defaultZone

/**
* Annotation to enable a DiscoveryClient implementation.
* @author Spencer Gibb
*/

@Import(EnableDiscoveryClientImportSelector.class)public @interface EnableDiscoveryClient {    /**     * If true, the ServiceRegistry will automatically register the local server.     */    boolean autoRegister() default true;}

從註解注釋知道主要開啟DiscoveryClient 的實現

看下注釋知道Eureka Client它向Eureka server註冊服務執行個體, 向服務續約, 查詢Eureka Server 中的服務執行個體列表

Eureka Client 還需要配置一個Eureka Server 的URL列表

   public static List<String> getServiceUrlsFromConfig(EurekaClientConfig clientConfig, String instanceZone, boolean preferSameZone) {        List<String> orderedUrls = new ArrayList<String>();        String region = getRegion(clientConfig);        String[] availZones = clientConfig.getAvailabilityZones(clientConfig.getRegion());        if (availZones == null || availZones.length == 0) {            availZones = new String[1];            availZones[0] = DEFAULT_ZONE;        }        logger.debug("The availability zone for the given region {} are {}", region, availZones);        int myZoneOffset = getZoneOffset(instanceZone, preferSameZone, availZones);        List<String> serviceUrls = clientConfig.getEurekaServerServiceUrls(availZones[myZoneOffset]);        if (serviceUrls != null) {            orderedUrls.addAll(serviceUrls);        }        int currentOffset = myZoneOffset == (availZones.length - 1) ? 0 : (myZoneOffset + 1);        while (currentOffset != myZoneOffset) {            serviceUrls = clientConfig.getEurekaServerServiceUrls(availZones[currentOffset]);            if (serviceUrls != null) {                orderedUrls.addAll(serviceUrls);            }            if (currentOffset == (availZones.length - 1)) {                currentOffset = 0;            } else {                currentOffset++;            }        }        if (orderedUrls.size() < 1) {            throw new IllegalArgumentException("DiscoveryClient: invalid serviceUrl specified!");        }        return orderedUrls;    }
擷取url
public List<String> getEurekaServerServiceUrls(String myZone) {        String serviceUrls = this.serviceUrl.get(myZone);        if (serviceUrls == null || serviceUrls.isEmpty()) {            serviceUrls = this.serviceUrl.get(DEFAULT_ZONE);        }        if (!StringUtils.isEmpty(serviceUrls)) {            final String[] serviceUrlsSplit = StringUtils.commaDelimitedListToStringArray(serviceUrls);            List<String> eurekaServiceUrls = new ArrayList<>(serviceUrlsSplit.length);            for (String eurekaServiceUrl : serviceUrlsSplit) {                if (!endsWithSlash(eurekaServiceUrl)) {                    eurekaServiceUrl += "/";                }                eurekaServiceUrls.add(eurekaServiceUrl);            }            return eurekaServiceUrls;        }        return new ArrayList<>();    }
從配置中讀取url

服務註冊

 private void initScheduledTasks() {        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);        }        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);            // InstanceInfo replicator            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();                }            };            if (clientConfig.shouldOnDemandUpdateStatusChange()) {                applicationInfoManager.registerStatusChangeListener(statusChangeListener);            }            instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds());        } else {            logger.info("Not registering with Eureka server per configuration");        }    }
初始化任務

最下面一行 instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds());

 public void run() {        try {            discoveryClient.refreshInstanceInfo();            Long dirtyTimestamp = instanceInfo.isDirtyWithTime();            if (dirtyTimestamp != null) {                discoveryClient.register();                instanceInfo.unsetIsDirty(dirtyTimestamp);            }        } catch (Throwable t) {            logger.warn("There was a problem with the instance info replicator", t);        } finally {            Future next = scheduler.schedule(this, replicationIntervalSeconds, TimeUnit.SECONDS);            scheduledPeriodicRef.set(next);        }    }

註冊到server

    /**     * Register with the eureka service by making the appropriate REST call.     */    boolean register() throws Throwable {        logger.info(PREFIX + "{}: registering service...", appPathIdentifier);        EurekaHttpResponse<Void> httpResponse;        try {            httpResponse = eurekaTransport.registrationClient.register(instanceInfo);        } catch (Exception e) {            logger.warn(PREFIX + "{} - registration failed {}", appPathIdentifier, e.getMessage(), e);            throw e;        }        if (logger.isInfoEnabled()) {            logger.info(PREFIX + "{} - registration status: {}", appPathIdentifier, httpResponse.getStatusCode());        }        return httpResponse.getStatusCode() == 204;    }
   public EurekaHttpResponse<Void> register(InstanceInfo info) {        String urlPath = "apps/" + info.getAppName();        ClientResponse response = null;        try {            Builder resourceBuilder = jerseyClient.resource(serviceUrl).path(urlPath).getRequestBuilder();            addExtraHeaders(resourceBuilder);            response = resourceBuilder                    .header("Accept-Encoding", "gzip")                    .type(MediaType.APPLICATION_JSON_TYPE)                    .accept(MediaType.APPLICATION_JSON)                    .post(ClientResponse.class, info);            return anEurekaHttpResponse(response.getStatus()).headers(headersOf(response)).build();        } finally {            if (logger.isDebugEnabled()) {                logger.debug("Jersey HTTP POST {}/{} with instance {}; statusCode={}", serviceUrl, urlPath, info.getId(),                        response == null ? "N/A" : response.getStatus());            }            if (response != null) {                response.close();            }        }    }

restful 請求伺服器註冊上去

然後去看Eureka-server  的  EurekaBootStrap.class

啟動時

 @Override    public void contextInitialized(ServletContextEvent event) {        try {            initEurekaEnvironment();            initEurekaServerContext();            ServletContext sc = event.getServletContext();            sc.setAttribute(EurekaServerContext.class.getName(), serverContext);        } catch (Throwable e) {            logger.error("Cannot bootstrap eureka server :", e);            throw new RuntimeException("Cannot bootstrap eureka server :", e);        }    }
protected void initEurekaServerContext() throws Exception {  ...//省略代碼   PeerAwareInstanceRegistry registry;        if (isAws(applicationInfoManager.getInfo())) {           ...//省略代碼,是AWS的代碼        } else {            registry = new PeerAwareInstanceRegistryImpl(                    eurekaServerConfig,                    eurekaClient.getEurekaClientConfig(),                    serverCodecs,                    eurekaClient            );        }        PeerEurekaNodes peerEurekaNodes = getPeerEurekaNodes(                registry,                eurekaServerConfig,                eurekaClient.getEurekaClientConfig(),                serverCodecs,                applicationInfoManager        ); }

 

Eureka 源碼分析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.