SpringCloud学习笔记(3)----Spring Cloud Netflix之深入理解Eureka

  

1. Eureka服务端的启动过程

  1.1  入口类EurekaServerInitializerConfiguration类,

public void start() {
        (new Thread(new Runnable() { public void run() { try { EurekaServerInitializerConfiguration.this.eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext); EurekaServerInitializerConfiguration.log.info("Started Eureka Server"); EurekaServerInitializerConfiguration.this.publish(new EurekaRegistryAvailableEvent(EurekaServerInitializerConfiguration.this.getEurekaServerConfig())); EurekaServerInitializerConfiguration.this.running = true; EurekaServerInitializerConfiguration.this.publish(new EurekaServerStartedEvent(EurekaServerInitializerConfiguration.this.getEurekaServerConfig())); } catch (Exception var2) { EurekaServerInitializerConfiguration.log.error("Could not initialize Eureka servlet context", var2); } } })).start(); }

 通过start()方法来加载上下文和相关的Server端的配置信息,该类上面使用了@Configuration注解,会被spring bean容器感知到。

  2. Eureka的初始化

  EurekaServerBootstrap类的contextInitialized方法

 public void contextInitialized(ServletContext context) {
        try { this.initEurekaEnvironment(); //环境初始化 this.initEurekaServerContext(); //服务初始化 context.setAttribute(EurekaServerContext.class.getName(), this.serverContext); } catch (Throwable var3) { log.error("Cannot bootstrap eureka server :", var3); throw new RuntimeException("Cannot bootstrap eureka server :", var3); } }

  查找服务初始化中的Evicetion

protected void initEurekaServerContext() throws Exception {
        JsonXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(), 10000); XmlXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(), 10000); if (this.isAws(this.applicationInfoManager.getInfo())) { this.awsBinder = new AwsBinderDelegate(this.eurekaServerConfig, this.eurekaClientConfig, this.registry, this.applicationInfoManager); this.awsBinder.start(); } EurekaServerContextHolder.initialize(this.serverContext); log.info("Initialized server context"); int registryCount = this.registry.syncUp(); this.registry.openForTraffic(this.applicationInfoManager, registryCount); EurekaMonitors.registerAllStats(); }

  openForTraffic()

 public void openForTraffic(ApplicationInfoManager applicationInfoManager, int count) {
        this.expectedNumberOfRenewsPerMin = count * 2; this.numberOfRenewsPerMinThreshold = (int)((double)this.expectedNumberOfRenewsPerMin * this.serverConfig.getRenewalPercentThreshold()); logger.info("Got {} instances from neighboring DS node", count); logger.info("Renew threshold is: {}", this.numberOfRenewsPerMinThreshold); this.startupTime = System.currentTimeMillis(); if (count > 0) { this.peerInstancesTransferEmptyOnStartup = false; } Name selfName = applicationInfoManager.getInfo().getDataCenterInfo().getName(); boolean isAws = Name.Amazon == selfName; if (isAws && this.serverConfig.shouldPrimeAwsReplicaConnections()) { logger.info("Priming AWS connections for all replicas.."); this.primeAwsReplicas(applicationInfoManager); } logger.info("Changing status to UP"); applicationInfoManager.setInstanceStatus(InstanceStatus.UP); super.postInit(); }
 protected void postInit() {
        this.renewsLastMin.start(); if (this.evictionTaskRef.get() != null) { ((AbstractInstanceRegistry.EvictionTask)this.evictionTaskRef.get()).cancel(); } this.evictionTaskRef.set(new AbstractInstanceRegistry.EvictionTask()); this.evictionTimer.schedule((TimerTask)this.evictionTaskRef.get(), this.serverConfig.getEvictionIntervalTimerInMs(), this.serverConfig.getEvictionIntervalTimerInMs()); }

  

2. 客户端注册过程

  客户端流程

  

  1.入口:DiscoveryClient功能描述

     1)  向Eureka Server注册服务实例

        2)向Eureka Server续约

        3)  当服务关闭的时候向Eureka Server取消租约

        4)  查询注册到Eureka Server中的服务实例

  2 实例化,调用构造方法

@Inject
    DiscoveryClient(ApplicationInfoManager applicationInfoManager, EurekaClientConfig config, AbstractDiscoveryClientOptionalArgs args, Provider<BackupRegistry> backupRegistryProvider) {
        this.RECONCILE_HASH_CODES_MISMATCH = Monitors.newCounter("DiscoveryClient_ReconcileHashCodeMismatch");
        this.FETCH_REGISTRY_TIMER = Monitors.newTimer("DiscoveryClient_FetchRegistry"); this.REREGISTER_COUNTER = Monitors.newCounter("DiscoveryClient_Reregister"); this.localRegionApps = new AtomicReference(); this.fetchRegistryUpdateLock = new ReentrantLock(); this.healthCheckHandlerRef = new AtomicReference(); this.remoteRegionVsApps = new ConcurrentHashMap(); this.lastRemoteInstanceStatus = InstanceStatus.UNKNOWN; this.eventListeners = new CopyOnWriteArraySet(); this.registrySize = 0; this.lastSuccessfulRegistryFetchTimestamp = -1L; this.lastSuccessfulHeartbeatTimestamp = -1L; this.isShutdown = new AtomicBoolean(false); if (args != null) { this.healthCheckHandlerProvider = args.healthCheckHandlerProvider; this.healthCheckCallbackProvider = args.healthCheckCallbackProvider; this.eventListeners.addAll(args.getEventListeners()); this.preRegistrationHandler = args.preRegistrationHandler; } else { this.healthCheckCallbackProvider = null; this.healthCheckHandlerProvider = null; this.preRegistrationHandler = null; } this.applicationInfoManager = applicationInfoManager; InstanceInfo myInfo = applicationInfoManager.getInfo(); this.clientConfig = config; staticClientConfig = this.clientConfig; this.transportConfig = config.getTransportConfig(); this.instanceInfo = myInfo; if (myInfo != null) { this.appPathIdentifier = this.instanceInfo.getAppName() + "/" + this.instanceInfo.getId(); } else { logger.warn("Setting instanceInfo to a passed in null value"); } this.backupRegistryProvider = backupRegistryProvider; this.urlRandomizer = new InstanceInfoBasedUrlRandomizer(this.instanceInfo); this.localRegionApps.set(new Applications()); this.fetchRegistryGeneration = new AtomicLong(0L); this.remoteRegionsToFetch = new AtomicReference(this.clientConfig.fetchRegistryForRemoteRegions()); this.remoteRegionsRef = new AtomicReference(this.remoteRegionsToFetch.get() == null ? null : ((String)this.remoteRegionsToFetch.get()).split(",")); if (config.shouldFetchRegistry()) { this.registryStalenessMonitor = new ThresholdLevelsMetric(this, "eurekaClient.registry.lastUpdateSec_", new long[]{15L, 30L, 60L, 120L, 240L, 480L}); } else { this.registryStalenessMonitor = ThresholdLevelsMetric.NO_OP_METRIC; } if (config.shouldRegisterWithEureka()) { this.heartbeatStalenessMonitor = new ThresholdLevelsMetric(this, "eurekaClient.registration.lastHeartbeatSec_", new long[]{15L, 30L, 60L, 120L, 240L, 480L}); } else { this.heartbeatStalenessMonitor = ThresholdLevelsMetric.NO_OP_METRIC; } logger.info("Initializing Eureka in region {}", this.clientConfig.getRegion()); if (!config.shouldRegisterWithEureka() && !config.shouldFetchRegistry()) { logger.info("Client configured to neither register nor query for data."); this.scheduler = null; this.heartbeatExecutor = null; this.cacheRefreshExecutor = null; this.eurekaTransport = null; this.instanceRegionChecker = new InstanceRegionChecker(new PropertyBasedAzToRegionMapper(config), this.clientConfig.getRegion()); DiscoveryManager.getInstance().setDiscoveryClient(this); DiscoveryManager.getInstance().setEurekaClientConfig(config); this.initTimestampMs = System.currentTimeMillis(); logger.info("Discovery Client initialized at timestamp {} with initial instances count: {}", this.initTimestampMs, this.getApplications().size()); } else { try { this.scheduler = Executors.newScheduledThreadPool(2, (new ThreadFactoryBuilder()).setNameFormat("DiscoveryClient-%d").setDaemon(true).build()); this.heartbeatExecutor = new ThreadPoolExecutor(1, this.clientConfig.getHeartbeatExecutorThreadPoolSize(), 0L, TimeUnit.SECONDS, new SynchronousQueue(), (new ThreadFactoryBuilder()).setNameFormat("DiscoveryClient-HeartbeatExecutor-%d").setDaemon(true).build()); this.cacheRefreshExecutor = new ThreadPoolExecutor(1, this.clientConfig.getCacheRefreshExecutorThreadPoolSize(), 0L, TimeUnit.SECONDS, new SynchronousQueue(), (new ThreadFactoryBuilder()).setNameFormat("DiscoveryClient-CacheRefreshExecutor-%d").setDaemon(true).build()); this.eurekaTransport = new DiscoveryClient.EurekaTransport(); this.scheduleServerEndpointTask(this.eurekaTransport, args); Object azToRegionMapper; if (this.clientConfig.shouldUseDnsForFetchingServiceUrls()) { azToRegionMapper = new DNSBasedAzToRegionMapper(this.clientConfig); } else { azToRegionMapper = new PropertyBasedAzToRegionMapper(this.clientConfig); } if (null != this.remoteRegionsToFetch.get()) { ((AzToRegionMapper)azToRegionMapper).setRegionsToFetch(((String)this.remoteRegionsToFetch.get()).split(",")); } this.instanceRegionChecker = new InstanceRegionChecker((AzToRegionMapper)azToRegionMapper, this.clientConfig.getRegion()); } catch (Throwable var9) { throw new RuntimeException("Failed to initialize DiscoveryClient!", var9); } if (this.clientConfig.shouldFetchRegistry() && !this.fetchRegistry(false)) { this.fetchRegistryFromBackup(); } if (this.preRegistrationHandler != null) { this.preRegistrationHandler.beforeRegistration(); } if (this.clientConfig.shouldRegisterWithEureka() && this.clientConfig.shouldEnforceRegistrationAtInit()) { try { if (!this.register()) { throw new IllegalStateException("Registration error at startup. Invalid server response."); } } catch (Throwable var8) { logger.error("Registration error at startup: {}", var8.getMessage()); throw new IllegalStateException(var8); } } this.initScheduledTasks(); //注册任务主要是在这个定时任务里面实现 try { Monitors.registerObject(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值