Spring Cloud系列之Eureka
Spring Cloud系列之配置中心Config
Spring Cloud系列之gateway
Spring Cloud系列之Feign
Spring Cloud系列之Hystrix
Spring Cloud系列之链路追踪
关于注册中心
目的:服务注册中心本质上是为了解耦服务提供者和服务消费者
对于任何一个微服务,原则上都应该存在或者支持多个提供者,这是由微服务的分布式属性决定的。
更进一步就是为了弹性的扩容、缩容
服务注册中心原理
这里我们就直接以一幅图来了解下:
主流注册中心对比
-
zookeeper
zookeeper它是一个分布式服务框架,是Apache hadoop的一个子项目,他主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等到。
zookeeper本质=存储+监听通知,zookeeper用来做注册中心,主要是因为他具有节点变更通知功能。另外zookeeper可用性也还可以,只要保证过半数节点存活,整个集群就是可用的
-
Nacos
Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台
nacos本质上=注册中心+配置中心的组合,他是spring cloud alibaba核心组件之一
-
Consul
Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。 Consul 使用 Go 语言编写,因此具有天然可移植性(支持Linux、windows和Mac OS X)。
采用raft算法保证服务一致性,并且支持健康检查。
-
Eureka
eureka是由Netflix开源,并被pivatal集成到springcloud体系中,他是基于restfulAPI风格开发的服务注册于发现组件。
下面我们用表格来对比下各个注册中心的区别:
CAP
一致性(Consistency)
可用性(Availability)
分隔容忍(Partition tolerance)
CAP不可能都满足
原因如下:
- 如果C是第一需求的话,那么会影响A的性能。
因为要数据同步,不然请求结果会有差异,但是数据同步会消耗时间,可用性就会降低。 - 如果A是第一需求,那么只要有一个服务在,就能正常接受请求。
但是对于返回结果便不能保证,原因是,在分布式部署的时候,数据一致的过程不可能像切线路那么快。 - 如果同时满足一致性和可用性,那么分区容错就很难保证了。
但是CAP理论提出就是针对分布式数据库环境的,所以P这个属性是必须具备的。
P就是在分布式环境中,由于网络的问题可能导致某个节点和其它节点失去联系,这时候就形成了P(partition)。
所以要不就ap 要不就cp
Nacos | Eureka | Consul | Zookeeper | |
---|---|---|---|---|
语言 | java | java | go | java |
一致性协议(CAP) | CP+AP(支持切换) | AP | CP | CP |
健康检查 | TCP/HTTP/MYSQL/Client Beat | Client Beat | TCP/HTTP/gRPC/Cmd | Keep Alive |
负载均衡策略 | 权重/ metadata/Selector | Ribbon | Fabio | — |
雪崩保护 | 有 | 有 | 无 | 无 |
自动注销实例 | 支持 | 支持 | 支持 | 支持 |
访问协议 | HTTP/DNS | HTTP | HTTP/DNS | TCP |
监听支持 | 支持 | 支持 | 支持 | 支持 |
多数据中心 | 支持 | 支持 | 支持 | 不支持 |
跨注册中心同步 | 支持 | 不支持 | 支持 | 不支持 |
SpringCloud集成 | 支持 | 支持 | 支持 | 支持 |
Dubbo集成 | 支持 | 不支持 | 支持 | 支持 |
K8S集成 | 支持 | 不支持 | 支持 | 不支持 |
Eureka
Eureka包括两个端:
Eureka Server:注册中心服务端,用于维护和管理注册服务列表。
Eureka Client:注册中心客户端,向注册中心注册服务的应用都可以叫做Eureka Client(包括Eureka Server本身)
Eureka基础架构:
[图片上传失败...(image-a7504e-1638869834231)]
Eureka交互流程及原理,下面我们贴出一张Eureka官方wiki的架构图:
Eureka Server:表示注册中心集群
us-east-xxx:表示集群所在的区域
Application Service:表示服务提供者
Application Client:表示服务消费者
Eureka Client:表示Eureka客户端
现在有三个区us-east-1c,us-east-1d,us-east-1e,每个区里都有一个Eureka Server集群,以及不定的Application Service和Application Client。
Eureka之server端构建
- 引入依赖
在父工程里面引入springcloud的大版本
<properties>
<java.version>1.8</java.version>
<springboot.version>2.1.5.RELEASE</springboot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 可以在这里强制覆盖依赖默认的版本号,只需要与依赖版本号使用的属性名称一致即可 -->
<lombok.version>1.18.6</lombok.version>
<fastjson.version>1.2.56</fastjson.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- springCloud -->
<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>
在eureka servermoudle的pom文件引入eureka-server:
<?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">
<parent>
<artifactId>dy-springcloud</artifactId>
<groupId>com.dy</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.dy</groupId>
<artifactId>eureka-server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
-
配置文件
新建application.yml,配置如下:
server:
port: 10001
spring:
application:
name: eureka-server
#eureka 参数配置 具体可参考 https://www.cnblogs.com/fangfuhai/p/7070325.html
eureka:
# 此实例注册到eureka服务端的唯一的实例ID,其组成为${spring.application.name}:${spring.application.instance_id:${random.value}}
instance:
# 获取实例的ip地址,而不是主机名(兼容老的eureka版本)
prefer-ip-address: true
# 实例名称在这里面我们是以 ip+服务名字+端口号+版本号
instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
client:
# 是否注册自己(在这里我们可以注册自己也可以选择不注册自己)
register-with-eureka: false
# 是否拉取服务列表
fetch-registry: false
# 配置eureka服务地址
service-url:
# eureka 服务地址,如果是集群的话;需要指定其它集群eureka地址 ,如果是多台eureka server 地址以逗号隔开
defaultZone: http://127.0.0.1:10001/eureka
server:
# 服务失效剔除时间间隔,默认60秒
eviction-interval-timer-in-ms: 3000
# 关闭自我保护模式(默认是打开的)
enable-self-preservation: false
-
启动类
application启动类如下:
package com.dy.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* @Description:
* @author: dy
*/
@EnableEurekaServer //声明当前应用是Eureka服务
@EnableDiscoveryClient //开启Eureka客户端发现功能
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
启动application,我们可以打开eureka提供的web页面地址为我们配置文件里面配置的service-url,去掉/eureka
,在这里我们得到的地址为http://127.0.0.1:10001,打开管理界面
Eureka之客户端构建
- 引入依赖
<?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">
<parent>
<artifactId>dy-springcloud</artifactId>
<groupId>com.dy</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.dy</groupId>
<artifactId>user-service</artifactId>
<dependencies>
<!-- eureka client依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
-
配置文件
application.yml配置文件如下:
server:
port: 11001
spring:
application:
name: user-service
eureka:
# 此实例注册到eureka服务端的唯一的实例ID,其组成为${spring.application.name}:${spring.application.instance_id:${random.value}}
instance:
# 获取实例的ip地址
prefer-ip-address: true
# 与此实例相关联的主机名,是其他实例可以用来进行请求的准确名称
hostname: localhost
# eureka客户需要多长时间发送心跳给eureka服务器,表明它仍然活着,默认为30 秒
lease-renewal-interval-in-seconds: 10
# Eureka服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为90秒
lease-expiration-duration-in-seconds: 30
client:
# 注册自己
register-with-eureka: true
# 不拉取服务
fetch-registry: true
# 配置服务地址
service-url:
# eureka 服务地址,如果是集群的话;需要指定其它集群eureka地址 ,如果是多台eureka server 地址以逗号隔开
defaultZone: http://127.0.0.1:10001/eureka
-
启动类
application启动类如下:
package com.dy.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @Description:
* @author: dy
*/
@EnableDiscoveryClient //开启Eureka客户端发现功能
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
Eureka高可用配置(集群)
目标:可以启动多台eureka-server实例;在eureka管理界面看到多个实例
分析:
Eureka Server是一个web应用,可以启动多个实例(配置不同端口)保证Eureka Server的高可用。
可以在配置server-url的时候配置多台server地址以逗号隔开
小结:
高可用配置:将Eureka Server作为一个服务注册到其它Eureka Server,这样多个Eureka Server之间就能够互相发现对方,同步服务,实现Eureka Server集群。