Java Spring Cloud 负载均衡详解

网友投稿 242 2022-12-07

Java Spring Cloud 负载均衡详解

目录1. Ribbon 客户端负载均衡1.1 Ribbon 概述1.2 Ribbon 远程调用1.3 Ribbon 负载均衡1.4 Ribbon 负载均衡策略总结

1. Ribbon 客户端负载均衡

1.1 Ribbon 概述

Ribbon 是 Netflix 提供的一个基于 HTTP 和 TCP 的客户端负载均衡工具。

Ribbon主要有两个功能:

简化远程调用

负载均衡

客户端负载均衡和服务端负载均衡的区别

服务端负载均衡

负载均衡算法在服务端

由负载均衡器维护服务地址列表

客户端负载均衡

负载均衡算法在客户端

客户端维护服务地址列表

1.2 Ribbon 远程调用

Ribbon 可以简化 RestTemplate 的远程调用。

原来的 Provider 中的远程调用如下:

@GetMapping("/goods/{id}")

public Goods findGoodsById(@PathVariable("id") int id){

//演示discoveryClient 使用

List instances = discoveryClient.getInstances("eureka-provider");

//判断集合是否有数据

if(instances == null || instances.size() == 0){

//集合没有数据

return null;

}

ServiceInstance instance = instances.get(0);

String host = instance.getHost();//获取ip

int port = instance.getPort();//获取端口

System.out.println(host);

System.out.println(port);

String url = "http://"+host+":"+port+"/goods/findOne/"+id;

// 3. 调用方法

Goods goods = restTemplate.getForObject(url, Goods.class);

return goods;

}

使用 Ribbon 简化 restTemplate 调用:

1.在声明 restTemplate 的 Bean 时候,添加一个注解:@LoadBalanced

@Configuration

public class RestTemplateConfig {

@LoadBalanced

@Bean

public RestTemplate restTemplate(){

return new RestTemplate();

}

}

2.在使用 restTemplate 发起请求时,需要定义 url 时,host:port 可以替换为服务提供方的应用名称

@GetMapping("/goods2/{id}")

public Goods findGoodsbCsYmceGmById2(@PathVariable("id") int id){

String url = "http://EUREKA-PROVIDER/goods/findOne/"+id;

// 3. 调用方法

Goods goods = restTemplate.getForObject(url, Goods.class);

return goods;

}

1.3 Ribbon 负载均衡

1.既然要负载均衡,那么我们就需要启动多个 Provider 服务来构成集群,在启动前先对 Provider 改造一下,让它将端口号设置到商品标题上

package com.zt.provider.controller;

/**

* Goods Controller 服务提供方

*/

@RestController

@RequestMapping("/goods")

public class GoodsController {

@Value("${server.port}")

private int port;

@Autowired

private GoodsService goodsService;

@GetMapping("/findOne/{id}")

public Goods findOne(@PathVariable("id") int id){

Goods goods = goodsService.findOne(id);

goods.setTitle(goods.getTitle() + ":" + port);//将端口号,设置到商品标题上

return goods;

}

}

2.接下来以多例启动 Provider,选择 edit configurations --> 勾选 allow parallel run

3.然后分别以 8001 和 8002 端口号分别启动 Provider

4.启动 Consumer 进行测试

http://localhost:9000/order/goods2/1

采用轮询的方式,调用两个 8001 和 8002 两个 Provider

{"id":1,"title":"华为手机:8001","price":3999.0,"count":10000}

{"id":1,"title":"华为手机:8002","price":3999.0,"count":10000}

1.4 Ribbon 负载均衡策略

策略类

命名

描述

RandomRule

随机策略

随机选择server

RoundRobinRule

轮询策略

轮询选择, 轮询index,选择index对应位置的Server;

RetryRule

重试策略

对选定的负载均衡策略机上重试机制,在一个配置时间段内当选择Server不成功,则一直尝试使用subRule的方式选择一个可用的server;

BestAvailableRule

最低并发策略

逐个考察server,如果server断路器打开,则忽略,再选择其中并发链接最低的server

AvailabilityFilteringRule

可用过滤策略

过滤掉一直失败并被标记为circuit tripped的server,过滤掉那些高并发链接的server(active connections超过配置的阈值)或者使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个Server的运行状态;

ResponseTimeWeightedRule

响应时间加权重策略

根据server的响应时间分配权重,响应时间越长,权重越低,被选择到的概率也就越低。响应时间越短,权重越高,被选中的概率越高,这个策略很贴切,综合了各种因素,比如:网络,磁盘,io等,都直接影响响应时间

ZoneAvoidanceRule

区域权重策略

综合判断server所在区域的性能,和server的可用性,轮询选择server并且判断一个AWS Zone的运行性能是否可用,剔除不可用的Zone中的所有server

设置负载均衡策略

1.编码方式

在 Consumer 服务编写配置类,采用随即策略

package com.zt.consumer.config;

import com.netflix.loadbalancer.IRule;

import com.netflix.loadbalancer.RandomRule;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Confihttp://guration

public class MyRule {

@Bean

public IRule rule() {

return new RandomRule();

}

}

在启动类上设置给指定服务开启负载均衡策略,比如给 EUREKA-PROVIDER 开启策略 MyRule

package com.zt.consumer;

@SpringBootApplication

@EnableEurekaClient

@EnableDiscoveryClient

/*

配置Ribbon的负载均衡策略 name

* name:设置 服务提供方的 应用名称

* configuration:设置负载均衡Bean

*/

@RibbonClient(name="EUREKA-PROVIDER",configuration = MyRule.class)

public class ConsumerApp {

public static void main(String[] args) {

SpringApplication.run(ConsumerApp.class, args);

}

}

2.配置方式

# 配置的方式设置Ribbon的负载均衡策略

EUREKA-PROVIDER: # 设置的服务提供方的 应用名称

ribbon:

NFloadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 策略类

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBootTest单元测试报错的解决方案
下一篇:详细聊聊RabbitMQ竟无法反序列化List问题
相关文章

 发表评论

暂时没有评论,来抢沙发吧~