Eureka(停更)
服务治理
在传统的RPC远程调用框架中,管理每个服务与服务之间的依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务与服务之间依赖关系,可以实现服务调用、均衡负载,容错等,实现服务发现与注册。
Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务治理。
服务注册与发现
Eureka 采用了 CS 的设计架构,Eureka Sever 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使 Eureka 的客户端连接到 Eureka Serve 并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。
在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息比如服务地址通讯地址等以别名方式注册到注册中心上。另一方(消费者服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地 RPC 调用 RPC 远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理概念)。在任何 RPC 远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址)。
包含的组件
Eureka Server
提供服务注册服务
各个微服务节点通过配置启动后,会在 Eureka Server 中进行注册,这样 Eureka Server 中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
Eureka Client
通过注册中心进行访问
是一个 Java 客户端,用于简化 Eureka Server 的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后会向 Eureka Server 发送心跳(默认周期30s)。如果 Eureka Server 在多个心跳周期内没有接受到某个节点的心跳,Eureka Server 将会从服务注册表中把这个服务节点移除(默认90s)。
构建 Eureka Server
依赖坐标
<!-- eureka server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
配置
server:
port: 7001
eureka:
instance:
# Eureka 服务端的实例名称
hostname: localhost
client:
# false 表示本端为注册中心,去维护服务实例,不需要检索服务
register-with-eureka: false
fetch-registry: false
service-url:
# 设置与 Eureka Server 交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: https://${eureka.instance.hostname}:${server.port}/eureka/
启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
使用@EnableEurekaServer
注解区分开启服务端与客户端
验证
启动后使用浏览器打开 http:\\localhost:7001
看到配置页面即启动成功
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MdhxSw25-1618551210427)(C:\Users\13536\AppData\Roaming\Typora\typora-user-images\image-20210416010608037.png)]
注册 Eureka Client
依赖坐标
<!-- eureka client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
配置
spring:
application:
# 配置微服务名称
name: provider-payment
eureka:
client:
# 是否将服务注册进 Eureka Server,默认为 ture
register-with-eureka: true
# 是否从 Eureka Server 抓取已有的注册信息,默认为 true
# 单节点无所谓,集群必须设置为 true 才能配和 ribbon 使用负载均衡
fetch-registry: true
# 服务端注册地址
service-url:
defaultZone: http://localhost:7001/eureka
启动类
@SpringBootApplication
@EnableEurekaClient
public class PaymentApplication {
public static void main(String[] args) {
SpringApplication.run(PaymentApplication.class, args);
}
}
使用@EnableEurekaClient
注解区分开启服务端与客户端
验证
启动后使用浏览器打开 http:\\localhost:7001
看到已经注册的服务即成功
Application 与 yml 中配置的服务名对应
Eureka Server 集群
相互注册,相互守望
-
搭建 Eureka Server 设置端口为 7002
-
如果只有一台机器,则可以修改host文件进行域名映射不同端口
相互注册&守望 配置
Eureka Server 7001
server:
port: 7001
spring:
application:
# 服务名
name: eureka-server
eureka:
instance:
# Eureka 服务端的实例名称
hostname: eureka7001.com
client:
# false 表示本端为注册中心,去维护服务实例,不需要检索服务
register-with-eureka: false
# 设置为 true
fetch-registry: true
service-url:
# 设置与 Eureka Server 7002 相互注册
defaultZone: http://eureka7002.com:7002/eureka/
Eureka Server 7002
server:
port: 7002
spring:
application:
name: eureka-server-a
eureka:
instance:
# Eureka 服务端的实例名称
hostname: eureka7002.com
client:
# false 表示本端为注册中心,去维护服务实例,不需要检索服务
register-with-eureka: false
# 设置为 true
fetch-registry: true
service-url:
# 设置与 Eureka Server 7001 相互注册
defaultZone: http://eureka7001.com:7001/eureka/
多台可使用 ,
进行地址分割
验证
7001: ---- 7002:
将其它服务同时注册进 Eureka Server 集群
eureka:
client:
# 是否将服务注册进 Eureka Server,默认为 ture
register-with-eureka: true
# 是否从 Eureka Server 抓取已有的注册信息,默认为 true
# 单节点无所谓,集群必须设置为 true 才能配和 ribbon 使用负载均衡
fetch-registry: true
# 配置多Server
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
搭建服务集群
payment-8002
配置
server:
port: 8002
spring:
application:
name: provider-payment
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:23306/seata_payment?useUnicode=FALSE&characterEncoding=utf-8&useSSL=FALSE
username: root
password: 123456
devtools:
livereload:
port: 35732
eureka:
client:
# 是否将服务注册进 Eureka Server,默认为 ture
register-with-eureka: true
# 是否从 Eureka Server 抓取已有的注册信息,默认为 true
# 单节点无所谓,集群必须设置为 true 才能配和 ribbon 使用负载均衡
fetch-registry: true
# 服务端注册地址
service-url:
defaultZone: http://localhost:7001/eureka, http://localhost:7002/eureka
mybatis:
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: com.study.cloud.entity
业务与8001一致,区别在于端口号
Rest Template调用
Ribbon
使用@LoadBalanced
注解开启RestTemplate
负载均衡
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
==只关注服务名称,不再关注端口号。有均衡负载算法进行选择服务的调用。==默认未轮询。
对外只暴露微服务地址名称。
完整配置
eureka:
# 配置实例
instance:
# 实例id
instance-id: payment8001
# 是否显示ip地址
prefer-ip-address: true
client:
# 是否将服务注册进 Eureka Server,默认为 ture
register-with-eureka: true
# 是否从 Eureka Server 抓取已有的注册信息,默认为 true
# 单节点无所谓,集群必须设置为 true 才能配和 ribbon 使用负载均衡
fetch-registry: true
# 服务端注册地址
service-url:
defaultZone: http://localhost:7001/eureka, http://localhost:7002/eureka
服务发现Discovery
服务发现可以实现 Client 获取注册中心已注册过的服务信息,包括自身服务。
启动类
添加开启服务发现注解@EnableDiscoveryClient
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class PaymentApplication8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentApplication8001.class, args);
}
}
基本使用
在 Compoment
中注入 DiscoveryClient
类
@Resource
private DiscoveryClient discoveryClient;
调用其方法
@GetMapping("/discovery")
public Result<DiscoveryClient> discovery() {
//获取注册的服务
List<String> serviceList = discoveryClient.getServices();
log.info("======== 服务列表清单 ========");
for (String service : serviceList) {
log.info(service);
}
log.info("============================");
log.info("======== 服务名获取实例 ========");
//获取实例信息
List<ServiceInstance> instanceList = discoveryClient.getInstances("PROVIDER-PAYMENT");
for (ServiceInstance instance : instanceList) {
log.info(instance.getInstanceId() + " | " + instance.getHost() + " | " + instance.getUri() + " | ");
}
log.info("==============================");
return new Result<>(200, "ok", discoveryClient);
}
打印信息:
返回结果:
{
"status": 200,
"message": "ok",
"data": {
"services": [
"provider-payment",
"consumer-order"
],
"order": 0
}
}
自我保护机制
保护模式主要用于一组 Client 和 Server 之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server 将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据------即不会注销任何微服务。
在某个时刻微服务不可用时,Eureka 不会立刻清理,依旧会对服务信息进行保存,属于 CAP 中的 AP 分支。
如果在 Eureka Server 首页看到一下提示,则说明 Eureka 进入了保护模式
作用
默认情况下,如果 Eureka Server 在一定时间内没有收到某个服务实例的心跳,Eureka Server 将会注销该实例(90秒)。但当网络分区故障发生(延时、卡顿、拥挤)时,微服务与 Eureka Server 之间无法正常通信,以上行为可能变得非常危险----因为微服务本身其实是健康的,此时本不应该注销这个服务。Eureka 通过“自我保护模式”来解决这个问题----当 Eureka Server 节点在短时间丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。
关闭保护机制
eureka:
instance:
# Eureka 服务端的实例名称
hostname: eureka7001.com
server:
# 关闭自我保护机制
enable-self-preservation: false
# 设置心跳检测间隔时间
eviction-interval-timer-in-ms: 2000
显示一下信息则表示关闭成功:
客户端
eureka:
# 配置实例
instance:
# 客户端发送心跳时间间隔(默认30)
lease-renewal-interval-in-seconds: 2
# 服务端在收到最后一次心跳后等待的时间上限(默认90)
lease-expiration-duration-in-seconds: 5
停更说明
The existing open source work on eureka 2.0 is discontinued. The code base and artifacts that were released as part of the existing repository of work on the 2.x branch is considered use at your own risk.
Eureka 1.x is a core part of Netflix’s service discovery system and is still an active project.