Spring Cloud(二)Eureka注册中心、Ribbon负载均衡、Nacos注册中心 您所在的位置:网站首页 ribbon设置负载方式 Spring Cloud(二)Eureka注册中心、Ribbon负载均衡、Nacos注册中心

Spring Cloud(二)Eureka注册中心、Ribbon负载均衡、Nacos注册中心

2023-08-14 00:23| 来源: 网络整理| 查看: 265

文章目录 Eureka注册中心Eureka的作用搭建Eureka Server搭建Eureka Client服务发现 Ribbon负载均衡负载均衡流程负载均衡策略饥饿加载(饿汉式) Nacos注册中心Nacos的安装服务注册Nacos服务分级存储模型集群负载均衡策略环境隔离原理分析配置管理配置自动刷新(热更新)多环境配置共享

Eureka注册中心

在上一篇中,我们提到了服务调用。

但在服务调用中,存在一系列问题:

服务消费者该如何获取服务提供者的地址信息?如果有多个服务提供者,消费者该如何选择?消费者如何得知服务提供者的健康状态(是否宕机)? 在这里插入图片描述 Eureka的作用

在这里插入图片描述 通过使用Eureka,就可以解决服务调用所产生的问题了:

消费者如何获取服务提供者具体信息?

服务提供者启动时向eureka注册自己的信息。eureka保存这些信息。消费者根据服务名称向eureka拉取提供者信息。

如果有多个消费者,消费者该如何选择?

服务消费者利用负载均衡算法,从服务列表中挑选一个。

消费者如何感知服务提供者的健康状态?

服务提供者每隔30秒向EurekaServer发送心跳请求,报告健康状态。eureka会更新记录服务列表信息,心跳不正常会被剔除出列表。消费者可以拉取到最新的信息。

在Eureka架构中,微服务角色有两类:

EurekaServer:服务端,注册中心 记录服务信息心跳监控 EurekaClient:客户端 Provider:服务提供者,例如上例的user-service 注册自己的信息到EurekaServer每隔30秒向EurekaServer发送心跳 Consumer:服务消费者,例如案例中的order-service 根据服务名称从EurekaServer拉取服务列表基于服务列表做负载均衡,选中一个微服务后发起远程调用。 搭建Eureka Server

第一步,引入依赖

cloud-demo cn.itcast.demo 1.0 4.0.0 eureka-server org.springframework.cloud spring-cloud-starter-netflix-eureka-server org.springframework.boot spring-boot-maven-plugin

第二步,编写启动类,添加@EnableEurekaServer注解

package cn.itcast.eureka; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; /** * @version 1.0 * @Description * @Author 月上叁竿 * @Date 2022-05-04 19:15 **/ @SpringBootApplication @EnableEurekaServer public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class,args); } }

第三步,编写application.yml配置文件

server: port: 10086 spring: application: name: eurekaserver eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka/

Eureka自身也是一个微服务,因此在启动时会自己注册自己。 在这里插入图片描述

搭建Eureka Client

第一步,引入依赖

org.springframework.cloud spring-cloud-starter-netflix-eureka-client

第二步,编写application.yml配置文件

spring: application: name: userservice # user服务的服务名称 eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka/

如何模拟多实例

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

服务发现

步骤一:修改url路径,用服务名代替ip、端口

@Service public class OrderService { @Autowired private OrderMapper orderMapper; @Autowired private RestTemplate restTemplate; public Order queryOrderById(Long orderId) { // 1.查询订单 Order order = orderMapper.findById(orderId); // 2.得到user信息 ip 端口 修改为服务名称 String url = "http://userservice/user/" + order.getUserId(); User user = restTemplate.getForObject(url, User.class); // 3.将user信息进行封装 order.setUser(user); // 4.返回 return order; } }

步骤二:在order-service项目的启动类中的RestTemplate添加负载均衡注解

@Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } Ribbon负载均衡 负载均衡流程

在这里插入图片描述 当order-serivice发送请求后,Ribbon会对请求进行拦截,向eureka-server拉取user-service的信息,若查到则返回服务列表,通过Ribbon进行负载均衡,选择列表中的一个服务进行调用。

在这里插入图片描述

负载均衡策略

Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个子接口都是一种规则: 在这里插入图片描述 IRule的默认实现是ZoneAvoidanceRule,根据zone选择服务列表,然后轮询。 在这里插入图片描述 通过定义IRule实现可以修改负载均衡规则,有两种方式:

代码方式:在order-service中的OrderApplication类中,定义一个新的IRule:@Bean public IRule randomRule(){ return new RandomRule(); } 配置文件方式:在order-service的application.yml文件中,添加新的配置也可以修改规则:userservice: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #负责均衡规则

注:约定大于配置,因此代码方式的优先级要高于配置文件方式。

饥饿加载(饿汉式)

Ribbon默认采用懒加载,即第一次访问时才会创建LoadBalanceClient,请求时间会很长。

而饥饿加载则会在项目启动时就创建,从而降低第一次访问的耗时,通过以下配置开启饥饿加载:

ribbon: eager-load: # 指定对userservice这个服务进行饥饿加载,这里的clients可以是列表 clients: userservice enabled: true # 开启饥饿加载 Nacos注册中心

Nacos是阿里巴巴的产品,现在是Spring Cloud中的一个组件。相比Eureka功能更加丰富,在国内受欢迎程度较高。

Nacos的安装

GitHub的Release下载页:https://github.com/alibaba/nacos/releases 在这里插入图片描述 下载好压缩文件后,将其解压至非中文路径下,会有两个目录:

conf:配置文件bin:启动脚本

在conf中的application.properties中可以修改端口,若8848端口已被占用,可以进行修改。

bin目录下有四个启动脚本,注意不要直接启动,而是通过命令行窗口用命令进行启动:

在这里插入图片描述在这里插入图片描述 启动服务后,在浏览器键入http://localhost:8848/nacos/index.html#login

在这里插入图片描述 会进入Nacos的Web管理界面,密码账号均是nacos。

服务注册

第一步,在cloud-demo父工程中添加spring-cloud-alibaba的管理依赖

com.alibaba.cloud spring-cloud-alibaba-dependencies 2.2.5.RELEASE pom import

第二步,添加nacos的客户端依赖

com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery

第三步,修改user-service和order-service的application.yml,添加nacos地址

spring: cloud: nacos: server-addr: localhost:8848

启动服务并测试

在这里插入图片描述

Nacos服务分级存储模型

分级存储模型:

第一级是服务,例如user-service 第二级是集群,例如杭州或上海 第三级是实例,例如杭州机房的某台部署了userservice的服务器 在这里插入图片描述

服务跨集群调用问题

服务调用尽可能地选择本地集群的服务,跨集群调用延迟较高。

本地集群不可访问时,再考虑取访问其他集群。

在这里插入图片描述

服务集群属性

第一步,修改application.yml,添加如下属性

spring: cloud: nacos: server-addr: localhost:8848 discovery: cluster-name: SH # 集群名称

在Nacos控制台可以看到集群的变化

在这里插入图片描述

集群负载均衡策略

根据集群负载均衡

第一步,修改order-service的application.yml,设置集群为HZ

spring: cloud: nacos: server-addr: localhost:8848 # nacos服务地址 discovery: cluster-name: HZ # 集群名称

第二步,在order-service中设置负载均衡的IRule为NacosRule,这个规则优先会寻找与自己同集群的服务

userservice: ribbon: NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则

NacosRule负载均衡策略:

优先选择同集群服务实例列表。本地集群找不到提供者,才会去其他集群寻找。确定了可用实例列表后,再采用随机负载均衡挑选实例。

根据权重负载均衡

实际部署中会出现这样的场景:

服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的及其承担更多的用户请求。

Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高。

在这里插入图片描述 在Nacos控制台可以设置实例的权重值,首先选中实例后的编辑按钮,在弹出的界面中将权重设置为0.1,测试发现8081端口所在的服务被访问到的频率大大降低。

实例的权重控制总结:

Nacos控制台可以设置实例的权重值,0~1之间。同集群内的多个实例,权重越高被访问的频率越高。权重设置为0完全不会被访问。 环境隔离

Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用于做最外层隔离。

在Nacos控制台可以创建namespace,用于隔离不同环境

在这里插入图片描述

填写一个新的命名空间信息

在这里插入图片描述

保存后在后台可以看到命名空间信息

在这里插入图片描述

修改order-service的application.yml,添加namespace

spring: cloud: nacos: server-addr: localhost:8848 # nacos服务地址 discovery: cluster-name: HZ # 集群名称 namespace: 3e16f3b3-6ea4-47fa-af3c-abb2df9c598e # dev环境

重启order-service后,查看控制台

在这里插入图片描述 在这里插入图片描述 此时访问order-service,由于namespace的不同,会导致找不到userservice,控制台会报错。

环境隔离总结:

每个namespace都有唯一的id服务设置namespace时要写id而不是名称不同namespace下的服务互相不可见 原理分析

在这里插入图片描述 ①服务提供者在启动时会向Nacos注册服务信息,服务消费者启动后会向Nacos定时拉取服务列表,若有对应的服务,则返回列表信息给消费者,消费者通过负载均衡算法选择一个服务进行远程调用。

②服务提供者分为临时实例和非临时实例,临时实例采用心跳监测,每隔一段时间会向Nacos发送请求,以报告自身健康状态,若服务挂掉,一段时间不给Nacos发送请求,Nacos会将其进行剔除;非临时实例由Nacos主动询问其健康信息,若服务挂掉,Nacos不会对其进行剔除,而是等待其恢复正常。

③当服务信息变更时,Nacos会主动推送更新后的服务列表信息。

临时实例和非临时实例

服务注册到Nacos时,可以选择注册为临时或非临时实例,通过修改application.yml文件来进行配置:

spring: cloud: nacos: server-addr: localhost:8848 # nacos服务地址 discovery: cluster-name: HZ # 集群名称 namespace: 3e16f3b3-6ea4-47fa-af3c-abb2df9c598e # dev环境 ephemeral: false # 是否是临时实例

Nacos和Eureka的异同点

Nacos与Eureka的共同点 都支持服务注册和服务拉取。都支持服务提供者心跳方式做健康检测。 Nacos与Eureka的不同点 Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式。临时实例心跳不正常会被剔除,非临时实例则不会被剔除。Nacos支持服务列表变更的消息推送模式,服务列表更新更及时。Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式。 配置管理

Nacos不仅提供了注册服务,还提供了配置管理服务。 在这里插入图片描述 在这里插入图片描述 配置获取的步骤如下:

在这里插入图片描述 在项目启动后,会将nacos中配置文件内容和本地配置文件application.yml合并,然后再创建Spring容器,加载bean。

由于我们在编写nacos配置文件时,Data ID需要写服务名称,而我们对于服务名称的配置是在application.yml中的,这就造成了无法读取nacos配置文件,那要怎么做呢?

我们可以添加一个引导文件bootstrap.yml,它的优先级是要高于application.yml的。

引入Nacos的配置管理客户端依赖

com.alibaba.cloud spring-cloud-starter-alibaba-nacos-config

在userservice中的resource目录添加一个bootstrap.yml文件

spring: application: name: userservice # 服务名称 profiles: active: dev # 环境 cloud: nacos: server-addr: localhost:8848 # nacos地址 config: file-extension: yaml # 文件后缀名

测试

package cn.itcast.user.web; import cn.itcast.user.pojo.User; import cn.itcast.user.service.UserService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @Slf4j @RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @Value("${pattern.dateformat}") private String dateformat; /** * 路径: /user/110 * * @param id 用户id * @return 用户 */ @GetMapping("/{id}") public User queryById(@PathVariable("id") Long id) { return userService.queryById(id); } @GetMapping("now") public String now(){ return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat)); } }

将配置交给Nacos管理的步骤:

在Nacos中添加配置文件在微服务中引入Nacos的config依赖在微服务中添加bootstrap.yml,配置Nacos地址、当前环境、服务名称、文件后缀名。这些决定了程序启动时去Nacos读取哪个配置文件。 配置自动刷新(热更新)

Nacos中的配置文件变更后,微服务无需重启就可以感知。不过需要下面两种配置来实现。

方式一:在@Value注入的变量所在类上添加注解@RefreshScope

package cn.itcast.user.web; import cn.itcast.user.config.PatternProperties; import cn.itcast.user.pojo.User; import cn.itcast.user.service.UserService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @Slf4j @RestController @RequestMapping("/user") @RefreshScope public class UserController { @Autowired private UserService userService; @Value("${pattern.dateformat}") private String dateformat; /** * 路径: /user/110 * * @param id 用户id * @return 用户 */ @GetMapping("/{id}") public User queryById(@PathVariable("id") Long id) { return userService.queryById(id); } @GetMapping("now") public String now(){ return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat); } }

方式二:使用@ConfigurationProperties注解

package cn.itcast.user.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * @version 1.0 * @Description * @Author 月上叁竿 * @Date 2022-05-07 10:05 **/ @Component @Data @ConfigurationProperties(prefix = "pattern") public class PatternProperties { private String dateformat; } @Slf4j @RestController @RequestMapping("/user") //@RefreshScope public class UserController { @Autowired private UserService userService; // @Value("${pattern.dateformat}") // private String dateformat; @Autowired private PatternProperties properties; /** * 路径: /user/110 * * @param id 用户id * @return 用户 */ @GetMapping("/{id}") public User queryById(@PathVariable("id") Long id) { return userService.queryById(id); } @GetMapping("now") public String now(){ return LocalDateTime.now().format(DateTimeFormatter.ofPattern(properties.getDateformat())); } }

注意事项:

不是所有的配置都适合放到配置中心,维护起来比较麻烦。建议将一些关键参数,需要运行时调整的参数放到nacos配置中心,一般都是自定义配置。推荐使用第二种方式进行热更新。 多环境配置共享

微服务启动时会从Nacos中读取多个配置文件:

[spring.application.name]-[spring.profiles.active].yaml,例如:userservice-dev.yaml,环境配置[spring.application.name].yaml,例如:userservice.yaml,默认配置。

无论profile如何变化,[spring.application.name].yaml这个文件一定会被加载,因此多环境共享配置可以写入这个文件。

在这里插入图片描述

多种配置的优先级

在这里插入图片描述 [服务名]-[环境].yaml > [服务名].yaml > 本地配置



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有