Ribbon是什么
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon的客户端组件提供一系列完整的配置项,如连接超时,重试等等。简单的说,就是在配置文件中列出LoadBalancer (简称LB: 负载均衡)后面所有的机器,Ribbon会自动的帮你基于某种规则(如简单轮询,随机连接等等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法!
什么是负载均衡
LB,即负载均衡(Load Balance),是微服务架构中经常使用的一种技术。负载均衡是我们处理高并发,环节网络压力和进行服务端扩容的重要手段之一,简单的说就是将用户的请求平摊的分配到多个服务上,从而实现系统的高可用(HA)性集群。常见的负载均衡软件有Nginx,Lvs等等,Dubbo和springCloud中均给我们提供了负载均衡,SpringCloud的负载均衡算法可以自定义。
服务端负载均衡:用户请求先到达负载均衡器(相当于一个服务),负载均衡器根据负载均衡算法将请求转发到微服务。负载均衡器维护一份服务端列表,根据负载均衡算法将请求转发到相应的微服务上,负载均衡算法有:轮训,随机,加权轮训,加权随机,地址哈希等方法,所以负载均衡可以为微服务集群分担请求,降低系统的压力。可以理解为:是一个URL先经过一个代理服务器(如nginx),然后这个代理服务器通过算法反向代理你的服务,来完成负载均衡。
客户端负载均衡:在客户端负载均衡中,每个客户端服务都有一份自己要访问的服务端清单,这些清单都要从Eureka服务注册中心获取,简单的理解为:一个请求在客户端的时候已经声明了要调用哪个服务,然后通过具体的负载均衡算法来完成负载均衡。
两者最大的区别是服务清单所存储的位置。
Ribbon负载均衡架构
SpringClound之Ribbon入门案例
1.引入Ribbon依赖
<!-- Ribbon 相关依赖,eureka会自动引入Ribbon -->
<!-- 由于依赖了spring-cloud-starter-netflix-eureka-client,
会自动添加spring-cloud-starter-netflix-ribbon依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.如何使用Ribbon
使用RestTemplate进行Eureka Client(包括服务提供者以及服务消费者,这里是服务消费者使用RestTemplate)之间的通信,为RestTemplate配置类添加@LoadBalanced注解即可,
@Configuration //标识配置类
public class ConfigBean {
///@LoadBalanced表示这个RestTemplate开启负载均衡,在调用服务提供者的接口时,
//可使用 服务名称 替代真实IP地址。服务名称 就是服务提供者在application.yml中
//配置的spring.application.name属性的值。
@LoadBalanced
@Bean // 向容器中添加 RestTemplate 组件,直接通过此组件可调用 REST 接口
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
启动类
@EnableEurekaClient //向服务注册中心进行注册
@SpringBootApplication
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class, args);
}
}
3.解决硬编码
Ribbon和Eureka整合后,消费者Consumer可以直接调用提供者服务,而不用关心地址和端口号。即使用添加@LoadBalanced注解后的RestTemplate调用服务提供者的接口时,可以使用虚拟IP替代真实IP地址。所谓的虚拟IP就是服务提供者在application.properties或yml文件中配置的spring.application.name属性的值。
// private static final String REST_URL_PREFIX = "http://localhost:8001";
//修改为Eureka注册中心的地址
//Ribbon 和 Eureka 整合后 ,消费者 Consumer 可以直接调用提供者服务,而不用再关心地址和端口号
private static final String REST_URL_PREFIX = "http://MICROSERVICE-PRODUCT";
微服务(服务提供者)集群搭建
server:
port: 8002
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径
type-aliases-package: com.dsx.domain # 所有Entity别名类所在包
mapper-locations: classpath:mybatis/mapper/**/*.xml # mapper映射文件
spring:
application:
name: microservice-product #这个很重要,这在以后的服务与服务之间相互调用一般都是根据这个name
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
driver-class-name: com.mysql.cj.jdbc.Driver # mysql驱动包
url: jdbc:mysql://127.0.0.1:3306/springcloud_db02?serverTimezone=GMT%2B8&characterEncoding=utf-8 # 数据库名称
username: root
password: 密码
dbcp2:
min-idle: 5 # 数据库连接池的最小维持连接数
initial-size: 5 # 初始化连接数
max-total: 5 # 最大连接数
max-wait-millis: 150 # 等待连接获取的最大超时时间
eureka:
client:
# 服务注册开关 开启
registerWithEureka: true
# 服务发现开关
fetchRegistry: true
# 客户端(服务提供者)注册到哪一个Eureka Server服务注册中心,多个用逗号分隔
serviceUrl:
#集群版 Eureka服务注册中心
defaultZone: http://eureka6001.com:6001/eureka,http://eureka6002.com:6002/eureka
instance:
instanceId: ${spring.application.name}:${server.port}#指定实例ID,就不会显示主机
preferIpAddress: true#访问路径可以显示IP地址
机器8001与上所示配置类似。
启动消费者发现,访问时Ribbon默认使用轮询算法去调用微服务。
Ribbon组件IRule
策略类 | 命名 | 说明 |
RoundRobinRule | 轮询策略 | 按顺序循环选择Server |
RandomRule | 随机策略 | 随机选择Server |
AvailabilityFilteringRule | 可用过滤策略 | 会先过滤掉由于多次访问故障处于断路器跳闸状态的服务,还有并发的连接数量超过阈值的服务,然后对于剩余的服务列表按照轮询的策略进行访问 |
RetryRule | 重试策略 | 先按照轮询的策略获取服务,如果获取服务失败则在指定的时间内会进行重试,获取可用的服务 |
BestAvailableRule | 最低并发策略 | 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量小的服务 |
ZoneAvoidanceRule | 区域权衡策略 | 默认规则,复合判断Server所在区域的性能和Server的可用性选择服务器 |
WeightedResponseTimeRule | 响应时间加载策略 | 根据平均响应时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越大。刚启动时如果同统计信息不足,则使用轮询的策略,等统计信息足够会切换到自身规则 |
使用:
@Configuration //标识配置类
public class ConfigBean {
///@LoadBalanced表示这个RestTemplate开启负载均衡,在调用服务提供者的接口时,
//可使用 服务名称 替代真实IP地址。服务名称 就是服务提供者在application.yml中
//配置的spring.application.name属性的值。
@LoadBalanced
@Bean // 向容器中添加 RestTemplate 组件,直接通过此组件可调用 REST 接口
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
@Bean
public IRule myRule() {
return new RetryRule();//在这里选择负载均衡算法
}
}
Ribbon实现自定义负载均衡算法,参考博客 https://blog.csdn.net/duan196_118/article/details/104345908
如有不足,欢迎留言指正,望不吝赐教!!!