精华内容
下载资源
问答
  • 服务发现原理 原理:如下图 1.1、发现原理 1.1.1、服务部署情况 注册中心:部署在上海机房,北京机房,深圳机房 服务提供者:部署在上海机房,深圳机房 消费者:部署在上海机房,北京机房 1.1.2、服务注册情况 ...

    服务发现原理

    • 原理:如下图

    1.1、发现原理

    1.1.1、服务部署情况
    • 注册中心:部署在上海机房,北京机房,深圳机房
    • 服务提供者:部署在上海机房,深圳机房
    • 消费者:部署在上海机房,北京机房
    1.1.2、服务注册情况
    • 注册中心:Server之间通过同步复制进行数据同步
    • 提供者(上海机房):注册到上海机房Server,并提供者数据同步到注册中心
    • 提供者(深圳机房):注册到深圳机房Server,并提供者数据同步到注册中心
    • 消费者(上海机房):注册到上海机房Server,并提供者数据同步到注册中心
    • 消费者(北京机房):注册到北京机房Server,并提供者数据同步到注册中心
    1.1.3、服务调用情况
    • 消费者(上海机房):优先调用上海机房提供者,当上海机房提供者下线时远程调用深圳机房提供者
    • 消费者(北京机房):北京区域没有提供者,会通过负债均衡计算调用深圳机房或上海机房服务提供者

    1.2、组建行为

    • Eureka Server:服务注册中心角度,提供服务注册和发现功能
    • Eureka Client提供者:是一个Client,扮演提供者角色,提供专业服务,向Server注册和更新自己的信息,也能从Server中获取到其他服务信息
    • Eureka Client消费者:是一个Client,扮演消费者角色,通过Server获取到其他服务信息,从而实现远程调用
    展开全文
  • 服务发现——Netflix Eureka 服务调用——Netflix Feign 熔断器——Netflix Hystrix 服务网关——Netflix Zuul 分布式配置——Spring Cloud Config 消息总线 —— Spring Cloud Bus 1.SpringBoot与Spring ...

    SpringCloud主要框架介绍:

    • 服务发现——Netflix Eureka
    • 服务调用——Netflix Feign 连接
    • 熔断器——Netflix Hystrix 连接
    • 服务网关——Netflix Zuul 连接
    • 分布式配置——Spring Cloud Config 连接
    • 消息总线 —— Spring Cloud Bus 连接连接

    高可用注册中心
    在微服务中,注册中心非常核心,可以实现服务治理,如果一旦注册出现故障的时候,可能会导致整个微服务无法访问,在这时候就需要对注册中心实现高可用集群模式(必须是集群的)。此外Consul、Zookeeper都可替换Eureka
    Swagger
    大公司中肯定会有专门文档服务器对接口文档进行更新。为了解决传统API接口文档维护的问题,为了方便进行测试后台Restful接口并实现动态的更新,因而引入Swagger接口工具
    1.SpringBoot与Spring Cloud版本的对照表
    Spring Boot 是 Spring 的一套快速配置脚手架,而Spring Cloud是一个基于Spring Boot实现的云应用开发工具。使用时得配套版本使用,相互对的上
    在这里插入图片描述
    2.Eureka组件介绍
    (1)Eureka包含两个组件:Eureka Server和Eureka Client。
    Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息。Eureka Server可通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。。
    Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也
    是一个内置的、使用轮询负载算法的负载均衡器。
    自我保护机制(独有):
    默认情况下Client客户端像服务端Server发送心跳包,在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,没收到心跳Eureka Server 90秒移除节点。但是短时间内丢失大量服务实例心跳,Eureka Server会开启自我保护机制不会删除该服务。
    为什么产生Eureka自我保护机制:
    Eureka Client正常运行但是与Eureka Server网络不通情况下,防止Eureka Server把Eureka Client服务删除
    集群注意点:
    Eureka通过相互注册进行集群,不能通过Nginx集群。网关可以通过Nginx集群
    3.搭建步骤
    (1)引入依赖 父工程pom.xml定义SpringCloud版本(Finchley):

        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Finchley.M9</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    

    (2)模块pom.xml引入eureka-server

        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
        </dependencies>
    

    (3)添加application.yml

    server: 
      port: 6868 #服务端口
    eureka:
      client:
        registerWithEureka: false #是否将自己注册到Eureka服务中,本身就是所有无需注册
        fetchRegistry: false #是否从Eureka中获取注册信息
        serviceUrl: #Eureka客户端与Eureka服务端进行交互的地址
          defaultZone: http://127.0.0.1:${server.port}/eureka/
    

    (4)编写启动类

    @SpringBootApplication
    @EnableEurekaServer
    public class EurekaServer {
        public static void main(String[] args) {
            SpringApplication.run(EurekaServer.class, args);
    }
    }
    

    (5)启动运行启动类,然后在浏览器地址栏输入 http://localhost:6868/ 查看运行效果

    服务注册
    (6)将其他微服务模块添加依赖

    <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    

    (7)修改每个微服务的application.yml,添加注册eureka服务的配置

    eureka:
      client:
        serviceUrl:
          defaultZone: http://127.0.0.1:6868/eureka/
      instance:
        prefer‐ip‐address: true
    

    (8)修改每个服务类的启动类,添加注解
    @EnableEurekaClient
    (9)启动测试:将每个微服务启动起来,发现eureka注册列表中可以看到这些微服务了

    4.Eureka高可用原理
    默认情况下Eureka是让服务注册中心,不注册自己。Eureka高可用实际上将自己作为服务向其他服务注册中心注册自己,这样就可以形成一组相互注册的服务注册中心,从而实现服务清单的互相同步,达到高可用效果。需要如下配置:

    ###因为该应用为注册中心,不会注册自己
        register-with-eureka: true
    ###不需要去注册中心上检索服务
        fetch-registry: true
    
    

    5.Eureka集群环境搭建
    (1)Eureka01配置

    ###服务端口号
    server:
      port: 8100
    ###eureka 基本信息配置
    spring: 
     application: 
      name: eureka-server
    eureka:
      instance:
        ###注册到eurekaip地址
        hostname: 127.0.0.1
      client:
        serviceUrl:
          defaultZone: http://127.0.0.1:8200/eureka/
    ###因为自己是为注册中心,不需要自己注册自己
        register-with-eureka: true
    ###因为自己是为注册中心,不需要检索服务
        fetch-registry: true
    
    

    (2)Eureka02配置

    ###服务端口号
    server:
      port: 8200
    ###eureka 基本信息配置
    spring: 
     application: 
      name: eureka-server
    eureka:
      instance:
        ###注册到eurekaip地址
        hostname: 127.0.0.1
      client:
        serviceUrl:
          defaultZone: http://127.0.0.1:8100/eureka/
    ###因为自己是为注册中心,不需要自己注册自己
        register-with-eureka: true
    ###因为自己是为注册中心,不需要检索服务
        fetch-registry: true
    
    

    (3)客户端集成Eureka集群

    server:
      port: 8000
    spring:
      application:
        name: app-itmayiedu-member
    #eureka:
    #  client:
    #    service-url:
    #      defaultZone: http://localhost:8100/eureka
    ###集群地址
    eureka:
      client:
        service-url:
               defaultZone: http://localhost:8100/eureka,http://localhost:8200/eureka    
        register-with-eureka: true
        fetch-registry: true
    
    

    (4)Maven配置

    <parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.0.1.RELEASE</version>
    	</parent>
    	<!-- 管理依赖 -->
    	<dependencyManagement>
    		<dependencies>
    			<dependency>
    				<groupId>org.springframework.cloud</groupId>
    				<artifactId>spring-cloud-dependencies</artifactId>
    				<version>Finchley.M7</version>
    				<type>pom</type>
    				<scope>import</scope>
    			</dependency>
    		</dependencies>
    	</dependencyManagement>
    	<dependencies>
    		<!--SpringCloud eureka-server -->
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    		</dependency>
    	</dependencies>
    	<!-- 注意: 这里必须要添加, 否者各种依赖有问题 -->
    	<repositories>
    		<repository>
    			<id>spring-milestones</id>
    			<name>Spring Milestones</name>
    			<url>https://repo.spring.io/libs-milestone</url>
    			<snapshots>
    				<enabled>false</enabled>
    			</snapshots>
    		</repository>
    	</repositories>
    
    

    6.Eureka源码分析

    展开全文
  • 我的博客,原文出处... #Eureka Server会定时(间隔值是eureka.server.eviction-interval-timer-in-ms,默认60s)进行检查,如果发现实例在在一定时间 #(此值由客户端设置的eureka.instance.lease-expiration-dur

    我的博客,原文出处http://www.deepinblog.com/eureka/175/

    我的博客地址,原文出处

    先直接给出配置让你尝鲜

    EurekaServer端配置

    eureka:
      server:
        #Eureka Server会定时(间隔值是eureka.server.eviction-interval-timer-in-ms,默认60s)进行检查,如果发现实例在在一定时间
        #(此值由客户端设置的eureka.instance.lease-expiration-duration-in-seconds定义,默认值为90s)内没有收到心跳,则会注销此实例。
        #我们这里配置每秒钟去检测一次,驱除失效的实例
        eviction-interval-timer-in-ms: 1000
        #关闭一级缓存,让客户端直接从二级缓存去读取,省去各缓存之间的同步的时间
        use-read-only-response-cache: false
    

    EurekaClient端(应用端)配置

    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka/
        # EurekaClient每隔多久从EurekaServer拉取一次服务列表,默认30秒,这里修改为2秒钟从注册中心拉取一次
        registry-fetch-interval-seconds: 2
      #租约期限以及续约期限的配置
      instance:
        #租约到期,服务失效时间,默认值90秒,服务超过90秒没有发生心跳,EurekaServer会将服务从列表移除
        #这里修改为6秒
        lease-expiration-duration-in-seconds: 6
        #租约续约间隔时间,默认30秒,这里修改为3秒钟
        lease-renewal-interval-in-seconds: 3
    
    #这里是Ribbon缓存实例列表的刷新间隔,默认30秒钟,这里修改为每秒钟刷新一次实例信息
    ribbon:
      ServerListRefreshInterval: 1000
    

    下面给你剖析原理

    Eureka服务端详解

    服务端缓存

    如图所示

    file

    服务注册到注册中心后,服务实例信息是存储在注册表中的,也就是内存中。但Eureka为了提高响应速度,在内部做了优化,加入了两层的缓存结构,将Client需要的实例信息,直接缓存起来,获取的时候 直接从缓存中拿数据然后响应给 Client。

    第一层缓存是readOnlyCacheMap,readOnlyCacheMap是采用ConcurrentHashMap来存储数据的,主要负责定时与readWriteCacheMap进行数据同步,默认同 步时间为 30 秒一次。

    第二层缓存是readWriteCacheMap,readWriteCacheMap采用Guava来实现缓存。缓存过期时间默认为180秒,当服务下线、过期、注册、状态变更等操作都会清除此缓存中的数据。

    第三层是数据存储层。

    Client获取服务实例数据时,会先从一级缓存中获取,如果一级缓存中不存在,再从二级缓存中获取,如果二级缓存也不存在,会触发缓存的加载,从存储层拉取数据到缓存中,然后再返回给 Client。

    Eureka 之所以设计二级缓存机制,也是为了提高 Eureka Server 的响应速度,缺点是缓存会导致 Client 获取不到最新的服务实例信息,然后导致无法快速发现新的服务和已下线的服务。

    了解了服务端的实现后,想要解决这个问题就变得很简单了,我们可以缩短只读缓存的更新时间 (eureka.server.response-cache-update-interval-ms)让服务发现变得更加及时,或者直接将只读缓 存关闭(eureka.server.use-read-only-response-cache=false),多级缓存也导致Client层面(数据一致性)很薄弱。

    客户端缓存

    客户端缓存主要分为两块内容,一块是 Eureka Client 缓存,一块是 Ribbon 缓存。

    Eureka Client缓存 ,EurekaClient负责跟EurekaServer进行交互,在EurekaClient中的 com.netflix.discovery.DiscoveryClient.initScheduledTasks() 方法中,初始化了一个 CacheRefreshThread 定时任务专⻔用来拉取 Eureka Server 的实例信息到本地。所以我们需要缩短这个定时拉取服务信息的时间间隔(此值在客户端配置eureka.client.registryFetchIntervalSeconds) 来快速发现新的服务

    Ribbon缓存,Ribbon会从EurekaClient中获取服务信息,ServerListUpdater是Ribbon中负责服务实例 更新的组件,默认的实现是PollingServerListUpdater,通过线程定时去更新实例信息。定时刷新的时 间间隔默认是30秒,当服务停止或者上线后,这边最快也需要30秒才能将实例信息更新成最新的。我们可以将这个时间调短一点,比如 3 秒。

    刷新间隔的参数是通过 getRefreshIntervalMs 方法来获取的,方法中的逻辑也是从 Ribbon的配置中进行取值的。所以我们需要缩短这个更新间隔(此值在客户端配置ribbon.ServerListRefreshInterval)来快速的更新Ribbon缓存实例列表

    将这些服务端缓存和客户端缓存的时间全部缩短后,跟默认的配置时间相比,快了很多。我们通过调整 参数的方式来尽量加快服务发现的速度,但是还是不能完全解决报错的问题,间隔时间设置为3秒,也还是会有间隔。所以我们一般都会开启重试功能,当路由的服务出现问题时,可以重试到另一个服务来 保证这次请求的成功。

    服务端缓存部分源码如下:

    /**
     *The class that is responsible for caching registry information that will be
     *queried by the clients.
     */
    public class ResponseCacheImpl implements ResponseCache {
        //一级缓存
      	private final ConcurrentMap<Key, Value> readOnlyCacheMap = new ConcurrentHashMap<Key, Value>();
        //二级缓存(Guava实现)
      	private final LoadingCache<Key, Value> readWriteCacheMap;
        //数据存储层
        private final AbstractInstanceRegistry registry;
    }
    
    

    客户端缓存更新部分源码如下:

    Eureka Client缓存刷新部分源码

        //Eureka Client缓存刷新部分源码
        /**
         * Initializes all scheduled tasks.
         * 在实例化com.netflix.discovery.DiscoveryClient被调用
         */
        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,
                          			//从哪个Eureka客户端拉取实例列表的间隔时间
                  							//通过eureka.client.registryFetchIntervalSeconds可配置
                                registryFetchIntervalSeconds,
                                TimeUnit.SECONDS,
                                expBackOffBound,
                          			//执行刷新的Runable定时任务
                                new CacheRefreshThread()
                        ),
                  			//从哪个Eureka客户端拉取实例列表的间隔时间
                  			//通过eureka.client.registryFetchIntervalSeconds可配置
                        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");
            }
        }	
    

    Ribbon缓存刷新部分源码

       //PollingServerListUpdater,Ribbon缓存刷新部分源码
       @Override
        public synchronized void start(final UpdateAction updateAction) {
            if (isActive.compareAndSet(false, true)) {
                final Runnable wrapperRunnable = new Runnable() {
                    @Override
                    public void run() {
                        if (!isActive.get()) {
                            if (scheduledFuture != null) {
                                scheduledFuture.cancel(true);
                            }
                            return;
                        }
                        try {
                            updateAction.doUpdate();
                            lastUpdated = System.currentTimeMillis();
                        } catch (Exception e) {
                            logger.warn("Failed one update cycle", e);
                        }
                    }
                };
    
                scheduledFuture = getRefreshExecutor().scheduleWithFixedDelay(
                        wrapperRunnable,
                        initialDelayMs,
                        refreshIntervalMs,//默认30秒,通过ribbon.ServerListRefreshInterval来配置更小的值来快速更新Ribbon实例缓存
                        TimeUnit.MILLISECONDS
                );
            } else {
                logger.info("Already active, no-op");
            }
        }
    

    服务下线

    1. 当服务正常关闭操作时,会发送服务下线的REST请求给EurekaServer。
    2. 服务中心接受到请求后,将该服务置为下线状态

    失效剔除

    Eureka Server 中会有定时任务去检测失效的服务,将服务实例信息从注册表中移除,也可以将这个失效检测的时间缩短,这样服务下线后就能够及时从注册表中清除。

    1. Eureka Server会定时(间隔值是eureka.server.eviction-interval-timer-in-ms,默认60s)进行检查,
      如果发现实例在在一定时间
      (此值由客户端设置的eureka.instance.lease-expiration-duration-in-seconds定义,默认值为90s)内没有收到心跳,
      则会注销此实例。

    Eureka客户端

    服务提供者(也是Eureka客户端)

    • 服务提供者(也是Eureka客户端)要向EurekaServer注册服务,并完成服务续约等工作
    • 服务注册详解(服务提供者)
      1. 当我们导入了eureka-client依赖坐标,配置Eureka服务注册中心地址
      2. 服务在启动时会向注册中心发起注册请求,携带服务元数据信息
      3. Eureka注册中心会把服务的信息保存在Map中。
    • 服务续约详解(服务提供者)
      1. 服务每隔30秒会向注册中心续约(心跳)一次(也称为报活),如果没有续约,租约在90秒后到期,然后服务会被失效。
        每隔30秒的续约操作我们称之为心跳检测往往不需要我们调整这两个配置
    #向Eureka服务中心集群注册服务 
    eureka:
      #租约期限以及续约期限的配置
      instance:
        #租约到期,服务失效时间,默认值90秒,服务超过90秒没有发生心跳,EurekaServer会将服务从列表移除
        #这里修改为6秒
        lease-expiration-duration-in-seconds: 6
        #租约续约间隔时间,默认30秒,这里修改为3秒钟
        lease-renewal-interval-in-seconds: 3
    

    服务消费者(也是Eureka客户端)

    • 服务消费者每隔30秒服务会从注册中心中拉取一份服务列表,这个时间可以通过配置修改。往往不需要我们调整
      1. 服务消费者启动时,从 EurekaServer服务列表获取只读备份,缓存到本地;
      2. 默认每隔30秒,会重新获取并更新数据;
      3. 每隔30秒的时间可以通过配置eureka.client.registry-fetch-interval-seconds修改,如下。
    #向Eureka服务中心集群注册服务 
    eureka:
        client:
          # EurekaClient每隔多久从EurekaServer拉取一次服务列表,默认30秒,这里修改为2秒钟从注册中心拉取一次
        	registry-fetch-interval-seconds: 2
    

    客户端缓存见Eureka服务端详情章节

    至此您应该明白Eureka的服务发现机制了吧

    最后再说说Eureka自我保护机制

    服务提供者 —> 注册中心

    • 定期的续约(服务提供者和注册中心通信),假如服务提供者和注册中心之间的网络有点问题,
      不代表 服务提供者不可用,不代表服务消费者无法访问服务提供者,所以有自我保护的机制
    • 如果在15分钟内超过85%的客户端节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,
      Eureka Server自动进入自我保护机制。
    • 为什么会有自我保护机制?
      • 默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳, Eureka Server将会移除该实例。
        但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,
        所以引入了自我保护机制。

    服务中心⻚面会显示如下提示信息
    file

    当处于自我保护模式时

    1. 不会剔除任何服务实例(可能是服务提供者和EurekaServer之间网络问题),保证了大多数服务依 然可用
    2. Eureka Server仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上,保证当前节点依然可用,
      当网络稳定时,当前Eureka Server新的注册信息会被同步到其它节点中。
    3. 在Eureka Server工程中通过eureka.server.enable-self-preservation配置可用关停自我保护,默认值是打开
    eureka:
      server:
        enable-self-preservation: false # 关闭自我保护模式(缺省为打开)
    

    如果有大批量的集群且存在网络分区,强烈建议开启自我保护机制

    展开全文
  • Eureka服务发现原理 eureka:多个eureka server组成一个高可用的eureka集群,集群内的eureka节点之间通过同步复制的方式更新注册信息,保持服务注册信息的一致性。 Application Service: 是一个服务的提供者,为...

    Eureka服务发现原理

    在这里插入图片描述

    • eureka:多个eureka server组成一个高可用的eureka集群,集群内的eureka节点之间通过同步复制的方式更新注册信息,保持服务注册信息的一致性。
    • Application Service: 是一个服务的提供者,为其他服务提供特定的业务服务;它也是一个eureka client,会将自己注册到eureka server中,同时获取注册表缓存在本地。
    • Application Client:服务调用者,会去调用application service提供的服务,通过http api 的方式调用。application client将自己注册到eureka server中,同时获取注册表信息,从信息表中找到所需的服务发起远程调用。
    • Replicate:eureka server之间注册表信息的同步机制,使得eureka集群中不同注册表中服务实例信息保持一致。

    Eureka注册原理解析:

    Eureka Client

    Eureka Client 将很多与Eureka Server的交互工作隐藏,开发人员是不用管这部分工作的。Eureka Client工作流程:

    在这里插入图片描述

    图片来自SpringCloud微服务架构进阶

    client注册的流程其实很简单,无非就是以下几个步骤:

    • 先读eureka server的配置信息,从而知道eureka server在哪,以便后面进行注册
    • 接着再读取自己的配置信息,然后将自己的信息封装在InstanceInfo实例中,等下将实例发送到eureka server中
    • 通过上面步骤已经知道eureka server的地址了,此时先把注册拉取到本地缓存起来
    • 将上面封装的InstanceInfo实例发送到eureka server进行注册,然后初始化心跳检测以及缓存刷新(这些都是通过开启后台线程完成的)
    • 再次拉取注册表更新本地注册表信息


    InstanceInfo实例部分代码:可以看到几个主要的信息比如:instanceId、ipAddr、port、appName、appGroupName、lastUpdatedTimestamp等

    
    @ProvidedBy(EurekaConfigBasedInstanceInfoProvider.class)
    @Serializer("com.netflix.discovery.converters.EntityBodyConverter")
    @XStreamAlias("instance")
    @JsonRootName("instance")
    public class InstanceInfo {
        private static final String VERSION_UNKNOWN = "unknown";
        private static final Logger logger = LoggerFactory.getLogger(InstanceInfo.class);
        public static final int DEFAULT_PORT = 7001;
        public static final int DEFAULT_SECURE_PORT = 7002;
        public static final int DEFAULT_COUNTRY_ID = 1;
        private volatile String instanceId;
        private volatile String appName;
        @Auto
        private volatile String appGroupName;
        private volatile String ipAddr;
        private static final String SID_DEFAULT = "na";
        /** @deprecated */
        @Deprecated
        private volatile String sid;
        private volatile int port;
        private volatile int securePort;
        ...
        @Auto
        private volatile Long lastUpdatedTimestamp;
        
        ...
        }
    
    Eureka Server

    Eureka Server是一个开箱即用的服务注册中心,开发人员只需要导入相关的依赖即可,它提供以下功能:

    • 服务注册
    • 接受eureka client发送过来的心跳检测
    • 服务剔除(当一个client心跳超时)
    • 服务下线(client请求关闭)
    • 集群同步(不同eureka server中注册表信息同步)
    • 获取注册表中服务实例信息(每个eureka server同时也是一个eureka client,eureka server可以把自己注册到eureka集群中)

    服务注册时eureka client会将服务实例InstanceInfo发送到eureka server。

    • 服务实例通过ConcurrentHashMap保存在内存中,在服务注册的过程中会先获取一个锁,防止其他线程对registry注册表进行数据操作,避免数据不一致。
      eureka server接收到client发送过来的InstanceInfo实例时,会先根据唯一的instanceId检查注册表中是否已存在该实例。
    • 如果没有该实例,说明这是一次新的注册服务,server会将InstanceInfo信息保存到注册表中
    • 如果存在该实例,说明这是一次心跳检测或者实例信息更新操作,会比较lastUpdatedTimestamp字段保留最新的InstanceInfo实例信息。
    集群同步

    为了保持注册表的一致性,集群中的eureka server需要一个同步机制来维护注册表。

    集群同步分为两个部分,我个人将其理解为pull和push:

    • pull:eureka server启动时从集群中其他节点pull注册表信息进行本地注册表的初始化
    • push:eureka server对本地的注册表进行更新操作后(包括增删改)会将操作push(也就是同步)到其他节点中

    集群模式下的eureka server,多个eureka server之间互相注册并同步注册表信息,即使集群中个别节点出现故障或宕机,集群还是能够稳定提供服务。

    缺陷:Eureka Server集群的节点之间是通过http的方式进行同步的,网络存在不可靠性,为了保持高可用性,eureka server 牺牲了数据一致性,eureka server不满足 CAP找那个C(数据一致性)。

    展开全文
  • Eureka工作原理

    万次阅读 多人点赞 2019-07-03 10:46:48
    Eureka 工作原理 上节内容为大家介绍了,注册中心 Eureka 产品的使用,以及如何利用 Eureka 搭建单台和集群的注册中心。这节课我们来继续学习 Eureka,了解它的相关概念、工作流程机制等。 Eureka 作为 Spring Cloud...
  • Eureka服务发现注册详解

    万次阅读 2019-06-25 16:48:38
    Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以...
  • Eureka服务注册原理

    2020-03-02 18:20:51
    原理图 相关分析 为什么不在服务注册表中进行注册和拉取 读写操作的分离
  • 在一个超大型的系统中,有100K个Client,也就是10万个服务,这么多个服务定时向Eureka注册中心请求发现服务时,应该怎样处理? 首先,我们可以让多个Eureka相互注册构成集群,多个服务向集群内的不同Eureka定时请求...
  • 在前面的文章介绍了,如何使用服务注册发现组件: Eureka,并给出使用示例。本文在此基础上,将会讲解 Eureka 客户端实现的内幕,结合源码深入实现的细节,知其所以然。客户端需要重点关注以下几点: 从Eureka ...
  • Eureka 服务注册与发现原理剖析

    千次阅读 2020-03-27 15:33:38
    Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务。主要用于定位运行在 AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以...
  • spring-cloud-eureka 发现服务实现原理 注册原理 本质是@EnableEurekaServer中导入了一个EurekaServerConfiguration的配置。其中InstanceRegistry的配置将实现对客户端的注册,将客户端存入注册队列...
  • Eureka支持高可用的配置,当集群中有分片出现故障时,Eureka就会转入自动保护模式,它允许分片故障期间继续提供服务发现和注册,当故障分片恢复正常时,集群中其他分片会把他们的状态再次同步回来。 客户端组件...
  • 第二章Eureka注册发现原理解析笔记

    千次阅读 2020-03-11 21:25:10
    一、EurekaClient运行流程分析 EurekaClient为了简化开发人员的工作量,将很多与EurekaServer交互的工作隐藏起来,自主完成,具体完成的工作如下,代码见spring-cloud-netflix-eureka-client-2.0.0.RELEASE.jar。 ...
  • Eureka 是 Netflix 出品的用于实现服务注册和发现的工具。 Spring Cloud 集成了 Eureka,并提供了开箱即用的支持。其中, Eureka 又可细分为 Eureka Server 和 Eureka Client。 1.基本原理 上图是来自eureka的...
  • Eureka服务注册原理及高可用集群配置  基本原理 上图是来自eureka的官方架构图,这是基于集群配置的eureka;  - 处于不同节点的eureka通过Replicate进行数据同步  - Application Service为服务提供者  - ...
  • Eureka 服务注册与发现

    2020-12-19 23:27:49
    Eureka 服务注册与发现
  • 在介绍工作原来之前,我们先来了解一下Eureka的核心概念。 核心概念 服务注册调用示意图,服务提供者和服务的消费者,本质上也是 Eureka Client 角色。...服务提供者启动时,会通过eureka client向eurek...
  • 文章目录RouteDefinition 定义服务发现构建RouteDefinition根据服务发现规则转发请求匹配 RouteRoute 转发 RouteDefinition 定义 在SpringCloudGateway内,路由转发规则被定义为Route,Route通过...
  • 目录 Netflix Eureka 简介 spring-cloud-netflix简介 Eureka 原理 服务发现 ...1、Eureka 是 Netflix 公司开发的服务发现框架,Spring Cloud 对它提供了支持,将它集成在了自己的spring-cl...
  • Eureka服务注册中心的原理 故障转移: Eureka内存实际上是有俩级缓存,一个是只读缓存,一个是可以更改的缓存。当注册表更新后,会立马同步到ReadWrite缓存,ReadWrite缓存会定时同步到ReadOnly缓存,而服务发现则...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,141
精华内容 7,656
关键字:

eureka服务发现原理