Spring Cloud(二)Eureka注册中心、Ribbon负载均衡、Nacos注册中心 | 您所在的位置:网站首页 › ribbon设置负载方式 › Spring Cloud(二)Eureka注册中心、Ribbon负载均衡、Nacos注册中心 |
文章目录
Eureka注册中心Eureka的作用搭建Eureka Server搭建Eureka Client服务发现
Ribbon负载均衡负载均衡流程负载均衡策略饥饿加载(饿汉式)
Nacos注册中心Nacos的安装服务注册Nacos服务分级存储模型集群负载均衡策略环境隔离原理分析配置管理配置自动刷新(热更新)多环境配置共享
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自身也是一个微服务,因此在启动时会自己注册自己。 第一步,引入依赖 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负载均衡 负载均衡流程
Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个子接口都是一种规则: 注:约定大于配置,因此代码方式的优先级要高于配置文件方式。 饥饿加载(饿汉式)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中的application.properties中可以修改端口,若8848端口已被占用,可以进行修改。 bin目录下有四个启动脚本,注意不要直接启动,而是通过命令行窗口用命令进行启动:
第一步,在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启动服务并测试 分级存储模型: 第一级是服务,例如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之间。同集群内的多个实例,权重越高被访问的频率越高。权重设置为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后,查看控制台
环境隔离总结: 每个namespace都有唯一的id服务设置namespace时要写id而不是名称不同namespace下的服务互相不可见 原理分析
②服务提供者分为临时实例和非临时实例,临时实例采用心跳监测,每隔一段时间会向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配置文件时,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这个文件一定会被加载,因此多环境共享配置可以写入这个文件。 多种配置的优先级
|
今日新闻 |
推荐新闻 |
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 |