SpringCloud极简入门(五)客户端负载均衡Ribbon
作者:陈刚,叩丁狼高级讲师。原创文章,转载请注明出处。
一.什么是负载均衡
负载均衡,英文名称为Load Balance,其意思就是将负载分摊到多个操作单元上进行执行,即把请求分担到多个服务进行执行,简而言之就是当一个服务承担不住请求压力,那我可以多弄几个服务来分担,这些服务的职责是一致的。就好比超市收银台,当客户太多,一个收银台忙不过来那我可以多增加几个收银台来减少收银慢的压力,这就是负载均衡。
二.什么是Ribbon
负载均衡分为服务器端负载均衡和客户端负载均衡,服务器端负载均衡如:“nginx”,而Ribbon是一个实现了客户端负载均衡组件,它和RestTemplate结合或者和Feign结合可以很好地控制HTTP和TCP客户端的行为。它从EurekaServer拉取服务列表实现负载均衡,并实现了多种策略(算法):轮询,随机等
三.使用RestTemplate 和 Ribbon实现负载均衡
在我们的应用基础上要实现负载均衡我们至少得需要一个消费者服务和两个提供者服务,而我们已经有一个消费者服务和一个提供者服务,我们还需要构建一个提供者服务
1.在pom文件中添加ribbon依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
2.将项目Producer拷贝一分命名为Producer2作为第二个提供者服务
3.改造Producer2:修改端口为2223,其他配置跟Producer一致
注意Producer服务的application:name和Producer2服务的application:name服务名字是一致的,待会儿我们会根据相同的服务名字调用不同的服务实例达到负载均衡的目的。
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1111/eureka/ #注册中心服务地址
server:
port: 2223 #当前服务端口
spring:
application:
name: producer #当前服务ID
4.改造ProvideController,修改返回的内容为:“你好呀这里是另外一个producer服务”,而Producer服务该方法返回的内容是“你好呀这里是producer服务”。
@RestController //@Controller 和 @ResponseBody 的混合注解
public class ProvideController {
@RequestMapping("/provide")
public String provide(@RequestParam("name")String name){
return name+":你好呀这里是另外一个producer服务";
}
}
5.改造消费者 Consumer ,在定义RestTemplate的方法上加上@LoadBalanced注解,该注解赋予了RestTemplate负载均衡的能力
@SpringBootApplication
@EnableEurekaClient
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(Consumer1Application.class, args);
}
//通过@LoadBalanced注解表明这个restRemplate开启负载均衡的功能。
//RestTemplate是spring内置的http请求封装
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
6.访问测试:依次启动EurekaServer,Producer,Producer2,Consumer,地址栏输入“http://localhost:3333/consumer?name=zs” 调用消费方法,多次刷新交替出现 "zs:你好呀这里是producer服务"和"zs:你好呀这里是另外一个producer服务";说明已经实现了负载均衡,并且ribbon默认的采用轮询规则,现在的请求流程是:
image.png
此时访问:htpp://localhost/1111 你会看到已经注册了两个PRODUCER和一个CONSUMBER服务
image.png
四.自定义负载均衡算法-编码方式
从上面访问测试结果得知,Ribbon默认使用的负载均衡算法为轮循,负载算法有很多,SpringCloud实现的负载均衡算法如下:
image.png
BaseAvailableRule:选择请求最小的服务
RoundRobinRule:使用轮询的方式依次选择每个服务进行访问
WeightedResponseTimeRule:对RoundRobinRule的扩展,可以根据服务的运行情况来增加权重,并根据权重挑选实例。
RandomRule:从服务实例列表中数据选择一个服务进行访问
RetryRule:实现了重试机制的轮询选择
Spring Cloud允许您通过使用@RibbonClient声明自定义的负载均衡算法配置,@RibbonClient通过 name属性指定要调用的服务,通过configuration属性去指定该服务使用什么样的负载均衡算法配置,下面我们就来通过代码的方式实现自定义。
1.在主程序类上打上 @RibbonClient(name = "PRODUCER", configuration = FooConfiguration.class) 标签。
@SpringBootApplication
@EnableEurekaClient
//@RibbonClient可以去指定使用什么样的负载均衡算法去调用某个服务,
//而负载均衡算法就通过configuration指向的配FooConfiguration去指定
//RibbonClient : name指向要调用的提供者服务 PRODUCER,
//configuration指向自定义的负载均衡算法配置类 FooConfiguration
@RibbonClient(name = "PRODUCER", configuration = FooConfiguration.class)
public class Consumer1Application {
public static void main(String[] args) {
SpringApplication.run(Consumer1Application.class, args);
}
//通过@LoadBalanced注解表明这个restRemplate开启负载均衡的功能。
//RestTemplate是spring内置的http请求封装
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
2.定义 FooConfiguration,实现自定义负载均衡规则,特别注意 : 该类不能被放在打有@ComponentScan标签或者@SpringBootApplication标签的类的包及其子包中,因为该类不能被ComponetScan给扫描到,否则将会覆盖掉其他所有的RibbonClient,所以请给该类额外分一个包
@Configuration
public class FooConfiguration {
//通过方法返回的实例类型指定负载均衡算法规则
@Bean
public IRule ribbonRule(IClientConfig config) {
//RandomRule : 负载均衡规则:随机
//RoundRobinRule: 轮询
//WeightedResponseTimeRule:加权
return new RandomRule(); //负载均衡算法:随机
}
}
3.启动该项目,访问 :“http://localhost:3333/consumer?name=zs” 将会随机出现 “zs:你好呀这里是producer服务”和“zs:你好呀这里是另外一个producer服务”;
五.自定义负载均衡算法-配置方式
使用配置方式定义负载均衡规则更为简单,且优先于编码方式,只需要在application.yml配置文件中加入一个配置如下:
PRODUCER: #提供者服务ID
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #负载均衡规则-随机
WechatIMG7.jpeg