一.Ribbon负载均衡
在上一节中,我们通过在RestTemplte实例中加上了注解 @LoadBalanced,表示将来由RestTemplate发起的请求会被Ribbon拦截和处理,实现了访问服务时的负载均衡,那么他是如何实现的呢?
1.1 Ribbon负载均衡的原理
Ribbon实现负载均衡的流程如上图所示,order-service需要请求user-service的服务,根据user-service在eureka注册中心的注册的服务名称是userservice,order-service直接使用usersivce作为“IP地址+端口号”进行访问,发起了请求http:userservice/user/1,然后Ribbon会收到该请求,于是访问eureka注册中心拉取userservice所有的服务列表,然后负载均衡访问中的一个。
具体的Ribbon的负载均衡实现原理如上图所示:
- 1.order-service发送的请求会被LoadBalancerInterceptor负载均衡拦截器拦截
- 2.由RibbonLoadBanlancerClient获取url中的服务id(就是你注册的服务名称)userservice
- 3.将该服务id交给DynamicServerListLoadBalancer,从eureka注册中心中拉取服务列表,并根据IRule选择一个负载均衡的策略,比如随机调度,轮询调度等选择某个服务。
- 4.将该服务返回给RibbonLoadBanlacnedClient
- 5.RibbonLoadBanlacnedClient修改url并发起请求。
1.2 Ribbon负载均衡的策略
有多种负载均衡的策略,默认是轮询,如果想要自己修改负载均衡的策略,需要在对应的服务中(该服务访问其他服务)进行配置.
方式一
代码方式,在比如order-service的application中提供一个定义一个新的IRule,该方式是全局配置,只要配置之后,无论是在order-service中调用哪个微服务,都会执行该负载均衡的策略;
/*** 代码方式配置负载均衡策略* @return*/@Beanpublic IRule randomRule(){return new RandomRule();}
方式二
配置yml方式,局部配置,配置某一个微服务的访问时的负载均衡的策略。
# 配置某个服务的负载均衡策略
userservice:ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡的策略
1.3 Ribbon饥饿加载
首先,明确什么是懒加载与饥饿加载?
懒加载(Lazy Loading)是一种延迟加载数据或资源的策略,它通常在需要时才加载数据,而不是在初始化时就立即加载。这个概念在软件开发中经常被用来提高性能和减少资源消耗。
“饥饿加载”(Eager Loading)是一种加载数据或资源的策略,它与懒加载相对。在饥饿加载中,数据或资源在初始化或启动时就被加载,而不管是否立即需要使用。
Ribbon默认是采用懒加载,即第一次访问时才会创建LoadBanlacnedClient,因此第一次请求的时间会很长,但之后就好了(因为加载好的内容会被缓存到内存中)。
修改Ribbon的加载方式为饥饿加载,于是便会在项目启东时就创建LoadBanlacnedClient,降低第一次访问的耗时,通过配置的方式开启饥饿加载。
# 配置饥饿加载
ribbon:eager-load:enabled: true
二.Nacos安装与入门
Nacos(全称为"Dynamic Naming and Configuration Service")是阿里巴巴开源的一款服务发现、配置管理和服务管理平台。它可以帮助开发者轻松构建云原生应用,实现动态服务发现、服务注册与配置管理,并提供服务治理、流量管理等功能。
2.1 认识Nacos
Nacos也是服务注册中心,但是相对Eureka有着更加丰富的功能,且在国内更受欢迎。
2.2 安装Nacos
当前使用的Nacos的版本是1.4.1,直接解压安装包即可。可以在nacos/conf目录下的application.properties文件中修改端口号信息,默认是8848(8848钛金手机,成功男人的标志)。
2.3 启动Nacos
进入Nacos安装目录下的bin目录,输入命令:
startup.cmd -m standalone
启动成功截图,然后按住ctrl+点击启动地址即可启动
登陆的默认账号和密码都是nacos,登陆成功页面
2.4 Nacos快速入门
由于Nacos是后续加入的,所以父工程spring-cloud的依赖并不包含之,需要在父工程中额外加入Nacos管理依赖。
1.修改依赖
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.5.RELEASE</version><type>pom</type><scope>import</scope>
</dependency>
将user-service,order-service中的原来eureka客户端依赖注释掉,修改为nacos客户端依赖。
<!-- nacos客户端依赖包 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2.修改配置文件
注释掉user-service,order-service的eureka服务注册信息的配置
在spring相关配置中添加:
cloud:nacos:server-addr: localhost:8848 # nacos服务地址
然后启动即可,nacos与eureka的其他代码都相同,只需要修改配置文件和导入依赖即可。修改之后直接启动各个服务,随后各个服务会被注册到nacos注册中心之中,如下图所示:
2.5 Nacos服务分级存储模型
Nacos还引入了服务集群的概念,在一个服务可以包含多个实例的同时(这点与eureka相同),每个实例还会有一个隶属的集群,比如北京集群,上海集群,广州集群,深圳集群,在一个服务需要调用另一个服务时应该尽可能的调用本地集群的服务,这样速度更快,延迟更低。
为服务实例配置集群属性
spring:cloud:nacos:discovery:cluster-name: HZ # 集群名称
配置好之后,启动user-service,user-service(1);
然后再修改集群名称为另一个:
spring:cloud:nacos:discovery:cluster-name: SH # 集群名称
再启动user-service(2).
此时user-service,user-service(1);会被部署到hz集群,user-service(2)会被部署到sh集群.
2.6 NacosRuler负载均衡
决定负载均衡的策略完全是由IRule决定的,当前order-service使用的是随机负载均衡策略
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡的策略
那么并不会按照集群本地访问优先的规则进行访问。所以修改负载均衡策略为NacosRule,优先选择本地集群,本地集群内使用随机方式访问。
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡的策略
配置之后,会优先访问同集群内服务user-service(hz集群)
user-service(1)(hz集群)
user-service(2)(sh集群)
当停掉HZ服务之后,只剩下SH服务:
仍能访问成功,但是order-service控制台会给出一个警告信息,提醒这是一个跨越集群的访问:
2.7 NacosRuler负载均衡的权重设置
当出现不同机器需要承担不同比例的请求时,就不能单纯的按照优先本地集群,集群内随机的方式负载均衡了。需要配置权重。直接在Nacos控制台配置权重即可,配置的权重通常是0-1之间,当某个服务的权重为0时,表示该服务不会被任何用户访问(可以用于不停服更新,丝滑过渡等场景)。
2.8 NacosRuler负载均衡的权重设置
Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做外层隔离。
namespace可以用于隔离开发环境,生产环境,测试环境等。
通过nacos控制台新建一个命名空间dev
可以看到,新建的命名空间dev中没有任何服务。
如果要修改服务所在命名空间,需要在代码中修改对应的服务yml配置文件。
spring:cloud:nacos:discovery:namespace: d3811bbe-1b14-449f-b984-85bdbcdf16dd # 命名空间ID
添加上述代码到order-service中,重启order-service服务,刷新nacos控制台,发现public命名空间中只剩下一个user-service;
命名空间dev中却有了order-service
此时由于二者位于不同的命名空间,二者便无法再相互访问…
2.9 Nacos与Eureka注册中心的比较
二者访问服务的逻辑基本一致。
区别一:服务提供者的健康检测
Nacos分为临时实例和非临时实例,二者的健康检测是不同的,临时实例的健康检测同Eureka,每隔30s向nacos注册中心报告一次状态(心跳检测),如果nacos注册中心在一定时间内未收到临时实例的报告,会直接认为该服务已经挂掉了,将该服务直接从列表中剔除。而非临时实例则是nacos主动询问目标服务,即使非临时服务挂掉了,nacos注册中心也不会把非临时实例从列表中剔除,而是会等着该服务,等着该服务回复健康。
区别二:服务消费者的获取服务方式不同
eureka的服务消费者只通过定时拉取服务的方式拉取服务列表pull,由于是定时拉取,因此当服务列表更新时,可能更新之后的服务获取不及时。
nacos的服务消费者不仅通过定时拉取服务的方式拉取服务列表pull,同时加入主动推送变更消息的机制push,这样当服务变更时可以及时的提醒服务消费者。
设置临时实例/非临时实例
默认为临时实例,在修改配置之后变为非临时实例。
spring:cloud:nacos:discovery:ephemeral: false # 设置为非临时实例