Spring Cloud Eureka

服务治理

服务治理是微服务架构中最为核心和基础的模块,它主要用来实现各个微服务实例的自动化注册和发现。
在微服务架构体系中,每个服务都是相对独立的,包括其部署、扩展和升级,都不应和其他服务产生耦合。但是微服务之间是无法避免业务关系的,也就是说服务之间需要互相调用。对于Restful接口而言,服务A要调用服务B的接口,必须知道具体的url,这样服务A就必须与服务B的部署位置产生依赖关系。另一方面,为了实现服务B的高可用,不论采用服务端负载均衡还是客户端负载均衡,都需要手工维护服务B的实例列表。
为了解决微服务架构中的服务实例维护问题,产生了大量的服务治理框架和产品。服务治理的功能主要有一下几点:

  • 对开发新服务和升级现有服务的计划管理服务的生命周期;
  • 确保升级服务不会影响目前的服务消费者制定方针来限制服务行为;
  • 制定所有服务都要遵从的规则,确保服务的一致性监控服务的性能;
  • 由于服务组合,服务停机和性能低下的后果是严重的。通过监控服务的性能和可用性,当问题出现的时候能马上采取应对措施;
  • 管理由谁来调用服务、怎样调用服务

服务注册

在服务治理框架中,通常需要一个注册中心。每个服务想注册中心登记自己提供的服务,将服务的位置、调用方式等告知注册中心。注册中心会按服务名分类组织分类清单。另外服务注册中心还需定时监控清单中的服务的健康状态,及时剔除不可用的实例。

服务发现

在服务治理框架下,服务之间的调用不在依赖于服务的具体位置(如ip:port),而是通过服务名调用,从而将服务的部署从微服务的调用中解决关联。通过服务名调用,还可以方便地实现负载均衡。由于服务注册,我们有一份清单可以找到某个服务的具体实例,若是服务不止一个实例,我们可以很方便地动态选择服务的实例进行调用,从而实现负载均衡。这也有利于服务的横向扩展,实现高可用。

Spring Cloud Eureka

Netflix Eureka是Netflix开发的一套基于jvm和restful的服务治理框架。其服务端是用java语言编写,主要适用于java实现的分布式系统。但是其通信协议为基于http的restful,所以客户端理论上用什么语言实现都可以。这也是微服务的一大特点,服务可以根据自身特点选用相应的语言或平台实现,不必局限于同一的平台。

搭建服务注册中心

Spring Cloud中的微服务就是一个个Spring Boot应用程序,服务注册中心也不例外。按上篇文章的步骤,搭建一个spring boot模块。

修改build.gradle,引入spring-cloud-starter-eureka-server

group 'com.zhuangqf.demo'
version '1.0-SNAPSHOT'

dependencies {
    compile "org.springframework.cloud:spring-cloud-starter-eureka-server"
    compile "org.springframework.boot:spring-boot-starter-web"
}

添加Application启动类,通过EnableEurekaServer注解启动一个注册服务中心。

@EnableEurekaServer
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }

}

添加application.yml:

spring:
  application:
    name: eureka-server
server:
  port: 9000

eureka:
  instance:
    instance-id: ${spring.cloud.client.ipAddress}:${server.port}
    hostname: ${spring.cloud.client.ipAddress}
  client:
    fetch-registry: false
    register-with-eureka: false
    serviceUrl.defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

先重点关注eureka.client配置:

  • eureka.client.fetch-registry 默认为true,是否拉取注册的实例信息,注册中心不需要远程调用实例,所以不需要检索服务,设为false。
  • eureka.client.register-with-eureka 对於单注册中心,不需要向自己注册
  • eureka.client.serviceUrl.defaultZone 注册中心地址

接入客户端

注册中心已经跑起来了,那么怎么让我们的服务注册到注册中心呢?让我们对之前写过的example模块做一些改造。

在example模块的build.gradle中添加依赖

compile "org.springframework.cloud:spring-cloud-starter-eureka"

相应的,在Application类加一个注解:

@SpringBootApplication
@EnableDiscoveryClient
public class Application {

    public static void main(String[] arg) {
        SpringApplication.run(Application.class,arg);
    }

}

接着,在application.yml中指定注册地址:

eureka:
  instance:
    instance-id: ${spring.cloud.client.ipAddress}:${server.port}
    hostname: ${spring.cloud.client.ipAddress}
  client:
    serviceUrl.defaultZone: http://localhost:9000/eureka/

高可用注册中心

高可用集群是指以减少服务中断时间为目的的服务器集群技术。它通过保护用户的业务程序对外不间断提供的服务,把因软件/硬件/人为造成的故障对业务的影响降低到最小程度。

在微服务架构系统中,故障是不可能避免的。Eureka Server的设计一开始就考虑了高可用的问题,在Eureka的服务治理设计中,所有节点既是服务提供方,又是服务消费方,服务注册中心也不例外。

Eureka Server的高可用实际上是将自己作为服务向其他服务注册中心注册自己,这样就可以形成一组互相注册的服务注册中心。注册中心之间会共享彼此的服务清单,注册中心可以在一个zone中,也可以按业务或服务的部署位置分为多个zone。

在这里,我们先简单实现同一个zone的两个注册中心,让它们彼此注册,实现高可用。

首先,在eureka-server的application.yml中增加以下配置

-- peer1
server.port: 9001

eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    serviceUrl.defaultZone: http://${eureka.instance.hostname}:9002/eureka

-- peer2
server.port: 9002

eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    serviceUrl.defaultZone: http://${eureka.instance.hostname}:9001/eureka

peer1和peer2是可选的两组配置,在配置中,我们从彼此注册到对方。

分别启动peer1和peer2

启动example

修改example的注册服务器地址:


此时,peer1或者peer2有一个出现故障在短时间内不会对系统的业务有太大的影响,因为另一个注册中心可以临时性承接所有的流量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章