认识Eureka

179 阅读4分钟

本文讲解了服务发现机制在分布式系统中存在的必要性,并对Eureka做了入门介绍,演示了如何下载Eureka源码、编译项目,为进一步学习源码做好环境准备。

一 为什么需要服务发现机制

1.1 没有服务发现机制

使用微服务构建的分布式系统,服务间通过网络交互。当服务A调用服务B的接口时,我们称服务A为消费者,服务B为提供者。

服务间调用时,服务消费者如何获得服务提供者的地址呢?如下面示例中硬编码吗?

User user = restTemplate.getForObject("http://168.10.37.121:8091/user/" + id, User.class)

或者将服务提供者配置到yaml中,使用LoadBalancerClient实现负责均衡。

# 消费者配置服务提供者
user-center:
  ribbon:
    listOfServers: 168.10.37.121:8091,168.10.37.25:8091
ServiceInstance serviceInstance = loadBalancerClient.choose("user-center");  
String uri = "/user/" + 1;  
String address = serviceInstance.getHost() + ":" + serviceInstance.getPort(); 
User user = restTemplate.getForObject("http://" + address + uri, User.class);

但是,以上方式都有很大局限:

  • 如果服务提供者的网络地址发生变化,将不得不修改服务消费者的代码或配置,重新发布;
  • 服务提供者往往集群部署,当某些节点宕机了,服务消费者无法感知,继续访问已宕机节点而报错。
  • 服务提供者动态增减节点时,硬编码时无法适应。

1.2 服务发现机制

硬编码维护服务提供者的网络地址,存在很多问题。

我们需要一套服务发现机制:即消费者获取服务提供者的网络地址,同时能适应提供者动态扩容缩容。

这就是独立于业务应用的服务发现组件

  • 各服务启动时,将自己的网络地址等信息注册到发现组件,保存到注册表中;
  • 消费者从发现组组件中查询服务提供者的网络地址,进而发起调用;
  • 各服务定期向发现组件上报节点状态(up或down),如通过周期性心跳,对于长时间没有上报的节点,将其从注册表中剔除(认为它已下线) image.png 可见,组件涉及服务端、客户端的双向交互。客户端即业务应用,主动发起注册、心跳、查询请求。

SpringCloud提供了多种服务发现组件的支持,如Eureka、Consul和Zookeeper等。

二 Eureka引入

Eureka是美国Netflix公司开源的服务发现组件,本身是一个基于RESTful (Representational State Transfer)的服务。它包含Server和Client两部分。主要用于AWS云中,实现服务发现、负载平衡和故障转移功能。

2.1 一些概念

  • Register:服务注册
    当Eureka客户端向Eureka Server发起注册,提供自身的元数据,比如IP地址、端口,运行状况等;
  • Renew:服务续约
    Eureka客户会每隔30秒(默认)发送一次心跳来续约。 通过续约来告知Eureka Server该Eureka客户端仍然存在线。
  • Fetch Registries:获取注册列表信息
    Eureka客户端从服务器获取注册表信息,并将其缓存在本地。客户端会使用注册表查找其他服务地址,从而进行远程调用。该注册列表信息定期(每30秒钟)更新一次。在默认的情况下Eureka客户端使用压缩JSON格式来获取注册列表的信息。
  • Cancel:服务下线
    Eureka客户端在程序关闭时向Eureka服务器发送取消请求。 发送请求后,该客户端实例信息将从服务器的实例注册表中删除。
  • Eviction 服务剔除
    在默认的情况下,当Eureka客户端连续90秒没有向Eureka服务器发送服务续约,即心跳,Eureka服务器会将该服务实例从服务注册列表删除。

2.2 架构设计

image.png 图中有2个角色,即Eureka Server和Eureka Client:

  • Eureka Client又分为Applicaton Service和Application Client,即服务提供者和服务消费者。
  • us-east-1c、us-east-1d等都是Available Zone(可理解为机房);每个机房都有一个Eureka Server,多个机房一同构成Eureka集群。
  • Eureka集群中,各节点是互联的,进行注册表同步。

us-east-1是Region名。Region表示AWS元中的地址位置,每个Region有多个Available Zone。在非AWS环境下,可以将Available Zone理解为机房。

三 eureka源码导入

3.1 拉取源码

从github上拉取源码,用idea打开项目。eureka使用gradle构建项目,idea将主动下载gradle-3.0-bin.zip。

git clone https://github.com/Netflix/eureka.git
git checkout v1.7.x

3.2 下载gradle

先配置本地gradle仓库地址。 image.png 在gradle/wrapper/gradle-wrapper.properties中,distributionUrl指向国外网站。如果下载速度很慢的话,可以替换为国内镜像地址。

镜像:mirrors.cloud.tencent.com/gradle/grad… image.png

3.3 配置依赖下载源

等idea自动下载完gradle,进入gradle的init.d文件夹(在Gradle user home绑定的目录下)。 image.png 创建一个init.gradle文件,内容如下,使用阿里云的Maven仓地址:

allprojects {
    repositories { 
        mavenLocal() 
        maven { name "Alibaba" ; url "https://maven.aliyun.com/repository/public" } 
        maven { name "Bstek" ; url "https://nexus.bsdn.org/content/groups/public/" } 
        mavenCentral()
    }
    buildscript {
        repositories { 
            maven { name "Alibaba" ; url 'https://maven.aliyun.com/repository/public' } 
            maven { name "Bstek" ; url 'https://nexus.bsdn.org/content/groups/public/' } 
            maven { name "M2" ; url 'https://plugins.gradle.org/m2/' }
        }
    }
}

3.4 加载项目

点击reload按钮,idea将自动下载依赖,需要一点时间。 image.png 项目构建完成,可以看到依赖的包都被引入了。 image.png