前言

在分布式系统领域有个著名的CAP定理:

C——数据一致性;

A——服务可用性;

P——服务对网络分区故障的容错性。

这三个特性在任何分布式系统中不能同时满足,最多同时满足两个。

Zookeeper是著名Hadoop的一个子项目,很多场景下Zookeeper也作为Service发现服务解决方案。Zookeeper保证的是CP,即任何时刻对Zookeeper的访问请求能得到一致的数据结果,同时系统对网络分割具备容错性,但是它不能保证每次服务请求的可用性。

而Spring Cloud Netflix在设计Eureka时遵守的就是AP原则。因为对于服务消费者来说,能消费才是最重要的——拿到可能不正确的服务实例信息后尝试消费一下,也好过因为无法获取实例信息而不去消费。所以,对于服务发现而言,可用性比数据一致性更加重要——AP胜过CP。

1、服务注册与服务发现

服务治理是微服务架构中最为核心和基础的模块,主要为各个微服务实例提供自动化注册与发现功能。

服务注册:服务治理框架会构建一个注册中心,每个服务向注册中心注册登记自己提供的服务,将服务名、主机、端口号、版本号、通信协议等告知注册中心,注册中心按服务名分类组织成一个服务清单。

例如:

有三个提供订单服务的实例分别运行在 192.168.0.100:8081、192.168.0.101:8082、192.168.0.102:8083;

还有四个提供用户服务的实例分别运行在 192.168.1.100:8091、192.168.1.101:8092、192.168.1.102:8093、192.168.1.103:8094;

当这些服务全部启动并成功注册到注册中心上后,注册中心会维护一份类似下面的一个服务清单:

服务名 服务地址
订单服务 192.168.0.100:8081、192.168.0.101:8082、192.168.0.102:8083
用户服务 192.168.1.100:8091、192.168.1.101:8092、192.168.1.102:8093、192.168.1.103:8094

服务发现:在服务治理框架下,服务之间不再通过具体实例地址来相互调用,而是通过向注册中心咨询并获取服务清单,以实现(通过服务名)对具体服务的调用。

  例如:前台用户下单需要调用订单服务,首先向注册中心发起咨询订单服务的请求,注册中心返回订单服务位置清单,然后调用方通过负载策略选择其中某一个位置进行服务调用即可。

2、单点注册中心

创建一个空项目,pom.xml如下(后面都基于这个pom):

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.springcloud.demo</groupId>
<artifactId>springcloud-demo</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>eureka-server</module>
<module>eureka-service-provider</module>
</modules> <name>Maven</name>
<!-- FIXME change it to the project's website -->
<url>http://maven.apache.org/</url>
<inceptionYear>2001</inceptionYear> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.8.RELEASE</version>
<relativePath/>
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<failIfNoTests>true</failIfNoTests>
</configuration>
</plugin>
</plugins>
</build>
</project>

1、服务注册中心

首先搭建一个注册中心,命名为eureka-server,引入eureka依赖包

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

在 Spring Boot 启动入口文件上加注解 @EnableEurekaServer

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

然后配置application.yml:

server:
port: 8081 eureka:
instance:
hostname: eurekaserver
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ spring:
application:
name: eurka-server

其中:

eureka.client.registerWithEureka = false     设置为false表示不向注册中心注册自己,默认为true
eureka.client.fetchRegistry = false               设置为false表示不需要去检索服务,默认为true

启动应用并访问 http://localhost:8081/ ,如下图所示:

可以看到注册中心还没有注册任何服务,至此注册中心已经搭建完毕。

2、服务提供者

搭建好注册中心后,我们再来创建一个服务提供者,然后将其注册到注册中心。新建一个项目eureka-service-provider,添加eureka依赖,在 Spring Boot 启动入口文件上加注解 @EnableEurekaClient

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

配置application.yml:

server:
port: 8082 eureka:
instance:
hostname: service-provider
client:
serviceUrl:
defaultZone: http://localhost:8081/eureka/ spring:
application:
name: service-1

因为需要向注册中心注册,所以 eureka.client.registerWithEureka、eureka.client.fetchRegistry 不要配置为 false

启动eureka-service-provider,刷新注册中心,可以看到服务已经注册成功了:

同时eureka-server控制台会打印一行日志:Registered instance SERVICE-1/xxxx:service-1:8082 with status UP (replication=false)

3、高可用注册中心

上面只是一个单点注册中心,微服务场景下应用通过注册中心来访问真实服务,如果注册中心挂了会造成服务无法调用,所以注册中心也得要保持高可用,Eureka 不可能没有想到这一点,其实在Eureka里,所有结点既是服务提供方,又是服务消费方,注册中心也不例外。

大家还记得在单节点配置里讲到的这两个配置吗:

eureka.client.registerWithEureka = false

eureka.client.fetchRegistry = false

实际上 Eureka 高可用方案就是将自己作为服务向其他服务注册中心注册自己,这样就可以形成一组相互注册的服务注册中心,在这组服务注册中心内部相互同步注册清单,形成一个高可用集群

注册中心集群

创建以下三个Eureka Server:peer1、peer2、peer3

peer1的配置如下(peer2、peer3配置类似):

server:
port: 8081 eureka:
instance:
hostname: peer1
client:
serviceUrl:
defaultZone: http://peer2:8082/eureka/,http://peer3:8083/eureka/ spring:
application:
name: eurka-server

分别启动peer1、peer2、peer3,访问peer1:8081

单点故障

这时候如果peer2突然挂了,访问peer1和peer3仍然可以看到peer2,这是因为Eureka默认开启了自我保护机制(peer2挂了没有剔除),可以通过设置 eureka.server.enable-self-preservation=false 来禁用保护

peer1的配置文件里新增eureka.server.enable-self-preservation=false设置,然后模拟peer3挂了,peer1注册中心如下:

大概两分钟左右,从peer1注册中心可以看到 registered-replicas 有3个,unavailable-replicas 里有 peer3,available-replicas 里只有 peer1 和 peer2 可用,

而从 peer2 里看 peer3 仍然可用(过比较长的时间,peer2 仍然会将 peer3 从 available-replicas 里剔除)

将serverce-1注册到注册中心peer1,然后在peer1 和 peer2里都可以看到service-1。

故障恢复

peer3 经过运维处理恢复了,重新启动peer3自动加入了peer1和peer2集群,可用看到service-1也自动注册到peer3上了:

4、配置

服务注册相关配置:eureka.instance 为前缀对应的Class

org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean

服务实例相关配置:eureka.client 为前缀对应的Class

org.springframework.cloud.netflix.eureka.EurekaClientConfigBean

服务配置属性以eureka.server为前缀对应的Class

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

client常见配置

# 启用Eureka客户端
eureka.client.enabled=true
# 从Eureka服务端获取注册信息的间隔时间(单位:秒)
eureka.client.registry-fetch-interval-seconds=30
# 是否从Eureka服务端获取注册信息
eureka.client.fetch-registry=true
# 是否要将自身的实例信息注册到Eureka服务端
eureka.client.register-with-eureka=true
# 初始化实例信息的变化到Eureka服务端的间隔时间(单位:秒)
eureka.client.instance-info-replication-interval-seconds=40
# 从Eureka客户端到Eureka服务端的连接总数
eureka.client.eureka-server-total-connections=200
# 获取实例时是否过滤,仅保留UP状态的实例
eureka.client.filter-only-up-instances=true

server常见配置

#设为false,关闭自我保护
eureka.server.enable-self-preservation=false
#表示是否将自己注册到Eureka Server,默认为true
eureka.client.register-with-eureka=false
#表示是否从Eureka Server获取注册信息,默认为true
eureka.client.fetch-registry=false
# 扫描失效服务的间隔时间(单位毫秒,默认是60*1000)即60秒
eureka.server.eviction-interval-timer-in-ms=5000
#设置 eureka server同步失败的等待时间 默认 5分
#在这期间,它不向客户端提供服务注册信息
eureka.server.wait-time-in-ms-when-sync-empty=5
#设置 eureka server同步失败的重试次数 默认为 5 次
eureka.server.number-of-replication-retries=5
#自我保护系数(默认0.85)
eureka.server.renewal-percent-threshold=0.85

instance常见配置

#是否优先使用IP地址作为主机名的标识,如果不配置就是机器的主机名
eureka.instance.prefer-ip-address=false
#Eureka客户端向服务的发送心跳的时间间隔(单位:秒)
eureka.instance.lease-renewal-interval-in-seconds=30
#Eureka服务的收到最后一次心跳之后等待的时间上限(单位:秒),
#超过这个时间之后会将该服务实例从注册中心清单里剔除
eureka.instance.lease-expiration-duration-in-seconds=90

附录

  本文Demo地址

  Spring Cloud Netflix官方文档

  Spring Cloud 中文社区

  spring-cloud-book

服务治理

SpringCloudLesson

更多配置参考

spring cloud 服务治理 - Eureka的更多相关文章

  1. Spring Cloud 系列之 Eureka 实现服务注册与发现

    如果你对 Spring Cloud 体系还不是很了解,可以先读一下 Spring Cloud 都有哪些模块 Eureka 是 Netflix 开源的服务注册发现组件,服务发现可以说是微服务架构的核心功 ...

  2. spring cloud 服务注册中心eureka高可用集群搭建

    spring cloud 服务注册中心eureka高可用集群搭建 一,准备工作 eureka可以类比zookeeper,本文用三台机器搭建集群,也就是说要启动三个eureka注册中心 1 本文三台eu ...

  3. Spring Cloud服务的注册与发现(Eureka)

    一.spring cloud简介 spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等.它运 ...

  4. spring Cloud服务注册中心Eureka集群

    spring Cloud服务注册中心Eureka集群配置: 在application.yml文件加以下配置: server: port: 8761 tomcat: uri-encoding: UTF- ...

  5. 基于Spring cloud Ribbon和Eureka实现客户端负载均衡

    前言 本案例将基于Spring cloud Ribbon和Eureka实现客户端负载均衡,其中Ribbon用于实现客户端负载均衡,Eureka主要是用于服务注册及发现: 传统的服务端负载均衡 常见的服 ...

  6. 老板让我重构项目,我想首先应该服务治理---eureka服务治理深入浅出

    目录 什么是服务治理 Eureka调用过程 Eureka单机注册 Eureka 单机启动 单机注册 集群注册 客户调用 Eureka集群注册 idea 如何同一个项目启动多次 Eureka自我保护 为 ...

  7. Spring Cloud 服务端注册与客户端调用

    Spring Cloud 服务端注册与客户端调用 上一篇中,我们已经把Spring Cloud的服务注册中心Eureka搭建起来了,这一章,我们讲解如何将服务注册到Eureka,以及客户端如何调用服务 ...

  8. spring cloud config与eureka配合使用

    前面两篇介绍了Spring Cloud Config服务端和客户端的简单配置,本篇介绍Spring Cloud Config与Eureka配合使用 前言 默认情况下,配置客户端启动时,都是通过配置属性 ...

  9. Spring Cloud 入门 之 Eureka 篇(一)

    原文地址:Spring Cloud 入门 之 Eureka 篇(一) 博客地址:http://www.extlight.com 一.前言 Spring Cloud 是一系列框架的有序集合.它利用 Sp ...

随机推荐

  1. python调用腾讯云短信接口

    目录 python调用腾讯云短信接口 账号注册 python中封装腾讯云短信接口 python调用腾讯云短信接口 账号注册 去腾讯云官网注册一个腾讯云账号,通过实名认证 然后开通短信服务,创建短信应用 ...

  2. VMWare15.0手动为Mac OS10.14虚拟机安装VMWare Tools

    安装完客户机虚拟机后,无法在虚拟机和本机之间拖拽传输文件,开启虚拟机后,底部提示安装VMWare Tools,但是这里无法安装. 虽然可以联网后使用局域网工具(如FeiQ)来传输,但是老感觉不是太方便 ...

  3. Docker 的操作命令记录

    docker ps:列出正在运行的 container docker ps -a:列出所有的 container docker rm [containerid]:移除 container(可并列多个, ...

  4. bugku——蹭网先解开密码(EWSA,hashcat破解wifi握手包)

    题目地址:http://ctf.bugku.com/files/77decd384a172b9a2294e6c6acfd48cc/wifi.cap 下载是个.cap的文件,破解过wifi的童鞋肯定知道 ...

  5. .htaccess文件配置理解

    0x00前言.htaccess文件是用于apache服务器下的控制文件访问的配置文件,因此Nginx下是不会生效的 .htaccess可以控制错误重定向,初始页面设置,文件夹的访问权限,文件的跳转等 ...

  6. 【转载】Gradle学习 第二章:概述

    转载地址:http://ask.android-studio.org/?/article/6 Here is a list of some of Gradle's features.<翻译> ...

  7. flink PageRank详解(批量迭代的页面排名算法的基本实现)

    1.PageRank算法原理   2.基本数据准备 /** * numPages缺省15个测试页面 * * EDGES表示从一个pageId指向相连的另外一个pageId */ public clas ...

  8. nmap指令

    -sP  主机发现    -p  端口扫描(可区域)  -sV  端口(服务版本信息)-O  操作系统-iL  使用列表里的IP.(快捷方便)-iR  对公网上的随机n个IP.--excludeile ...

  9. nc用法

    NC 在客户端 和 服务器执行------------------------------------------------------------------------------------- ...

  10. 目标检测论文解读11——Mask R-CNN

    目的 让Faster R-CNN能做实例分割的任务. 方法 模型的结构图如下. 与Faster R-CNN相比,主要有两点变化. (1) 用RoI Align替代RoI Pool. 首先回顾一下RoI ...