上一篇:springCloud微服务—初始服务注册发现与配置中心之Consul
<spring-cloud.version>Hoxton.SR8</spring-cloud.version> <spring-boot.version>2.3.0.RELEASE</spring-boot.version>
为什么要用负载均衡?
随着互联网的发展,公司的业务流量越来越大,业务处理逻辑也越来越复杂,单台机器的性能已经跟不上公司业务发展,所以单机出现了很多弊端,所以有了微服务集群,使用多台机器,多个服务来进行性能的水平扩展以及避免单点故障。但是怎样把流量或负担来分担到不同的服务器上面那?为了解决这个问题就有了负载均衡技术。客户端的流量首先到达负载均衡服务器,由负载均衡服务器通过一定的调度算法将流量分发到不同的服务上,同时负载均衡服务器也会对应用服务器做健康检查,当发现故障节点时便可动态的将故障节点从应用集群中剔除掉,来保证系统的高可用。
何为负载均衡?
负载均衡(Load Balance简称LB):是一种集群技术,他将他特定的业务(网络服务,网络流量等)分担给多台网络设备(包括服务器,防火墙等)或多条链路,从而提高了业务处理能力,宝资了业务的高可靠性。
Ribbon本地负载均衡与Nginx服务端负载均衡的区别
Nginx是服务器负载均衡,客户端所有的请求都会交给Nginx,然后由Nginx实现转发请求,负载均衡是由服务端实现的。Ribbon本地负载均衡,在调用服务接口的时候,会在注册中心上获取注册信息服务列表之后缓冲到JVM本地,从而在本地实现RPC远程服务调用技术。
1.Ribbon是什么?为什么要使用Ribbon
Ribbon是Neflix发布的开源项目,后由spring Cloud开发团队封装到springCloud中,可以让我们轻松的将面向服务的rest请求自动转换成客户端负载均衡服务调用。功能是提供客户端的软件负载均衡算法和服务调度,ribbon是一个基于http和cp的客户端负载均衡工具,spring Cloud Ribbon虽然只是一个工具类框架,不像服务注册中心,配置中心,api网关那样需要独立部署,但是它几乎存在于每一个spring cloud构建的微服务和基础设施中,因为微服务间调用,api网关请求转发等内容,实际上都是通过ribbon来实现的。Ribbon客户端提供一系列完善的配置项,如:连接超时,重试等,也就是说,通过配置文件中列出LB后面所有的机器,ribbon会自动的帮助我们基于某种规则(轮询,随机等)去连接这些机器。
在微服务框架中,我们都会把一个服务部署多个,其他服务调用该服务的时候,如何保证负载均衡不得不去考虑,负载均衡可以增加系统的可用性和扩展性,当我们调用其他服务时,Ribbon可以很方便的实现负载均衡功能。
Ribbon架构图
Ribbon工作:首先选择EurekaServer,它优先选择在同一区域内负载较少的Server。然后再根据用户指定的策略,再从Server取到服务注册列表中选择一个地址,Ribbon提供了多种策略:轮询,随机,根据时间响应时间加权等。
2.创建服务—我们沿用之前的服务
springcloud-demo //父工程
|—springcloud-demo-eurekaserver 注册中心
|—springcloud-demo-provider //生产者
|—springcloud-demo-consumer //消费者
由于spring-cloud-starter-netflix-eureka-client自带了spring-cloud-starter-ribbon,所以不需要引入其他pom包;
2.1使用@LoadBalanced注解赋予RestTemplate负载均衡能力
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
2.2启动两个服务端;可以构建两个服务;或者通过springboot配置启动两个服务;我这里使用的是配置;不知道怎么配置的话可以在上面章节中寻找;
2.3编写客户方测试类,服务端我们还是使用之前的测试类,
package com.qizh.springclouddemo.common.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @ProjectName: springclouddemo
* @ClassName: ConsumerController
* @Description: 消费者测试类
* @Author: 86157
* @Date: 2022/5/21 2:04
*/
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/consumer/ping")
public String ping(){
return restTemplate.getForObject("http://springcloud-demo-provider/springcloud-demo-provider/ping",String.class);
}
}
2.4启动服务并测试http://localhost:8002/springcloud-demo-consumer/consumer/ping
通过后台我们发现生产者被我们交叉访问
到此我们就完成了简单的负载均衡,我们也可以通过配置类来完成策略调整
3.自定义路由规则:Ribbon的核心组件IRule:更改负载算法,由我们的轮询方式换成随机算法,需要自定义一个配置类:(注意:如果这个类放在了@ComponentScan所扫描的包以及子包下,自定义的这个配置类会被所有的Ribbon客户端所享用,达不到特殊定制的目的)
3.1、自定义配置类
package com.qizh.springclouddemo.config;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @ProjectName: springclouddemo
* @ClassName: MyselfRule
* @Description: 自定义负载均衡路由规则类
* @Author: 86157
* @Date: 2022/6/15 16:17
*/
@Configuration
public class MyselfRule {
@Bean
public IRule myRule(){
return new RoundRobinRule();
}
}
3.2、启动类增加@RibbonClient注解,并做配置
@RibbonClient(name = "springcloud-demo-provider",configuration = MyselfRule.class)
并注释原来RestTemplate上的注解
@Bean
// @LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
3.3、启动服务并测试http://localhost:8002/springcloud-demo-consumer/consumer/ping
4.Ribbon常用的配置项:(全局配置,指定服务进行配置)
4.1、全局配置
#Ribbon全局配置
ribbon:
ConnectTimeout: 1000 #服务请求连接超时时间(毫秒)
ReadTimeout: 3000 #服务请求处理超时时间(毫秒)
OkToRetryOnAllOperations: true #对超时请求启用重试机制
MaxAutoRetriesNextServer: 1 #切换重试实例的最大个数
MaxAutoRetries: 1 # 切换实例后重试最大次数
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #修改负载均衡算法
#负载均衡算法
#com.netflix.loadbalancer.RandomRule:从提供服务的实例中以随机的方式;
#com.netflix.loadbalancer.RoundRobinRule:以线性轮询的方式,就是维护一个计数器,从提供服务的实例中按顺序选取,第一次选第一个,第二次选第二个,以此类推,到最后一个以后再从头来过;
#com.netflix.loadbalancer.RetryRule:在RoundRobinRule的基础上添加重试机制,即在指定的重试时间内,反复使用线性轮询策略来选择可用实例;
#com.netflix.loadbalancer.WeightedResponseTimeRule:对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择;
#com.netflix.loadbalancer.BestAvailableRule:选择并发较小的实例;
#com.netflix.loadbalancer.AvailabilityFilteringRule:先过滤掉故障实例,再选择并发较小的实例;
#com.netflix.loadbalancer.ZoneAwareLoadBalancer:采用双重过滤,同时过滤不是同一区域的实例和故障实例,选择并发较小的实例。
4.2、针对某个服务的局部配置
springcloud-demo-provider:
ribbon:
ConnectTimeout: 1000 #服务请求连接超时时间(毫秒)
ReadTimeout: 3000 #服务请求处理超时时间(毫秒)
OkToRetryOnAllOperations: true #对超时请求启用重试机制
MaxAutoRetriesNextServer: 1 #切换重试实例的最大个数
MaxAutoRetries: 1 # 切换实例后重试最大次数
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #修改负载均衡算法