SpringCloud 微服务
本文全程都是 qa 格式!
本文全程都是 qa 格式!
本文全程都是 qa 格式!
Eureka 注册中心
硬编码服务调用会出现什么问题
- 消费者不知如何获取服务提供者地址信息
- 多个提供者不知如何选择
- 无法了解提供者健康状态
Eureka 架构中微服务分为哪两类
EurekaServer服务端,注册中心EurekaClient客户端
EurekaServer 和 EurekaClient 关系
EurakaServer 有什么作用
- 记录每个微服务的服务信息,如访问功能的接口路径。
- 心跳监控,监控提供者微服务的健康状态。
EurekaClient 微服务分类和作用是什么
EurakeClient微服务分为消费者和提供者。- 提供者
- 提供者会注册自己的信息到
EurekaServer(将自己的服务信息给EurekaServer) - 提供者会每个30秒向
EurekaServer发送心跳(想EurekaServer发送自己健康状态),不发送视为心跳不正常,信息会被剔除
- 提供者会注册自己的信息到
- 消费者
- 消费者会根据服务名称从
EurekaServer中拉去服务列表 - 获取服务列表后做负载均衡,选中一个微服务后发起远程调用。
- 消费者会根据服务名称从
消费者如何获取服务提供者的具体信息
- 服务提供者在启动时会像
Eureka注册自己的信息。Eureka保存这些信息。消费者根据服务名称像Eureka拉去提供者信息。
如果多个服务提供者,消费者如何选择
- 消费者利用负载均衡算法,从服务列表中挑选一个
消费者如何感知提供者的健康状态
- 提供者每隔30秒像
EurekaServer发送心跳请求,报告健康状态。Eureka 会跟新服务列表信息,心跳不正常会被剔除。消费者就可以拉取到最新的信息。
如何搭建Eureka服务端(EurekaServer)
-
导入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> -
配置
Eureka端口、服务名称、地址信息可以根据自己的实际需求去进行修改
server: # 注册端口是因为 eureka 自己也是微服务 port: 10086 # 这里是作为 eureka 微服务的注册,为了以后多个 eureka 微服务能互相通信 spring: application: # 配置的是 eureka的服务名称 name: eureka-server eureka: client: service-url: # 配置的是 eureka 的地址信息 defaultZone: http://127.0.0.1:10086/eureka -
开启
Eureka微服务在引导类上添加注解
@EnableEurekaServer@SpringBootApplication @EnableEurekaServer public class EurekaServer { public static void main(String[] args) { SpringApplication.run(EnableEurekaServer.class, args); } } -
通过配置的地址跳转到对应的页面说明成功
EurekaServer 初始化会注册自己吗
-
会的,
EurekaServer会注册自己。从下图可以看出,在初始话的时候会把自己注册到
Eureka当中。
如何创建 Eureka 客户端(EurekaClient)
-
引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> -
设置配置
# 这里是作为 eureka-client 的注册 spring: application: # 配置的是 eureka的服务名称 name: userService eureka: client: service-url: # 根据 url 注册到对应的 EurekaServer defaultZone: http://127.0.0.1:10086/eureka -
当我们在
EurekaServe服务端看到对应的名称的服务已经完成注册即完成
提供者和消费者在 Eureka 中担任什么角色
- 提供者和消费者在
Eureka中都是EurekaClient,都是属于客户端。 - 只有
EurekaServer是客户端,用来注册和监控以及查询的作用。
idea 一个服务如何启动多个实例
- 已经有关键字了自己去找吧
- 【微服务】idea同一个服务复制启动多个实例_@大吉的博客-CSDN博客_微服务多实例
Eureka 如何体现服务队列
- 通过服务名称来区分服务队列。
若干个相同服务名称不同功能的客户端服务在同一个服务端会怎么样
-
他们会因为服务名称相同所以在同一个服务端以服务队列的形式体现。
-
我们从此得出一个结论,服务队列的分配依据之一是根据客户端的服务名称来完成。
什么是服务的发现
- 服务的发现也可以被称为服务的拉取,是消费者向
EurekaServer拉去对应服务名称的提供者的信息。
如何实现服务的发现
-
将
url的ip路径换为要拉取的提供者者的服务名称。public Order queryOrderById(Long orderId) { // 1.查询订单 Order order = orderMapper.findById(orderId); // 2. 利用 RestTemplate 发送 http 请求到对应的 微服务中 String url = "http://user-service/user/" + order.getUserId(); User user = restTemplate.getForObject(url, User.class); // 3. 封装 User 到 Order 中。 order.setUser(user); // 4.返回 return order; } -
在
RestTemplate类上添加负载均衡注解@LoadBalanced/** * 创建 RestTemplate 并注入 spring 容器。 * @return RestTemplate */ @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } -
这样子就可以实现服务的发现。默认的负载均衡是两个提供者服务器轮询服务。
总结 Eureka 总体流程
-
搭建
Eureka Server-
引入
eureka-server依赖<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> -
添加
@EnableEurekaServer注解@SpringBootApplication @EnableEurekaServer public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); } } -
在配置文件中配置
eureka地址# 这里是作为 eurekaServer 微服务的注册,为了以后多个 eureka 微服务能互相通信 spring: application: # 配置的是 eureka的服务名称 name: eureka-server eureka: client: service-url: # 配置的是 eureka 的地址信息 defaultZone: http://127.0.0.1:10086/eureka
-
-
服务注册
-
引入
eureka-client依赖<!--Eureka客户端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> -
在配置文件中配置服务名称和
eureka服务器地址# 配置服务名称 spring: application: name: order-service # 配置 eureka 服务器地址 eureka: client: service-url: # 根据 url 注册到对应的 EurekaServer defaultZone: http://127.0.0.1:10086/eureka
-
-
服务发现
-
在提供者和消费者都已注册
-
消费者通过服务提供者的服务名称远程调用
通过
url调用restTemplate.getForObject方法去远程调用public Order queryOrderById(Long orderId) { // 1.查询订单 Order order = orderMapper.findById(orderId); // 2. 利用 RestTemplate 发送 http 请求到对应的 微服务中 String url = "http://user-service/user/" + order.getUserId(); User user = restTemplate.getForObject(url, User.class); // 3. 封装 User 到 Order 中。 order.setUser(user); // 4.返回 return order; } -
在
RestTemplate类上添加负载均衡注解@LoadBalanced/** * 创建 RestTemplate 并注入 spring 容器。 * @return RestTemplate */ @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); }
-
Ribbon 负载均衡
负载均衡在微服务中起到了什么作用
-
为消费者向注册器拉去提供者信息并根据负载均衡算法选择一个进行远程调用
负载均衡如何在微服务里面实现
-
这是详解图,下面就让我们一起来看看如何实现
-
首先
LoadBalancerInterceptor类获取到消费者传入的uri,通过uri获取到提供者的服务名称。将服务名称传入RibbonLoadBalancerClient类当中。 -
RibbonLoadBalancerClient类获取到了服务名称,便向Eureka注册器拉取对应提供者的服务列表,然后通过getServer传入ZoneAwareLoadBalancer类中。 -
ZoneAwareLoadBalancer获取到服务列表之后,将其传至BaseLoadBalancer类中进行负载均衡选择。 -
BaseLoadBalancer类中通过IRule类型的rule选择了对应的负载均衡规则并返回。 -
最后返回到
LoadBalancerInterceptor类,修改url,拿到真实的ip地址和端口号来代替原来的服务名称,并对提供者发起请求。
负载均衡的常用策略有哪些
如何自定义负载均衡的策略
-
通过代码的方式进行调整
通过配置类设置全局的负载均衡规则
@Bean public IRule iRule() { // 根据自己的实际选择返回对应的负载均衡策略 return new RoundRobinRule(); } -
通过配置文件的方式进行调整
通过配置文件设置单一服务的负载均衡规则
# 服务名称 userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务 ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则
代码实现和配置文件实现的自定义负载均衡策略有什么区别
- 代码实现的负载均衡策略作用域是全体服务,即消费者调用任何服务
- 代码方式配置灵活,但修改时需要重新打包发布
- 配置文件的负载均衡策略作用域是指定服务,指消费者调用特定服务
- 配置方式直观方便,无需重新打包发布,但是无法做到全局配置
- 当两者共存的时候,必定会有冲突。所有的策略都是按照代码实现的负载均衡策略来实现。
Ribbon负载均衡的默认加载机制是什么
Ribbon默认的加载机制是懒加载,即当服务第一次访问的时候才会去创建LoadBalanceClient,请求时间长。
什么是饥饿加载
- 饥饿加载不同于
Ribbon默认的懒加载。当服务启动的时候便会去创建LoadBalanceClient,缩短第一次请求时间,但是增加设备负担。
如何开启饥饿加载
-
通过配置配置文件开启指定服务名称的饥饿加载
ribbon: eager-load: enabled: true # 开启饥饿加载 clients: - userservice # 指定服务名称,这是个服务名称列表