服务注册Eureka基础
1 微服务的注册中心
注册中心可以说是微服务架构中的”通讯录“,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就这里找到服务的地址,进行调用。
1.1 注册中心的主要作用
服务注册中心(下称注册中心)是微服务架构非常重要的一个组件,在微服务架构里主要起到了协调者的一个作用。注册中心一般包含如下几个功能:
1. 服务发现:
- 服务注册/反注册:保存服务提供者和服务调用者的信息
- 服务订阅/取消订阅:服务调用者订阅服务提供者的信息,最好有实时推送的功能
- 服务路由(可选):具有筛选整合服务提供者的能力。
2. 服务配置:
- 配置订阅:服务提供者和服务调用者订阅微服务相关的配置
- 配置下发:主动将配置推送给服务提供者和服务调用者
3. 服务健康检测
- 检测服务提供者的健康情况
1.2 常见的注册中心
Zookeeper
zookeeper它是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。简单来说zookeeper=文件系统+监听通知机制。
Eureka
Eureka是在Java语言上,基于Restful Api开发的服务注册与发现组件,Springcloud Netflix中的重要组件。
Consul
Consul是由HashiCorp基于Go语言开发的支持多数据中心分布式高可用的服务发布和注册服务软件,采用Raft算法保证服务的一致性,且支持健康检查。
Nacos
Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。简单来说 Nacos 就是注册中心 + 配置中心的组合,提供简单易用的特性集,帮助我们解决微服务开发必会涉及到的服务注册与发现,服务配置,服务管理等问题。Nacos 还是 Spring Cloud Alibaba 组件之一,负责服务注册与发现。
最后我们通过一张表格大致了解Eureka、Consul、Zookeeper的异同点。选择什么类型的服务注册与发现组件可以根据自身项目要求决定。
2 Eureka的概述
2.1 Eureka的基础知识
Eureka是Netflix开发的服务发现框架,SpringCloud将它集成在自己的子项目spring-cloud-netflix中,实现SpringCloud的服务发现功能。
上图简要描述了Eureka的基本架构,由
3个角色组成:
1、Eureka Server
- 提供服务注册和发现
2、Service Provider
- 服务提供方
- 将自身服务注册到Eureka,从而使服务消费方能够找到
3、Service Consumer
- 服务消费方
- 从Eureka获取注册服务列表,从而能够消费服务
2.2 Eureka的交互流程与原理
图是来自Eureka官方的架构图,大致描述了Eureka集群的工作过程。图中包含的组件非常多,可能比
较难以理解,我们用通俗易懂的语言解释一下:
- Application Service 相当于本书中的服务提供者,Application Client相当于服务消费者;
- Make Remote Call,可以简单理解为调用RESTful API;
- us-east-1c、us-east-1d等都是zone,它们都属于us-east-1这个region;
由图可知,Eureka包含两个组件:Eureka Server 和 Eureka Client,它们的作用如下:
- Eureka Client是一个Java客户端,用于简化与Eureka Server的交互;
- Eureka Server提供服务发现的能力,各个微服务启动时,会通过Eureka Client向Eureka Server进行注册自己的信息(例如网络信息),Eureka Server会存储该服务的信息;
- 微服务启动后,会周期性地向Eureka Server发送心跳(默认周期为30秒)以续约自己的信息。如果Eureka Server在一定时间内没有接收到某个微服务节点的心跳,Eureka Server将会注销该微服务节点(默认90秒);
- 每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过复制的方式完成服务注册表的同步;
- Eureka Client会缓存Eureka Server中的信息。即使所有的Eureka Server节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者。
综上,Eureka通过心跳检测、健康检查和客户端缓存等机制,提高了系统的灵活性、可伸缩性和可用性。
3 搭建Eureka注册中心
3.1 搭建Eureka服务中心
(1) 创建shop_eureka_server子模块
在 shop_parent 下创建子模块eureka_server
(2) 引入maven坐标
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
(3) 配置application.yml
server:
port: 9000 #端口
#配置eureka server
eureka:
client:
register-with-eureka: false #是否将自己注册到注册中心
fetch-registry: false #是否从eureka中获取注册信息
service-url: #配置暴露给Eureka Client的请求地址
defaultZone: http://127.0.0.1:9000/eureka/
server:
enable-self-preservation: false #关闭自我保护
eviction-interval-timer-in-ms: 4000 #剔除时间间隔,单位:毫秒
(4) 配置启动类
在 cn.itcast.eureka 下创建启动类 EurekaServerApplication
@SpringBootApplication
@EnableEurekaServer //激活Eureka Server端配置
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class);
}
}
3.2 服务注册中心管理后台
打开浏览器访问http://localhost8761即可进入EurekaServer内置的管理控制台,显示效果如下
4 服务注册到Eureka注册中心
4.1 商品服务注册
(1) 商品模块中引入坐标
在 product service文件中添加eureka client的相关坐标
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
(2) 配置application.yml文件
在工程的 application.yml 中添加Eureka Server的主机地址
# 配置 eureka server
eureka:
client:
service-url: # eureka server的路径
defaultZone: http://127.0.0.1:9000/eureka/
instance:
prefer-ip-address: true #使用ip注册
(3) 修改启动类添加服务注册注解
@SpringBootApplication
@EntityScan("cn.itcast.product.entity")
// 从Spring Cloud Edgware版本开始, @EnableDiscoveryClient 或 @EnableEurekaClient 可
//省略。只需加上相关依赖,并进行相应配置,即可将微服务注册到服务发现组件上。
//@EnableDiscoveryClient
//@EnableEurekaClient
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class);
}
}
4.2 订单服务注册
和商品微服务一样,只需要引入坐标依赖,在工程的 application.yml 中添加Eureka Server的主机地址即可
# 配置 eureka server
eureka:
client:
service-url: # eureka server的路径
defaultZone: http://localhost:9000/eureka/
instance:
prefer-ip-address: true #使用ip注册
5 Eureka中的自我保护
微服务第一次注册成功之后,每30秒会发送一次心跳将服务的实例信息注册到注册中心。通知 Eureka
Server 该实例仍然存在。如果超过90秒没有发送更新,则服务器将从注册信息中将此服务移除。
Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果出现低于的情况(在单机调试的时候很容易满足,实际在生产环境上通常是由于网络不稳定导致),Eureka Server会将当前的实例注册信息保护起来,同时提示这个警告。保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)验证完自我保护机制开启后,并不会马上呈现到web上,而是默认需等待 5 分钟(可以通过eureka.server.wait-time-in-ms-when-sync-empty 配置),即 5 分钟后你会看到下面的提示信息:
如果关闭自我保护
通过设置 eureka.enableSelfPreservation=false 来关闭自我保护功能
#配置eureka server
eureka:
server:
enable-self-preservation: false #关闭自我保护
eviction-interval-timer-in-ms: 4000 #剔除时间间隔,单位:毫秒
6 Eureka中的元数据
Eureka的元数据有两种:标准元数据和自定义元数据。
- 标准元数据:主机名、IP地址、端口号、状态页和健康检查等信息,这些信息都会被发布在服务注册表中,用于服务之间的调用。
- 自定义元数据:可以使用eureka.instance.metadata-map配置,符合KEY/VALUE的存储格式。这些元数据可以在远程客户端中访问。
在程序中可以使用DiscoveryClient 获取指定微服务的所有元数据信息
//注入discoveryClient
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/buy/{id}")
public Product buyById(@PathVariable Long id) {
//根据微服务名称从注册中心获取相关的元数据信息
List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
for (ServiceInstance instance : instances) {
System.out.println(instance);
}
ServiceInstance instance = instances.get(0);
Product product = null;
//根据元数据信息 获取对应服务的ip和端口,拼接url
product = restTemplate.getForObject("http://"+instance.getHost()+":"+instance.getPort()+"/product/1",Product.class);
return product;
}