Service Discovery: Eureka

介绍下Eureka的使用以及相关配置参数

高可用

服务调用

1.使用原始的Eureka DiscoveryClient 来找到服务实例的主机并且用Spring的RestTemplate来发起调用。 2.使用Ribbon,一个使用Eureka来找到服务实例的客户端负载均衡解决方案 3. 使用Feigin,它使用了一个说明性的方法来调用服务。它内部使用了Ribbo

源码

服务端

服务端启动

EurekaServerInitializerConfiguration.start()

try {
					//TODO: is this class even needed now?
					eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext);
					log.info("Started Eureka Server");

					publish(new EurekaRegistryAvailableEvent(getEurekaServerConfig()));
					EurekaServerInitializerConfiguration.this.running = true;
					publish(new EurekaServerStartedEvent(getEurekaServerConfig()));
				}
				catch (Exception ex) {
					// Help!
					log.error("Could not initialize Eureka servlet context", ex);
				}

复制 neighboring eureka node

// Copy registry from neighboring eureka node
		int registryCount = this.registry.syncUp();

计算Renews threshold (numberOfRenewsPerMinThreshold)

公式: 2 * N * 0.85 ==> 60/心跳时间(总是认为是30s)*instance num *factor Netflix code assumes that heartbeats are always received at intervals of 30 seconds for this calculation.

1.初始化 numberOfRenewsPerMinThreshold PeerAwareInstanceRegistryImpl


    @Override
      //count 来自 this.registry.syncUp();
    public void openForTraffic(ApplicationInfoManager applicationInfoManager, int count) {
        // Renewals happen every 30 seconds and for a minute it should be a factor of 2.
        this.expectedNumberOfRenewsPerMin = count * 2;
       // serverConfig.getRenewalPercentThreshold() 来自配置 默认0.85
        this.numberOfRenewsPerMinThreshold =
                (int) (this.expectedNumberOfRenewsPerMin * serverConfig.getRenewalPercentThreshold());
        logger.info("Got " + count + " instances from neighboring DS node");
        logger.info("Renew threshold is: " + numberOfRenewsPerMinThreshold);
        this.startupTime = System.currentTimeMillis();
        if (count > 0) {
            this.peerInstancesTransferEmptyOnStartup = false;
        }
        DataCenterInfo.Name selfName = applicationInfoManager.getInfo().getDataCenterInfo().getName();
        boolean isAws = Name.Amazon == selfName;
        if (isAws && serverConfig.shouldPrimeAwsReplicaConnections()) {
            logger.info("Priming AWS connections for all replicas..");
            primeAwsReplicas(applicationInfoManager);
        }
        logger.info("Changing status to UP");
        applicationInfoManager.setInstanceStatus(InstanceStatus.UP);
        super.postInit();
    }

2.客户端注册时候刷新numberOfRenewsPerMinThreshold

    AbstractInstanceRegistry
  // The lease does not exist and hence it is a new registration
                synchronized (lock) {
                    if (this.expectedNumberOfRenewsPerMin > 0) {
                        // Since the client wants to cancel it, reduce the threshold
                        // (1
                        // for 30 seconds, 2 for a minute)
                        this.expectedNumberOfRenewsPerMin = this.expectedNumberOfRenewsPerMin + 2;
                        this.numberOfRenewsPerMinThreshold =
                                (int) (this.expectedNumberOfRenewsPerMin * serverConfig.getRenewalPercentThreshold());
                    }
                }
                logger.debug("No previous lease information found; it is new registration");

3.renewal-threshold-update-interval-ms 时间间隔后从新计算阀值.

接收客户端的rest 请求 DiscoveryJerseyProvider

  @Override
    public Object readFrom(Class serializableClass, Type type,
                           Annotation[] annotations, MediaType mediaType,
                           MultivaluedMap headers, InputStream inputStream) throws IOException {
        DecoderWrapper decoder;
        if (MediaType.MEDIA_TYPE_WILDCARD.equals(mediaType.getSubtype())) {
            decoder = xmlDecoder;
        } else if ("json".equalsIgnoreCase(mediaType.getSubtype())) {
            decoder = jsonDecoder;
        } else {
            decoder = xmlDecoder; // default
        }

        try {
            return decoder.decode(inputStream, serializableClass);
        } catch (Throwable e) {
            if (e instanceof Error) { // See issue: https://github.com/Netflix/eureka/issues/72 on why we catch Error here.
                closeInputOnError(inputStream);
                throw new WebApplicationException(createErrorReply(500, e, mediaType));
            }
            LOGGER.debug("Cannot parse request body", e);
            throw new WebApplicationException(createErrorReply(400, "cannot parse request body", mediaType));
        }
    }

EvictionTask


以eviction-interval-timer-in-ms (eureka.server.evictionIntervalTimerInMs)指定的频率执行 移除过期的instacne.在移除之前检查是否进入自我保护模式.(Renews < Renews threshold && eureka.server.enableSelfPreservation=true)

Renews (last min)


每分钟计算一次.

客户端

转载于:https://my.oschina.net/fuckmylife0/blog/1548668

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值