什么是DiveintoEureka

这篇文章将为大家详细讲解有关什么是Dive into  Eureka,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

站在用户的角度思考问题,与客户深入沟通,找到云霄网站设计与云霄网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都做网站、网站设计、外贸营销网站建设、企业官网、英文网站、手机端网站、网站推广、申请域名、网络空间、企业邮箱。业务覆盖云霄地区。

1. What is Eureka?

其官方文档中对自己的定义是:

Eureka is a REST (Representational State Transfer) based service that is primarily used in the AWS cloud for locating services for the purpose of load balancing and failover of middle-tier servers. We call this service, the Eureka Server. Eureka also comes with a Java-based client component,the Eureka Client, which makes interactions with the service much easier. The client also has a built-in load balancer that does basic round-robin load balancing.

简单来说Eureka就是Netflix开源的一款提供服务注册和发现的产品,并且提供了相应的Java客户端。

2. Why Eureka?

那么为什么我们在项目中使用了Eureka呢?我大致总结了一下,有以下几方面的原因:

  • 它提供了完整的Service Registry和Service Discovery实现

    • 首先是提供了完整的实现,并且也经受住了Netflix自己的生产环境考验,相对使用起来会比较省心。

  • 和Spring Cloud无缝集成

    • 我们的项目本身就使用了Spring Cloud和Spring Boot,同时Spring Cloud还有一套非常完善的开源代码来整合Eureka,所以使用起来非常方便。

    • 另外,Eureka还支持在我们应用自身的容器中启动,也就是说我们的应用启动完之后,既充当了Eureka的角色,同时也是服务的提供者。这样就极大的提高了服务的可用性。

  • Open Source

    • 最后一点是开源,由于代码是开源的,所以非常便于我们了解它的实现原理和排查问题。

3. Dive into Eureka

相信大家看到这里,已经对Eureka有了一个初步的认识,接下来我们就来深入了解下它吧~

3.1 Overview

3.1.1 Basic Architecture

什么是Dive into  Eureka

上图简要描述了Eureka的基本架构,由3个角色组成:

  1. Eureka Server

    • 提供服务注册和发现

  2. Service Provider

    • 服务提供方

    • 将自身服务注册到Eureka,从而使服务消费方能够找到

  3. Service Consumer

    • 服务消费方

    • 从Eureka获取注册服务列表,从而能够消费服务

需要注意的是,上图中的3个角色都是逻辑角色。在实际运行中,这几个角色甚至可以是同一个实例,比如在我们项目中,Eureka Server和Service Provider就是同一个JVM进程。

3.1.2 More in depth

architecture-detail

上图更进一步的展示了3个角色之间的交互。

  1. Service Provider会向Eureka Server做Register(服务注册)、Renew(服务续约)、Cancel(服务下线)等操作。

  2. Eureka Server之间会做注册服务的同步,从而保证状态一致

  3. Service Consumer会向Eureka Server获取注册服务列表,并消费服务

3.2 Demo

为了给大家一个更直观的印象,我们可以通过一个简单的demo来实际运行一下,从而对Eureka有更好的了解。

3.2.1 Git Repository

Git仓库:git@github.com:nobodyiam/spring-cloud-in-action.git

这个项目使用了Spring Cloud相关类库,包括:

  • Spring Cloud Config

  • Spring Cloud Eureka (Netflix)

3.2.2 准备工作

Demo项目使用了Spring Cloud Config做配置,所以第一步先在本地启动Config Server。

由于项目基于Spring Boot开发,所以直接运行com.nobodyiam.spring.cloud.in.action.config.ConfigServerApplication即可。

3.2.3 Eureka Server Demo

Eureka Server的Demo模块名是:eureka-server

3.2.3.1 Maven依赖

eureka-server是一个基于Spring Boot的Web应用,我们首先需要做的就是在pom中引入Spring Cloud Eureka Server的依赖。


    org.springframework.cloud
    spring-cloud-starter-eureka-server
    1.1.0.RC2
3.2.3.2 启用Eureka Server

启用Eureka Server非常简单,只需要加上@EnableEurekaServer即可。

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

做完以上配置后,启动应用,Eureka Server就开始工作了!

启动完,打开http://localhost:8761就能看到启动成功的画面了。

什么是Dive into  Eureka

3.2.4 Service Provider and Service Consumer Demo

Service Provider的Demo模块名是:reservation-service

Service Consumer的Demo模块名是:reservation-client

3.2.4.1 Maven依赖

reservation-servicereservation-client都是基于Spring Boot的Web应用,我们首先需要做的就是在pom中引入Spring Cloud Eureka的依赖。


    org.springframework.cloud
    spring-cloud-starter-eureka
    1.1.0.RC2
3.2.4.2 启动Service Provider

启用Service Provider非常简单,只需要加上@EnableDiscoveryClient即可。

@EnableDiscoveryClient
@SpringBootApplication
public class ReservationServiceApplication {
  public static void main(String[] args) {
    new SpringApplicationBuilder(ReservationServiceApplication.class)
            .run(args);
  }
}

做完以上配置后,启动应用,Server Provider就开始工作了!

启动完,打开http://localhost:8761就能看到服务已经注册到Eureka Server了。

eureka-server-with-service-provider

3.2.4.3 启动Service Consumer

启动Service Consumer其实和Service Provider一样,因为本质上Eureka提供的客户端是不区分Provider和Consumer的,一般情况下,Provider同时也会是Consumer。

@EnableDiscoveryClient
@SpringBootApplication
public class ReservationClientApplication {
  @Bean
  CommandLineRunner runner(DiscoveryClient dc) {
    return args -> {
      dc.getInstances("reservation-service")
              .forEach(si -> System.out.println(String.format(
                      "Found %s %s:%s", si.getServiceId(), si.getHost(), si.getPort())));
    };
  }
  public static void main(String[] args) {
    SpringApplication.run(ReservationClientApplication.class, args);
  }
}

上述代码中通过dc.getInstances("reservation-service")就能获取到当前所有注册的reservation-service服务。

3.3 Eureka Server实现细节

看了前面的demo,我们已经初步领略到了Spring Cloud和Eureka的强大之处,通过短短几行配置就实现了服务注册和发现!

相信大家一定想了解Eureka是如何实现的吧,所以接下来我们继续Dive!首先来看下Eureka Server的几个对外接口实现。

3.3.1 Register

首先来看Register(服务注册),这个接口会在Service Provider启动时被调用来实现服务注册。同时,当Service Provider的服务状态发生变化时(如自身检测认为Down的时候),也会调用来更新服务状态。

接口实现比较简单,如下图所示。

  1. ApplicationResource类接收Http服务请求,调用PeerAwareInstanceRegistryImplregister方法

  2. PeerAwareInstanceRegistryImpl完成服务注册后,调用replicateToPeers向其它Eureka Server节点(Peer)做状态同步

什么是Dive into  Eureka

注册的服务列表保存在一个嵌套的hash map中:

  • 第一层hash map的key是app name,也就是应用名字

  • 第二层hash map的key是instance name,也就是实例名字

以3.2.4.2中的截图为例,RESERVATION-SERVICE就是app name,jason-mbp.lan:reservation-service:8000就是instance name。

Hash map定义如下:

private final ConcurrentHashMap>> registry =
new ConcurrentHashMap>>();
3.3.2 Renew

Renew(服务续约)操作由Service Provider定期调用,类似于heartbeat。主要是用来告诉Eureka Server Service Provider还活着,避免服务被剔除掉。接口实现如下图所示。

可以看到,接口实现方式和register基本一致:首先更新自身状态,再同步到其它Peer。

什么是Dive into  Eureka

3.3.4 Fetch Registries

Fetch Registries由Service Consumer调用,用来获取Eureka Server上注册的服务。

为了提高性能,服务列表在Eureka Server会缓存一份,同时每30秒更新一次。

什么是Dive into  Eureka

3.3.6 How Peer Replicates

在前面的Register、Renew、Cancel接口实现中,我们看到了都会有replicateToPeers操作,这个就是用来做Peer之间的状态同步。

通过这种方式,Service Provider只需要通知到任意一个Eureka Server后就能保证状态会在所有的Eureka Server中得到更新。

具体实现方式其实很简单,就是接收到Service Provider请求的Eureka Server,把请求再次转发到其它的Eureka Server,调用同样的接口,传入同样的参数,除了会在header中标记isReplication=true,从而避免重复的replicate。

3.3.7 How Peer Nodes are Discovered

那大家可能会有疑问,Eureka Server是怎么知道有多少Peer的呢?

Eureka Server在启动后会调用EurekaClientConfig.getEurekaServerServiceUrls来获取所有的Peer节点,并且会定期更新。定期更新频率可以通过eureka.server.peerEurekaNodesUpdateIntervalMs配置。

这个方法的默认实现是从配置文件读取,所以如果Eureka Server节点相对固定的话,可以通过在配置文件中配置来实现。

如果希望能更灵活的控制Eureka Server节点,比如动态扩容/缩容,那么可以override getEurekaServerServiceUrls方法,提供自己的实现,比如我们的项目中会通过数据库读取Eureka Server列表。

具体实现如下图所示:

什么是Dive into  Eureka

3.4 Service Provider实现细节

现在来看下Service Provider的实现细节,主要就是Register、Renew、Cancel这3个操作。

3.4.1 Register

Service Provider要对外提供服务,一个很重要的步骤就是把自己注册到Eureka Server上。

这部分的实现比较简单,只需要在启动时和实例状态变化时调用Eureka Server的接口注册即可。需要注意的是,需要确保配置eureka.client.registerWithEureka=true。

什么是Dive into  Eureka

3.4.3 Cancel

在Service Provider服务shut down的时候,需要及时通知Eureka Server把自己剔除,从而避免客户端调用已经下线的服务。

逻辑本身比较简单,通过对方法标记@PreDestroy,从而在服务shut down的时候会被触发。

什么是Dive into  Eureka

3.5 Service Consumer实现细节

Service Consumer这块的实现相对就简单一些,因为它只涉及到从Eureka Server获取服务列表和更新服务列表。

3.5.1 Fetch Service Registries

Service Consumer在启动时会从Eureka Server获取所有服务列表,并在本地缓存。需要注意的是,需要确保配置eureka.client.shouldFetchRegistry=true。

什么是Dive into  Eureka

3.5.3 How Eureka Servers are Discovered

Service Consumer和Service Provider一样,也有一个如何知道Eureka Server地址的问题。

其实由于Service Consumer和Service Provider本质上使用的是同一个Eureka客户端,所以这部分逻辑是一样的,这里就不再赘述了。

关于什么是Dive into  Eureka就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。


网站名称:什么是DiveintoEureka
网页链接:http://myzitong.com/article/pohjgd.html