SpringColud Eureka的服务注册与发现
2021-05-13 18:30
标签:ast 建议 eureka 解决 ext 一个 包含 code 异常 本文中所有代码都会上传到git上,请放心浏览 在传统应用中,组件之间的调用,通过有规范的约束的接口来实现,从而实现不同模块间良好的协作。但是被拆分成微服务后,每个微服务实例的网络地址都可能动态变化,数量也会变化,使得原来硬编码的地址失去了作用。需要一个中心化的组件来进行服务的登记和管理,为了解决上面的问题,于是出现了服务治理,就是管理所有的服务信息和状态,也就是我们所说的注册中心 比如我们去做火车或者汽车,需要去买票乘车,只看我们有没有票(有没有服务),有就去买票(获取注册列表),然后乘车(调用),不用关心到底有多少车在运行 流程图: 注册中心:Eureka,Nacos,Consul,Zookeeper 本文中讲解的是比较火热的Spring Cloud微服务下的Eureka,Eureka是Netflix开发的服务发现框架,是一个RESTful风格的服务,是一个用于服务发现和注册的基础组件,是搭建Spring Cloud微服务的前提之一,它屏蔽了Server和client的交互细节,使得开发者将精力放到业务上。 服务注册与发现主要包括两个部分: 服务端(Eureka Server): 一个公共服务,为Client提供服务注册和发现的功能,维护注册到自身的Client的相关信息,同时提供接口给Client获取注册表中其他服务的信息,使得动态变化的Client能够进行服务间的相互调用。 客户端(Eureka Client): Client将自己的服务信息通过一定的方式登记到Server上,并在正常范围内维护自己信息一致性,方便其他服务发现自己,同时可以通过Server获取到自己依赖的其他服务信息,完成服务调用,还内置了负载均衡器,用来进行基本的负载均衡 Eureka GIt官网:https://github.com/Netflix/Eureka 服务注册与发现关系图: 在有的教程中,会引入 启动类上添加此注解标识该服务为配置中心 我们启动 注意:在客户端pom里面我们需要加上 在客户端启动类中我们需要加上 工程启动后,刷新 并且我们可以在idea日志打印中看到 Eureka Client将定时从Eureka Server中拉取注册表中的信息,并将这些信息缓存到本地,用于服务发现 官网地址:https://github.com/Netflix/eureka/wiki/Eureka-REST-operations Eureka服务器还提供了一个端点 存储了每个客户端的注册信息。EurekaClient从EurekaServer同步获取服务注册列表。通过一定的规则选择一个服务进行调用 有时候我们会看到这样的提示信息: 那么自我保护是如何触发的呢? numberOfRenewsPerMinThreshold = expectedNumberOfRenewsPerMin * 续租百分比(默认为0.85) 例如:我们有10个服务,期望每分钟续约数:10 * 2=20,期望阈值:20*0.85=17,当少于17时,就会触发自我保护机制 由于server和client通过心跳保持 服务状态,而只有状态为UP的服务才能被访问。看eureka界面中的status。 比如心跳一直正常,服务一直UP,但是此服务DB(数据库)连不上了,无法正常提供服务。 此时,我们需要将 微服务的健康状态也同步到server。只需要启动eureka的健康检查就行。这样微服务就会将自己的健康状态同步到eureka。配置如下即可。 在client端配置:将自己的健康状态传播到server。 Eureka Client 会每隔 30 秒发送一次心跳来续约。 通过续约来告知 Eureka Server 该 Eureka Client 运行正常,没有出现问题。 默认情况下,如果 Eureka Server 在 90 秒内没有收到 Eureka Client 的续约,Server 端会将实例从其注册表中删除,此时间可配置,一般情况不建议更改。 如果Eureka Client在注册后,既没有续约,也没有下线(服务崩溃或者网络异常等原因),那么服务的状态就处于不可知的状态,不能保证能够从该服务实例中获取到回馈,所以需要服务剔除此方法定时清理这些不稳定的服务,该方法会批量将注册表中所有过期租约剔除,剔除是定时任务,默认60秒执行一次。延时60秒,间隔60秒 剔除的限制: 由于集群间的同步复制是通过HTTP的方式进行,基于网络的不可靠性,集群中的Eureka Server间的注册表信息难免存在不同步的时间节点,不满足CAP中的C(数据一致性) 中间我们讲解了eureka的节点搭建,以及原理,对于现在很火热的微服务,我们对Eureka是非常有必要进行了解的,如果觉得文章对你有帮助,来个点赞支持吧,如果对文章有疑问或建议,欢迎讨论留言,谢谢大家~ SpringColud Eureka的服务注册与发现 标签:ast 建议 eureka 解决 ext 一个 包含 code 异常 原文地址:https://www.cnblogs.com/mingyueyy/p/13127576.html一、Eureka简介
项目git地址:https://github.com/839022478/Spring-Cloud1.1 注册中心
使用注册中心,我们不需要关心有多少提供方,只管去调用就可以了,那么注册中心有哪些呢?服务端(Eureka Server)和客户端(Eureka Client)
1.3 服务注册与发现
1.2 client功能和server功能
1.2.1 client功能
1.2.2 server注册中心功能
注册表提供 查询API(查询可用的微服务实例)和管理API(用于服务的注册和注销)。二、Eureka单节点搭建
2.1 pom.xml
spring-boot-starter-web
,这个依赖其实不用,因为spring-cloud-starter-netflix-eureka-server
的依赖已经包含了它,在pom依赖进去,就可以了2.2 application.yml
server:
port: 8500
eureka:
client:
#是否将自己注册到Eureka Server,默认为true,由于当前就是server,故而设置成false,表明该服务不会向eureka注册自己的信息
register-with-eureka: false
#是否从eureka server获取注册信息,由于单节点,不需要同步其他节点数据,用false
fetch-registry: false
#设置服务注册中心的URL,用于client和server端交流
service-url:
defaultZone: http://localhost:8080/eureka/
2.3 服务端启动类
@EnableEurekaServerimport org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
2.4 启动
EurekaDemoApplication
,然后在浏览器中输入地址 http://localhost:8500/
,就可以启动我们的 Eureka 了,我们来看下效果,出现了这个画面,就说明我们已经成功启动~,只是此时我们的服务中是还没有客户端进行注册三、服务注册
spring-boot-starter-web
,否则服务是无法正常启动的3.1 pom.xml
3.2 application.yml
#注册中心
eureka:
client:
#设置服务注册中心的URL
service-url:
defaultZone: http://localhost:8500/eureka/
#服务名
instance:
appname: mxn
3.3 客户端启动类
@EnableDiscoveryClient
注解import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaClientApplication.class, args);
}
}
3.4 查看效果
http://localhost:8500/
页面,我们可以发现服务注册成功了DiscoveryClient_MXN/DESKTOP-5BQ3UK8 - registration status: 204
,说明就是注册成功了
Eureka Server与Eureka Client之间的联系主要通过心跳的方式实现。心跳(Heartbeat)即Eureka Client定时向Eureka Server汇报本服务实例当前的状态,维护本服务实例在注册表中租约的有效性。四、Eureka 端点
(eureka/apps/{applicaitonName})
可以查看所注册的服务详细信息 。applicaitonName就是微服务的名称,比如这里我们访问 http://localhost:8500/eureka/apps/mxn
五、Eureka 原理
5.1 本质
5.2 Eureka架构图
5.3 Eureka自我保护
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY‘RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
,这是因为默认情况下,Eureka Server在一定时间内,没有接收到某个微服务心跳,会将某个微服务注销(90S)。但是当网络故障时,微服务与Server之间无法正常通信,上述行为就非常危险,因为微服务正常,不应该注销,它的指导思想就是 宁可保留健康的和不健康的,也不盲目注销任何健康的服务
我们也可以通过命令去关闭自我保护的功能:eureka:
server:
enable-self-preservation: false
自我保护机制的触发条件是,当每分钟心跳次数( renewsLastMin
) 小于 numberOfRenewsPerMinThreshold
时,并且开启自动保护模式开关( eureka.server.enable-self-preservation = true
) 时,触发自我保护机制,不再自动过期租约
上面我们所有的小于 numberOfRenewsPerMinThreshold
,到底是怎么计算的呢,我们在eureka源码中可以得知
expectedNumberOfRenewsPerMin = 当前注册的应用实例数 x 2
当前注册的应用实例数 x 2 是因为,在默认情况下,注册的应用实例每半分钟续租一次,那么一分钟心跳两次,因此 x 25.4 健康检查
eureka:
client:
healthcheck:
enabled: true
5.5 Eureka监听事件
import com.netflix.appinfo.InstanceInfo;
import org.springframework.cloud.netflix.eureka.server.event.*;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
public class CustomEvent {
@EventListener
public void listen(EurekaInstanceCanceledEvent event ) {
System.out.println(LocalDateTime.now()+"服务下线事件:"+event.getAppName()+"---"+event.getServerId());
//发钉钉
}
@EventListener
public void listen(EurekaInstanceRegisteredEvent event) {
InstanceInfo instanceInfo = event.getInstanceInfo();
System.out.println(LocalDateTime.now()+"服务上线事件:"+instanceInfo.getAppName()+"---"+instanceInfo.getInstanceId());
}
@EventListener
public void listen(EurekaInstanceRenewedEvent event) {
System.out.println(LocalDateTime.now()+"服务续约/心跳上报事件:"+event.getAppName()+"---"+event.getServerId());
}
@EventListener
public void listen(EurekaRegistryAvailableEvent event) {
System.out.println(LocalDateTime.now()+"注册中心可用事件");
}
@EventListener
public void listen(EurekaServerStartedEvent event) {
System.out.println(LocalDateTime.now()+"注册中心启动事件");
}
}
5.6 Renew: 服务续约
5.6 服务剔除
1.自我保护期间不清除。
2.分批次清除。六、Eureka缺陷
七、总结