目录
前言
上篇文章通过restTemplate简单实现了服务的调用,但是应用场景下,更多的会用到负载均衡来提升并发处理的的能力,本章就介绍下服务负载均衡实现
一、本地idea中启动多个生产者服务
1、开启生产者服务sca-provider在本地上允许重复启动项目选项
2、去application.yml,更改他的端口号,每更改一个端口号,去启动一次(启动项目前要先启动nacos注册中心)
3、去nacos注册中查看,已经起了两个生产者sca-provider的服务实例
二、负载均衡实现
1.LoadBalancerClient实现基础负载均衡
LoadBalancerClient对象可以从nacos中基于服务名获取服务实例,然后在工程中基于特点算法实现负载均衡方式的调用,其本质上是springclound内置的一个接口,所以不用手动去创建对象,该接口继承了Ribbon接口,只有一个实现类RibbonLoadBalancerClient,再底层就是实现了IRule接口,完成负载均衡的算法
1、接着上次的代码,在sca-consumer的ConsumerController.java内新添加如下代码用来测试
/**
* @Value,取值方式为${},是读取配文件里面的对应配置的值,并赋值给下面的变量“ :”后面的8090是当未读到配置里的值时给的默认值
*/
@Value("${spring.application.name:8090}")
private String appName;
/**
* LoadBalancerClient是微服务当中的一个负载均衡客户端对象
* 借助此对象,可以基于服务名从nacos中获取多个服务实例
* 并且基于一定的负载均衡算法进行远端服务的调用
*/
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/consumer/doRestEcho2")
public String doRestEcho2(){
// 1、基于服务名获取服务实例
ServiceInstance serviceInstance = loadBalancerClient.choose("sca-provider");
//2、基于服务实例构建要访问的服务url
// %S表示占位符,方法后面的几个参数顺序代表在url中占位符的位置
String url = String.format("http://%s:%s/provider/echo/%s",serviceInstance.getHost(),serviceInstance.getPort(),appName);
System.out.println("request url:"+url);
return restTemplate.getForObject(url, String.class);
}
2、启动sca-consumer项目,在浏览器输入http://localhost:8090/consumer/doRestEcho2
不断的刷新,发现消费者在调用不同的生产者服务实例,实现了负载均衡
说明:这里多个实例并发提供服务的方式为负载均衡,这里的负载均衡实现默认是因为Nacos集成了Ribbon来实现的,Ribbon配合RestTemplate,可以非常容易的实现服务之间的访问。Ribbon是Spring Cloud核心组件之一,它提供的最重要的功能就是客户端的负载均衡(客户端可以采用一定算法,例如轮询访问,访问服务端实例信息),这个功能可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡方式的服务调用。
2.@LoadBalanced
@LoadBalanced注解用于创建一个负载均衡的RestTemplate对象上,并把该对象交给spring容器管理,该注解作用就是当RestTemplate对象携带服务名作为参数发起请求时,通过LoadBalancerInterceptor拦截器拦截所有请求,通过loadBalancer拿到服务名后进行核心的负载均衡实现,简化我们实现负载均衡的代码量
- 先在主启动类上创建一个新的RestTemplate对象,并添加@LoadBalanced注解
- 接着上次的代码,在sca-consumer的ConsumerController.java内新添加如下代码用来测试
- 实现负载均衡
三、Ribbon负载均衡策略
基于Ribbon方式的负载均衡,Netflix默认提供了七种负载均衡策略,对于SpringCloud Alibaba解决方案中又提供了NacosRule策略,默认的负载均衡策略是轮训策略。当系统提供的负载均衡策略不能满足我们需求时,我们还可以基于IRule接口自己定义策略。如图所示:
1、修改默认的负载均衡策略
1. 通过配置文件方式(推荐)
在sca-consumer的application.yml文件下添加如下配置
#修改默认客户端负载均衡的算法方式
sca-provider: #要访问的服务名称(该服务名可以有多个实例),若使用
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
2. 通过配置类添加新的负载均衡方式的对象(不推荐)
在主启动类或者配置类中添加如下代码
@Bean
public IRule ribbonRule(){
return new RandomRule();
}
3、验证
启动各服务后,再去调用接口http://localhost:8090/consumer/doRestEcho3,通过断点调试,可以看出调用的负载均衡策略算法已经改变
4. 总结
- 配置文件的方式更加的灵活,利于以后的项目在生产环境上配置的改动,只需要将这些配置写到配置中心,就可以不重启服务的方式来修改配置。
- 当提供的几种默认策略算法都不满足时,也可以自己去实现IRule接口,参考现有的几种实现类,写自己的策略算法