微服务4-Ribbon

ribbon

两种负载均衡

当系统面临大量的用户访问,负载过高的时候,通常会增加服务器数量来进行横向扩展(集群),多个服务器的负载需要均衡,以免出现服务器负载不均衡,部分服务器负载较大,部分服务器负载较小的情况。通过负载均衡,使得集群中服务器的负载保持在稳定高效的状态,从而提高整个系统的处理能力。

软件负载均衡:nginx,lvs
硬件负载均衡:F5
我们只关注软件负载均衡,
第一层可以用DNS,配置多个A记录,让DNS做第一层分发。
第二层用比较流行的是反向代理,核心原理:代理根据一定规则,将http请求转发到服务器集群的单一服务器上。

软件负载均衡分为:服务端(集中式),客户端。

服务端负载均衡:在客户端和服务端中间使用代理,nginx。

客户端负载均衡:根据自己的情况做负载。Ribbon就是。

客户端负载均衡和服务端负载均衡最大的区别在于 服务端地址列表的存储位置,以及负载算法在哪里

客户端负载均衡

image-20220125223015750

服务端负载均衡image-20220125223440714

Ribbon使用流程

image-20220125224048594

Ribbon组成

官网首页:https://github.com/Netflix/ribbon

ribbon-core: 核心的通用性代码。api一些配置。

ribbon-eureka:基于eureka封装的模块,能快速集成eureka。

ribbon-examples:学习示例。

ribbon-httpclient:基于apache httpClient封装的rest客户端,集成了负载均衡模块,可以直接在项目中使用。

ribbon-loadbalancer:负载均衡模块。

ribbon-transport:基于netty实现多协议的支持。比如http,tcp,udp等。

java使用

@GetMapping("/client6")
public Object client6() {
   
   // ribbon 完成客户端的负载均衡,过滤掉down了的节点
   ServiceInstance instance = lb.choose("provider");
   
   String url ="http://" + instance.getHost() +":"+ instance.getPort() + "/HelloWorld/getHi";
      
   String respStr = restTemplate.getForObject(url, String.class);

   return respStr;
}

负载均衡算法

默认实现:

ZoneAvoidanceRule(区域权衡策略):复合判断Server所在区域的性能和Server的可用性,轮询选择服务器。

其他规则:

BestAvailableRule(最低并发策略):会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务。逐个找服务,如果断路器打开,则忽略。

RoundRobinRule(轮询策略):以简单轮询选择一个服务器。按顺序循环选择一个server。

RandomRule(随机策略):随机选择一个服务器。

AvailabilityFilteringRule(可用过滤策略):会先过滤掉多次访问故障而处于断路器跳闸状态的服务和过滤并发的连接数量超过阀值得服务,然后对剩余的服务列表安装轮询策略进行访问。

WeightedResponseTimeRule(响应时间加权策略):据平均响应时间计算所有的服务的权重,响应时间越快服务权重越大,容易被选中的概率就越高。刚启动时,如果统计信息不中,则使用RoundRobinRule(轮询)策略,等统计的信息足够了会自动的切换到WeightedResponseTimeRule。响应时间长,权重低,被选择的概率低。反之,同样道理。此策略综合了各种因素(网络,磁盘,IO等),这些因素直接影响响应时间。

RetryRule(重试策略):先按照RoundRobinRule(轮询)的策略获取服务,如果获取的服务失败则在指定的时间会进行重试,进行获取可用的服务。如多次获取某个服务失败,就不会再次获取该服务。主要是在一个时间段内,如果选择一个服务不成功,就继续找可用的服务,直到超时。

切换负载均衡策略

注解方式

@Bean
	public IRule myRule(){
		//return new RoundRobinRule();
		//return new RandomRule();
		return new RetryRule(); 

自定义方式

@GetMapping("/client7")
public Object client7() {  
   List<ServiceInstance> instances = discoveryClient.getInstances("provider");       
   // 自定义轮训算法    
   // 随机
   int nextInt = new Random().nextInt(instances.size());
   AtomicInteger atomicInteger = new AtomicInteger(); 
   // 轮训
   int i = atomicInteger.getAndIncrement();
   instances.get(i % instances.size());      
   // 权重。。
   for (ServiceInstance serviceInstance : instances) {
	// int quanzhong =    serviceInstance.getMetadata(); // 权重  1-9     
   }           
   ServiceInstance instance = instances.get(nextInt);     
   String url ="http://" + instance.getHost() +":"+ instance.getPort() + "/getHi";     
   String respStr = restTemplate.getForObject(url, String.class);
   return respStr;
}

配置文件

针对服务定ribbon策略:

provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

给所有服务定ribbon策略:

ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

属性配置方式优先级高于Java代码。

Ribbon脱离Eureka

Ribbon可以和服务注册中心Eureka一起工作,从服务注册中心获取服务端的地址信息,也可以在配置文件中使用listOfServers字段来设置服务端地址。

ribbon.eureka.enabled=false
ribbon.listOfServers=localhost:80,localhost:81

image-20220125232852437

自动处理Url

	@Bean
	// 开启负载均衡
	@LoadBalanced
	RestTemplate restTemplate() {
		return new RestTemplate();
	}

接下来便可以使用资源地址调用服务

String url ="http://provider/getHi";
String respStr = restTemplate.getForObject(url, String.class);
posted @   gary2048  阅读(68)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示