文章目录
ps:我的个人笔记地址:TinkerBell学习笔记
1 Spring Cloud Eureka 简介
Eureka: 古希腊词汇 意思为“发现了”
公司:Eureka 为Netfix公司的一个开源服务发现注册组件
(Netfix公司其他服务组件,负载均衡 熔断技术,网关等等)
2 前言-分布式特点 CAP?
2.1 什么是CAP原则
CAP原则:又称CAP定理,
范围指:在一个分布式系统中
一致性(Consistency):
-A,B,C里面的数据是一致的
可用性(Availability):
-当集群中只要还存活一台服务,就能对外提供服务
分区容错性(Partition tolerance)(这个特性是不可避免的):
在集群里面的机器,因为网络原因,机房的原因,可能导致数据不会里面 同步),它在分布式必须需要实现的特性!
CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。 由此可知:有组合 AP原则(高可用原则) CP原则(一致性原则)
2.2.1 Eureka和Zookeeper的区别?
先说结论: Eureka:AP原则(高可用) Zookeeper:CP原则(一致性)
在 zk 里面,若主机挂了,则 zk 集群整体不对外提供服务了,(重新选举)需要选一个新的出来(120s 左右)才能继续对外提供服务!
Eureka 注重服务的可用性,当 Eureka 集群只有一台活着,它就能对外提供服务
2.2.2 为什么Eureka只要集群有存活就能提供服务
Zookeeper集群中有“老大master”,小弟“leader”区分,当老大宕机了,需要在小弟中重新选举一个新老大,此时是暂停服务的(120s)
Eureka集群中 每个节点的地位相等,他们两两注册 (后面会介绍),所以只要当集群中还有存活,他们就不会停止服务
3 快速搭建Eureka服务端
新建Spring Boot项目 ,勾选 Eureka Server依赖 , 确认
3.1 分析 pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<!-- 实质还是 springboot 项目-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.tinkerbell</groupId>
<artifactId>Eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>01-Eureka-server</name>
<description>01-Eureka-server</description>
<properties>
<java.version>1.8</java.version>
<!-- 这里控制了 springcloud 的版本-->
<spring-cloud.version>Hoxton.SR12</spring-cloud.version>
</properties>
<dependencies>
<dependency> <!-- eureka 注册中心的服务端-->
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 依赖管理,cloud 的依赖-->
</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>
</project>
3.2 修改启动类
@SpringBootApplication
@EnableEurekaServer //表示开启Eureka注册中心服务端
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
3.3 修改配置文件
server:
port: 8761 #为什么是 8761,其他端口就报错
spring:
application:
name: eureka-server #给服务起个名称 后面会用到
3.4 访问测试
3.5 分析端口 8761
Eureka-Server 不仅提供让别人注册的功能,它也能注册到别人里面,自己注册自己 所以,在启动项目时,默认会注册自己,我们也可以关掉这个功能。
那么往哪个地址注册自己呢?看一下源码
4 快速搭建Eureka-client客户端
新建Spring Boot项目,勾选Eureka Client依赖和Spring Web依赖(不勾选的话吗,项目启动就停了 无法注册),确认
4.1 分析Poml.xml
eureka-client客户端的依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
4.2 修改启动类
@SpringBootApplication
@EnableEurekaClient //表示开启Eureka-Client客户端
public class EurekaClientAApplication {
publ
ic static void main(String[] args) {
SpringApplication.run(EurekaClientAApplication.class, args);
}
}
4.3 修改配置文件
server:
port: 8080
spring:
application:
name: eureka-client-a
eureka:
client:
service-url: #eureka 服务端和客户端的交互地址,集群用,隔开
defaltZone: http://localhost:8761/eureka
4.4访问测试
注意
:访问的是8761端口(服务端)访问client客户端注册是否成功
成功!~Binggo
4.5 同一个服务(客户端)启动多台
4.6 访问测试
5 注册中心的状态
UP
: 服务是上线的,括号里面是具体服务实例的个数,提供服务的最小单元
DOWN
: 服务是下线的
UN_KONW
: 服务的状态未知
5.2 服务的实例名称
修改:
eureka:
instance:
hostname: localhost #默认hostname为电脑主机名称,修改为localhost或者 上线部署的ip地址
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
###5.3 server中常用的配置文件
server:
port: 8761 #为什么是 8761,其他端口就报错
spring:
application:
name: eureka-server #服务名称
eureka:
instance:
hostname: localhost
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
client:
service-url: #eureka 服务端和客户端的交互地址,集群用,隔开
defaultZone: http://localhost:8761/eureka
fetch-registry: true #是否拉取服务列表
register-with-eureka: true #是否注册自己(单机 eureka 一般关闭注册自己,集群注意打开)
server:
eviction-interval-timer-in-ms: 30000 #清除无效节点的频率(毫秒)--定期删除
enable-self-preservation: true #server 的自我保护机制,避免因为网络原因造成误剔除,生产环境建议打开
renewal-percent-threshold: 0.85 #85%,如果在一个机房的 client 端,15 分钟内有 85%的 client 没有续约,那么则可能是
#网络原因,认为服务实例没有问题,不会剔除他们,宁可放过一万,不可错杀一个,确保高可用
5.4 client中常用的配置
server:
port: 8080
spring:
application:
name: eureka-client-a
eureka:
client:
service-url: #eureka 服务端和客户端的交互地址,集群用,隔开
defaltZone: http://localhost:8761/eureka
fetch-registry: true #是否拉取服务列表
register-with-eureka: true #是否注册自己(单机 eureka 一般关闭注册自己,集群注意打开)
registry-fetch-interval-seconds: 5 # 表示 eureka-client 间隔多久去拉取服务注册信息
instance:
hostname: localhost
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
prefer-ip-address: true # 服务列表以 ip 的形式展示
lease-renewal-interval-in-seconds: 10 # #表示 eureka server 发送心跳给 server 端的频率
lease-expiration-duration-in-seconds: 20 #至上一次收到 client 的心跳之后,等待
#下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该实例
6 构建 Eureaka-Server 集群
6.1 server-1
eureka:
client:
service-url: #eureka 服务端和客户端的交互地址,集群用,隔开
defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka
6.2 server-2
eureka:
client:
service-url: #eureka 服务端和客户端的交互地址,集群用,隔开
defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka
6.3 访问测试
发现并没有出现集群信息,只是同一个服务 server 启动了多台 没有数据交互 不是真正意 义上的集群
原因是: http://localhost:8761/eureka/,http://localhost:8762/eureka/ 这样写,eureka 认为只有一个机器,就是 localhost
解决:修改 hosts 文件: C:\Windows\System32\drivers\etc
6.4 重新修改配置文件
省略其他,仅需修改defaultZone
defaultZone: http://peer1:8761/eureka,http://peer2:8762/eureka
6.5 测试成功
7 集群的使用
改造 eureka-client-a 的配置文件
server:
port: 8080
spring:
application:
name: eureka-client-a
eureka:
client:
service-url: #eureka 服务端和客户端的交互地址,集群用,隔开
defaltZone: http://peer1:8761/eureka,http://peer2:8761/eureka
7.1 集群测试
不管哪一台server都注册成功了…
7.2 Eureka AP原则测试
宕机一台 server
Eureka server 的集群里面,没有主机和从机的概念,节点都是对等的,只有集群里面有一 个集群存活,就能保证服务的可用性。 (主机 (写) 从 (读))
8 Eureka概念理解
8.1 服务的注册
当项目启动时(eureka 的客户端),就会向 eureka-server 发送自己的元数据(原始数据) (运行的 ip,端口 port,健康的状态监控等,因为使用的是 http/ResuFul 请求风格), eureka-server 会在自己内部保留这些元数据(内存中)。(有一个服务列表)(restful 风 格,以 http 动词的请求方式,完成对 url 资源的操作)
8.2 服务的续约
项目启动成功了,除了向 eureka-server 注册自己成功,还会定时的向 eureka-server 汇 报自己,心跳,表示自己还活着。(修改一个时间)
8.3 服务的下线(主动下线)
当客户端项目关闭时,会给 eureka-server 报告,说明自己要下机了。
8.4 服务的剔除(被动下线,主动剔除)
当项目超过了指定时间没有向 eureka-server 汇报自己,那么 eureka-server 就会认为此 节点死掉了,会把它剔除掉,也不会放流量和请求到此节点了。
9 Eureka服务发现
9.1 什么是服务发现
根据服务名称发现服务的实例过程 客户端会在本地缓存服务端的列表 拉取列表是有间隔周期的 (导致服务上线 客户端不能第一时间感知到 (可以容忍)) 其实每次做服务发现 都是从本地的列表来进行的
9.2 测试服务发现
启动 eureka-server 一台 ,启动服务 a ,启动服务 b ,确保服务都上线了
9.3 在服务a中做服务发现
思路:在服务a中给个接口 传入服务b的名称 找到服务b
package com.tinkerbell.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @Author: 小叮当
* @Description: 调用服务发现
* @Date Created in 2022/9/2 0002 下午 11:16
* @Web www.tinkerbell9433.top / TinkerBell学习笔记
*/
@RestController
public class TestController {
//注入服务发现组件,我们的 eureka 已经实现了这个接口,所以 IOC 里面有这个对象 */
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/find")
public String find(String serverId){
//调用服务发现
List<ServiceInstance> instances = discoveryClient.getInstances(serverId);
instances.forEach(System.out::println);
return instances.toString();
}
}
9.4 测试成功
10 Eureka原理时序图
【ps:eureka 客户端会把服务列表缓存到本地 为了提高性能 但是有脏读问题,当你启动一个新的应用的时候 不会被老的应用快速发现】
ps:我的个人笔记:TinkerBell学习笔记