SpringCloud学习笔记(四)之Ribbon负载均衡

    在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http restful的。Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign。

简介

是基于Netflix Ribbon实现的一套客户端负载均衡的工具。

简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。也很容易使用Ribbon实现自定义的负载均衡算法。

集中式LB

即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5,也可以是软件,如nginx),由该设施负责把访问请求通过某种策略转发到服务的提供方。

进程内LB

将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。

Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

配置初步

因为Ribbon是客户端的负载均衡工具,所以只能配置客户端:micoservicecloud-consumer-dept-80

配置pom.xml

在micoservicecloud-consumer-dept-80的pom.xml添加以下信息:

1<!-- Ribbon相关 --> 2<dependency> 3 <groupId>org.springframework.cloud</groupId> 4 <artifactId>spring-cloud-starter-eureka</artifactId> 5</dependency> 6<dependency> 7 <groupId>org.springframework.cloud</groupId> 8 <artifactId>spring-cloud-starter-ribbon</artifactId> 9</dependency> 10<dependency> 11 <groupId>org.springframework.cloud</groupId> 12 <artifactId>spring-cloud-starter-config</artifactId> 13</dependency>

 配置application.yml

在micoservicecloud-consumer-dept-80的application.yml添加以下信息:

1eureka: 2 client: 3 service-url: 4 defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ 5 register-with-eureka: false

Configuration配置类添加标签@LoadBalanced

controller层添加微服务地址

对应页面中的server的地址

启动类添加标签

小结

Ribbon和Eureka整合后Consumer可以直接调用服务而不用关心地址和端口号。

负载均衡案例

Ribbon在工作时分成两步:

第一步,先选择EurekaServer,它优先选择在同一个区域负载均衡较少的server。

第二步,再根据用户指定的策略,在从server取到的服务注册列表中选择一个地址。

其中Ribbon提供多种策略:比如轮询、随机和根据响应时间加权。

1. 另外创建两个maven工程:

micoservicecloud-provider-dept-8002

micoservicecloud-provider-dept-8003

2. 其他代码一样,需要修改红色部分,配置各自的application.yml文件:

1server: 2 port: 8002 #配置各自的端口号 3 4mybatis: 5 config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径 6 type-aliases-package: com.minn.springcloud.entities # 所有Entity别名类所在包 7 mapper-locations: classpath:mybatis/mapper/**/*.xml # mapper映射文件 8 9spring: 10 application: 11 name: micoservicecloud-dept #这name不能修改,三个配置文件一样 12 datasource: 13 type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型 14 driver-class-name: org.gjt.mm.mysql.Driver #mysql驱动包 15 url: jdbc:mysql://localhost:3306/clouddb02 #数据库名称,配置各自的数据库名字 16 username: root 17 password: 123456 18 dbcp2: 19 min-idle: 5 #数据库连接池的最小维持连接数 20 initial-size: 5 #初始化连接数 21 max-total: 5 #最大连接数 22 max-wait-millis: 200 #等待连接获取的最大超时时间 23 24#客户端注册进eureka服务列表内 25eureka: 26 client: 27 service-url: 28 defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka 29 instance: 30 instance-id: micoservicecloud-dept8002 #自定义服务名称信息 31 prefer-ip-address: true #访问路径可以显示IP地址 32 33info: 34 app.name: minn-microservicecloud 35 company.name: www.minn.com 36 build.artifactId: $project.artifactId$ 37 build.version: $project.version$

3. 创建另外两个数据库clouddb2,clouddb3。各自对应新创建的maven工程。 

1DROP DATABASE IF EXISTS clouddb03; 2 3CREATE DATABASE clouddb03 CHARACTER SET UTF8; 4 5USE clouddb03; 6 7CREATE TABLE dept( 8 deptno BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT, 9 dname VARCHAR(60), 10 db_source VARCHAR(60) 11); 12 13INSERT INTO dept(dname,db_source) VALUES('开发部',DATABASE()); 14INSERT INTO dept(dname,db_source) VALUES('人事部',DATABASE()); 15INSERT INTO dept(dname,db_source) VALUES('财务部',DATABASE());

4. 依次启动各自的启动类:

micoservicecloud-eureka-7001 ,micoservicecloud-eureka-7002,micoservicecloud-eureka-7003,

micoservicecloud-provider-dept-8001,micoservicecloud-provider-dept-8002,

micoservicecloud-provider-dept-8003,micoservicecloud-consumer-dept-80

5.  分别访问三个服务端页面,可以查到数据

6.  查看消费端界面

点击刷新按钮,发现轮询访问三个服务端界面,这就是通过****@LoadBalanced****

实现负载均衡。

核心组件IRule

根据特定算法中从服务列表中选取一个要访问的服务。

RoundRobinRule:轮询

RandomRule:随机

AvailabilityFilteringRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,还有并发的连接数量超过阀值的服务,然后对剩余的服务列表按照轮询策略进行访问。

WeightedResponseTimeRule:根据平均响应时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越高。刚启动时如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够,会切换到WeightedResponseTimeRule。

RetryRule:先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务。

BestAvailableRule:会先过滤由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务。

ZoneAvoidanceRule:默认规则,复合判断server所在区域的性能和server的可用性选择服务器。

自定义

需求:让每个微服务提供方被调用5次,再切换到下一个提供方。

1.  在启动类上加下面信息:

1//在启动该微服务的时候能去加载我们自定义Ribbon配置类,从而使配置生效 2@RibbonClient(name = "MICOSERVICECLOUD-DEPT",configuration = MySelfRule.class)

2. 创建MySelfRule的类

1package com.minn.myrule; 2 3import com.netflix.loadbalancer.IRule; 4import org.springframework.context.annotation.Bean; 5import org.springframework.context.annotation.Configuration; 6 7@Configuration 8public class MySelfRule { 9 @Bean 10 public IRule myRule(){ 11 return new RandomRule_ZY(); 12 } 13}

 注意:该类不能跟启动类在同一个包或者启动类的子包里,必须在别的包里。

3. 创建RandomRule_ZY类

1package com.minn.myrule; 2 3import com.netflix.client.config.IClientConfig; 4import com.netflix.loadbalancer.AbstractLoadBalancerRule; 5import com.netflix.loadbalancer.ILoadBalancer; 6import com.netflix.loadbalancer.Server; 7import java.util.List; 8 9public class RandomRule_ZY extends AbstractLoadBalancerRule { 10 private int total = 0; //总共被调用的次数,目前要求每台被调用5次 11 private int currentIndex = 0;//当前提供服务的机器号 12 public Server choose(ILoadBalancer lb , Object key){ 13 if(lb == null){ 14 return null; 15 } 16 Server server = null; 17 while(server == null){ 18 if(Thread.interrupted()){ 19 return null; 20 } 21 List<Server> upList = lb.getReachableServers(); 22 List<Server> allList = lb.getAllServers(); 23 24 int serverCount = allList.size(); 25 if(serverCount == 0){ 26 return null; 27 } 28 29 if(total<5){ 30 server = upList.get(currentIndex); 31 total ++; 32 }else{ 33 total = 0; 34 currentIndex ++; 35 if(currentIndex>=upList.size()){ 36 currentIndex = 0; 37 } 38 } 39 if(server == null){ 40 Thread.yield(); 41 continue; 42 } 43 if(server.isAlive()){ 44 return (server); 45 } 46 server = null; 47 Thread.yield(); 48 } 49 return server; 50 } 51 52 @Override 53 public void initWithNiwsConfig(IClientConfig iClientConfig) { 54 } 55 56 @Override 57 public Server choose(Object key) { 58 return choose(getLoadBalancer(),key); 59 } 60}
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

SpringCloud系列——Zuul 动态路由

  前言  Zuul是在SpringCloudNetflix平台上提供动态路由,监控,弹性,安全等边缘服务的框架,是Netflix基于jvm的路由器和服务器端负载均衡器,相当于是设备和Netflix流应用的Web网站后端所有请求的前门。本文基于上篇(SpringCloud系列——Ribbon负载均衡(https://www.

SpringCloud全家桶学习之客户端负载均衡及自定义负载均衡算法

一、Ribbon是什么?  SpringCloudRibbon是基于NetflixRibbon实现的一套客户端 负载均衡的工具(这里区别于nginx的负载均衡)。简单来说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix中间服务连接在一起。Ribbon客户端组件