Springcloud Eureka原理

Spring Cloud Eureka 基于 Netflix Eureka 进行了封装,增加了Spring Boot 特有的自动化配置风格,主要负责微服务中的服务治理功能,包括服务注册服务发现

我们希望有一个模块可以自动注册存在的微服务,而不是手动配置。在调用的时候,在这个模块中查找被注册的服务的位置,然后直接调用,这就是服务治理。

Eureka 主要用于服务治理,主要包含两大部分,服务注册中心客户端。客户端又可以根据需要分为服务提供者和服务消费者。

服务治理机制

服务注册中心

  • 失效剔除:
    在正常情况下,服务提供者下线时,将会提醒服务注册中心下线,然后服务注册中心会将服务的实例从服务列表剔除。
    如果由于网络故障,没有将下线的请求信息发送给注册中心,服务中心不知道具体的服务提供者已经下线,在Eureka Server 启动的时候,一个定时任务将会被创建,每60s(默认)便去清单中剔除超过90s(默认) 的服务实例。

  • 自我保护:
    Eureka Server 会维持一个心跳,如果运行时,统计心跳的比例在15分钟内低于85%,则服务中心将会自动启动自我保护机制。
    在自我保护机制中,当前的注册信息会被保护起来,使得这些信息不会过期。在实际情况中可能由于网络不稳定导致心跳失败,所以自我保护机制还是很有必要。在调试中会调用到不存在的服务实例,需要将自我保护机制关掉。

	//自我保护机制
	private boolean enableSelfPreservation = true;

	private double renewalPercentThreshold = 0.85;
eureka:
  server:
  	# 关掉自我保护
    enable-self-preservation: false

服务提供者

  • 服务注册:
    只要加上注解就可以使得客户端到服务注册中心注册。客户端启动之后,会马上发送请求,并按照配置配置信息注册到服务注册中心,在请求中会带上服务的元数据信息。
  • 服务续约:
    在服务注册之后,服务提供者需要使用心跳来维护注册的服务。为了防止剔除,服务提供者使用心跳进行维护,这个过程称为服务续约。
euewka:
  instance:
    # 续约时间,也是心跳时间
    lease-renewal-interval-in-seconds: 30
    # 服务时效时间 超时时间
    lease-expiration-duration-in-seconds: 90

服务消费者

  • 服务下线
    当服务进行关闭,客户端就会触发一个服务消息给Eureka Server, 提醒这是一个正常的服务关闭操作,然后服务注册中心就可以把服务实例从列表删除。

  • 获取服务:
    启动服务消费者,将会触发一个请求给服务注册中心,将服务注册中心的服务清单获取下来,并在客户端维护。也可以定期更新本地维护的清单,默认30s。

eureka:
  client:
    # 定期更新本地维护的清单
    registry-fetch-interval-seconds: 30

查看自动配置类

服务注册中心配置

org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean

@ConfigurationProperties(EurekaServerConfigBean.PREFIX)
public class EurekaServerConfigBean implements EurekaServerConfig {

	//服务注册中心的配置都是以 eureka.server 开头
	public static final String PREFIX = "eureka.server";

	private static final int MINUTES = 60 * 1000;

	@Autowired(required = false)
	PropertyResolver propertyResolver;

	private String aWSAccessId;

	private String aWSSecretKey;

	private int eIPBindRebindRetries = 3;

	private int eIPBindingRetryIntervalMs = 5 * MINUTES;

	private int eIPBindingRetryIntervalMsWhenUnbound = 1 * MINUTES;
	
	//自我保护机制
	private boolean enableSelfPreservation = true;
	//心跳失败比例
	private double renewalPercentThreshold = 0.85;
	//续约数阀值更新频率
	private int renewalThresholdUpdateIntervalMs = 15 * MINUTES;
	
	..........

服务注册类的配置

org.springframework.cloud.netflix.eureka.EurekaClientConfigBean

@ConfigurationProperties(EurekaClientConfigBean.PREFIX)
public class EurekaClientConfigBean implements EurekaClientConfig, Ordered {

	//客户端配置都是以 eureka.client 开头
	public static final String PREFIX = "eureka.client";

	/**
	 * Default Eureka URL.
	 */
	public static final String DEFAULT_URL = "http://localhost:8761" + DEFAULT_PREFIX + "/";

	//默认可用分区。
	public static final String DEFAULT_ZONE = "defaultZone";

	private static final int MINUTES = 60;

	@Autowired(required = false)
	PropertyResolver propertyResolver;

	// 是否启动客户端
	private boolean enabled = true;
	
	// 获取服务的时间间隔
	private int registryFetchIntervalSeconds = 30;
	
	//更新实例到 Server 的时间
	private int instanceInfoReplicationIntervalSeconds = 30;

	//初始化实例到Server 的时间
	private int initialInstanceInfoReplicationIntervalSeconds = 40;

	//轮询Server地址更改时间
	private int eurekaServiceUrlPollIntervalSeconds = 5 * MINUTES;

	//读取 Server 超时时间
	private int eurekaServerReadTimeoutSeconds = 8;

	// 连接 Server 时间
	private int eurekaServerConnectTimeoutSeconds = 5;

	//Client 到Server 的连接总数
	private int eurekaServerTotalConnections = 200;

	//Client 到每个主机的连接总数
	private int eurekaServerTotalConnectionsPerHost = 50;
	........

服务实例类的配置

org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean

//实力类的配置以 eureka.instance 开头
@ConfigurationProperties("eureka.instance")
public class EurekaInstanceConfigBean implements CloudEurekaInstanceConfig, EnvironmentAware {

	private static final String UNKNOWN = "unknown";

	//配置前缀
	private String actuatorPrefix = "/actuator";

	// 应用名
	private String appname = UNKNOWN;

	// 应用组名
	private String appGroupName;

	// 实例注册之后,是否马上开启通信,默认 false
	private boolean instanceEnabledOnit;
	
	// 非安全端口
	private int nonSecurePort = 80;
	
	// 安全端口
	private int securePort = 443;

	..............

服务注册中心仪表盘配置

服务注册中心的仪表盘用于服务注册中心的可视化展示。
org.springframework.cloud.netflix.eureka.server.EurekaDashboardProperties

@ConfigurationProperties("eureka.dashboard")
public class EurekaDashboardProperties {

	// 仪表盘访问路径
	private String path = "/";
	
	//	是否启用仪表盘
	private boolean enabled = true;

eureka:
  dashboard:
    path: /dashboard

在这里插入图片描述# 查看源码

DiscoveryClient 实例


/**
 * Convenience annotation for clients to enable Eureka discovery configuration
 * (specifically). Use this (optionally) in case you want discovery and know for sure that
 * it is Eureka you want. All it does is turn on discovery and let the autoconfiguration
 * find the eureka classes if they are available (i.e. you need Eureka on the classpath as
 * well).
 *
 * @author Dave Syer
 * @author Spencer Gibb
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface EnableEurekaClient {

}

通过注释发现,@EnableEurekaClient的作用就是启动Eureka Discovery configuration.

public class EurekaDiscoveryClient implements DiscoveryClient {

EurekaDiscoveryClient类的作用就是与Eureka Server 相互协作/

Eureka Client 负责向Server 注册服务实例、向Server 租约续期、向Server取消租约、查询Server中的服务实例列表,Eureka Client 还需要配置一个Eureka Server 的URL列表。

服务发现

从要与eureka客户机对话的属性文件中获取所有eureka服务url的列表。

public static List<String> getServiceUrlsFromConfig(EurekaClientConfig clientConfig, String instanceZone, boolean preferSameZone) {
        List<String> orderedUrls = new ArrayList<String>();
        // 读取region 并返回,每个微服务对应一个 region
        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;
    }

获取实例

@Override
	public List<ServiceInstance> getInstances(String serviceId) {
		List<InstanceInfo> infos = this.eurekaClient.getInstancesByVipAddress(serviceId, false);
		List<ServiceInstance> instances = new ArrayList<>();
		for (InstanceInfo info : infos) {
			instances.add(new EurekaServiceInstance(info));
		}
		return instances;
	}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Cloud Eureka是一个用于服务注册和发现的组件,它简化了在微服务架构中的服务管理和通信。 首先,Spring Cloud Eureka由两个核心角色组成:Eureka Server和Eureka Client。 Eureka Server主要负责服务注册和发现。它是一个集中式的服务注册中心,负责管理所有服务的状态和元数据。每个服务在启动时会向Eureka Server注册自己的实例信息,包括服务名称、IP地址和端口等,Eureka Server会维护一个服务注册表来跟踪所有已注册的服务。 Eureka Client则是各个微服务应用程序的客户端。它在服务启动时会向Eureka Server注册自己,并定期发送心跳来更新自己的状态。同时,它也会从Eureka Server获取其他服务的注册信息,并将其缓存在本地。这样,当需要使用其他服务时,Eureka Client可以直接从缓存中获取服务的访问地址,而不需要向注册中心发送请求。 此外,Eureka Server和Eureka Client之间也会进行心跳和故障检测。Eureka Client会定时发送心跳给Eureka Server,以通知自己的状态仍然健康;而Eureka Server则会周期性地检查各个服务的心跳,并从注册表中删除超时没有心跳的服务。 总的来说,Spring Cloud Eureka通过Eureka Server作为中心化的服务注册中心,实现了微服务的注册和发现。它可以根据客户端的需求,动态地维护服务的可用性和负载均衡。这样,微服务架构中的各个服务可以方便地相互调用,并实现高可用的分布式系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zxg45

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值