springcloud之ribbon负载均衡
目录
- 前言
- `ribbon` 实现负载均衡
- `Maven` 主要依赖
- `application.properties` 配置文件
- `eureka-client-producer` 服务提供方
- `eureka-client-consumer` 服务消费方
- `eureka-client-producer` 服务提供方的主要代码
- `service` 层
- `controller` 层
- 启动类
- `eureka-client-consumer` 服务消费方的主要代码
- `config` 配置类
- `service` 层
- `controller` 层
- 启动类
- 启动测试
- `eureka` 集群改单机
- 启动各个服务测试
- 测试
- `ribbon` 配置负载均衡策略
- `ribbon` 支持的策略
- 对某个服务配置启用某种策略
- 启动服务测试
前言
Ribbon
是 Netflix
开发的一个负载均衡组件,它在服务体系中起着重要作用,与其他 springcloud
组件结合可以发挥出强大作用,它的负载策略有多种,默认轮询,可配置超时重试
说到负载均衡,ribbon
与 lvs、nginx
不一样,nginx
是服务端负载均衡,ribbon
是客户端负载均衡,具体表现为客户端从注册中心拿到服务的所有实例,然后以负载均衡方式去调用服务,默认以轮询的方式去调用服务实例
ribbon
与 eureka
配合使用的大致架构如下
ribbon
实现负载均衡
在 上一篇 文章中,已实现 eureka
客户端的注册行为,本篇文章将实现 eureka
客户端的调用,即服务提供方提供接口供服务消费方来消费,调用,并实现 ribbon
的客户端负载均衡
依然使用上一篇文章的项目,如下
Maven
主要依赖
eureka-client-consumer
服务消费方项目添加如下依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
spring-cloud-starter-netflix-eureka-client
:如果已经引入了这个eureka
客户端的依赖,此时可以不需要引入上述spring-cloud-starter-netflix-ribbon
依赖了,因为eureka
客户端的依赖已经包含了
spring-cloud-starter-netflix-ribbon
依赖eureka-client-producer
:作为服务的提供方,需要提供接口供消费方使用。这里我们可以连接数据库,至于连接数据库,以及ORM
持久层框架的依赖,这里不再赘述,自己引入即可
application.properties
配置文件
eureka-client-producer
服务提供方
server.port=8080#注册进eureka的名称
spring.application.name=eureka-client-producer#JDBC 配置
spring.datasource.druid.url=jdbc:mysql://127.0.0.1:3306/shiro?characterEncoding=utf8&useSSL=false&autoReconnect=true&serverTimezone=UTC
spring.datasource.druid.username=root
spring.datasource.druid.password=123456
spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource#druid 连接池配置
spring.datasource.druid.initial-size=3
spring.datasource.druid.min-idle=3
spring.datasource.druid.max-active=10
spring.datasource.druid.max-wait=60000#指定 mapper 文件路径
mybatis.mapper-locations=classpath:org/example/mapper/*.xml
mybatis.configuration.cache-enabled=true
#开启驼峰命名
mybatis.configuration.map-underscore-to-camel-case=true
#打印 SQL 语句
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpleureka.client.service-url.defaultZone=http://eureka7001:8761/eureka/
eureka.instance.prefer-ip-address=true
eureka-client-consumer
服务消费方
server.port=8090#注册进eureka的名称
spring.application.name=eureka-client-consumereureka.client.service-url.defaultZone=http://eureka7001:8761/eureka/
eureka.instance.prefer-ip-address=true
eureka-client-producer
服务提供方的主要代码
service
层
查询数据库
@Slf4j
@Service
public class UserServiceImpl implements UserService {@Value(value = "${server.port}")private Integer port;@Autowiredprivate UserMapper userMapper;@Overridepublic ResultVo selectOne(Integer id) {log.info("服务提供方的端口为:" + port);User user = userMapper.selectByPrimaryKey(id);ResultVo resultVo = new ResultVo();BeanUtils.copyProperties(user, resultVo);resultVo.setPort(port);return resultVo;}
}
controller
层
对外提供的接口
@Slf4j
@Controller
@RequestMapping(path = "/user")
public class UserController {@Autowiredprivate UserService userService;@GetMapping(path = "/selectUserById")@ResponseBodypublic ResultVo selectUserById(Integer id) {return userService.selectOne(id);}
}
启动类
@EnableEurekaClient
@Slf4j
@SpringBootApplication
public class AppProducer {public static void main(String[] args) {SpringApplication.run(AppProducer.class, args);log.info("------AppProducer Running------");}
}
eureka-client-consumer
服务消费方的主要代码
config
配置类
@Configuration
public class UserConsumerConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}
service
层
@Slf4j
@Service
public class UserConsumerServiceImpl implements UserConsumerService {@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate LoadBalancerClient loadBalancerClient;/*** ribbon 实现负载均衡*/@Overridepublic ResultVo findOneById(Integer id) {// eureka-client-producer:是生产者端服务名称ResponseEntity<ResultVo> responseEntity = restTemplate.getForEntity("http://eureka-client-producer/user/selectUserById?id=" + id, ResultVo.class);ResultVo resultVo = responseEntity.getBody();assert resultVo != null;log.info("User为:" + resultVo.toString());log.info("调用服务提供方的端口为:" + resultVo.getPort());return resultVo;}
}
eureka-client-producer
:就是配置文件application.properties
配置的spring.application.name
的值
controller
层
@Slf4j
@Controller
@RequestMapping(path = "/UserConsumer")
public class UserConsumerController {@Autowiredprivate UserConsumerService userConsumerService;/*** ribbon 实现负载均衡*/@GetMapping(path = "/findOneById")@ResponseBodypublic ResultVo findOneById(Integer id) {return userConsumerService.findOneById(id);}
}
启动类
@EnableEurekaClient
@Slf4j
@SpringBootApplication
public class AppConsumer {public static void main(String[] args) {SpringApplication.run(AppConsumer.class, args);log.info("------AppConsumer Running------");}
}
启动测试
eureka
集群改单机
由于机器资源有限,服务启动太多有点卡,所以将 eureka
集群模式改为单机模式,以节省机器资源,配置文件 application.properties
改为如下
server.port=8761#false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
eureka.client.fetch-registry=false
#false表示不向注册中心注册自己
eureka.client.register-with-eureka=false
#集群版
#eureka.client.service-url.defaultZone=http://eureka7002:8762/eureka/,http://eureka7003:8763/eureka/
#单机版
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
#注册进对方注册中心展示的实例名称
eureka.instance.hostname=eureka7001
启动各个服务测试
分别启动 eureka-client-producer
,eureka-client-consumer
,eureka-server-one
,这 3
个服务项目,首先查看 eureka
注册中心的服务注册情况,浏览器输入:http://eureka7001:8761/
如下
- 为了测试负载均衡,对
eureka-client-producer
服务要启动两个实例,即启动两个端口不同的实例服务;一个端口为8080
,一个为8070
测试
使用 postman
测试接口,也就是接口 http://127.0.0.1:8090/UserConsumer/findOneById?id=1
我们发送 5
次请求,查看控制台日志情况,如下
观察日志,可以看到服务提供方 eureka-client-producer
分别以 8080,8070
端口被调用,并且是轮询的方式,这也印证了 ribboon
是默认以轮询的方式去调用服务实例
ribbon
配置负载均衡策略
ribbon
支持的策略
ribbon
支持 7
种负载均衡策略
策略类 | 命名 | 描述 |
---|---|---|
RandomRule | 随机策略 | 随机选择 server |
RoundRobinRule
|
轮询策略
|
按照顺序选择 server ( 默认策略)
|
RetryRule | 重试策略 | 在一个配置时间段内,当选择 server 不成功,则一直尝试选择一个可用的 server |
BestAvailableRule | 最低并发策略 | 逐个考察 server,如果 server 断路器打开,则忽略,再选择其中并发链接最低的 server |
AvailabilityFilteringRule | 可用过滤策略 | 过滤掉一直失败并被标记为 circuit tripped 的 server,过滤掉那些高并发链接的 server(active connections 超过配置的阈值) |
ResponseTimeWeightedRule | 响应时间加权重策略 | 根据 server 的响应时间分配权重,响应时间越长,权重越低,被选择到的概率也就越低。响应时间越短,权重越高,被选中的概率越高,这个策略很贴切,综合了各种因素,比如:网络,磁盘,io 等,都直接影响响应时间 |
ZoneAvoidanceRule | 区域权重策略 | 综合判断 server 所在区域的性能,和 server 的可用性,轮询选择 server 并且判断一个 AWS Zone 的运行性能是否可用,剔除不可用的 Zone 中的所有 server |
对某个服务配置启用某种策略
在服务消费方 eureka-client-consumer
的配置类 UserConsumerConfig
中添加如下配置
/*** 配置随机负载均衡策略*/
@Bean
public IRule ribbonRule() {return new RandomRule();
}
启动服务测试
postman
测试接口如下
我们发送 9
次请求,查看控制台日志情况,如下
可以看到,我们配置的随机负载均衡策略已经生效
springcloud之ribbon负载均衡相关推荐
- SpringCloud:Ribbon负载均衡(基本使用、 负载均衡、自定义配置、禁用 Eureka 实现 Ribbon 调用)
现在所有的服务已经通过了 Eureka 进行了注册,那么使用 Eureka 注册的目的是希望所有的服务都统一归属到 Eureka 之中进 行处理,但是现在的问题,所有的微服务汇集到了 Eureka 之 ...
- SpringCloud的Ribbon负载均衡
Spring Cloud Ribbon相关学习: 简介 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具. 简单的说,Ribbon是Netflix ...
- SpringCloud[04]Ribbon负载均衡服务调用
文章目录 Ribbon负载均衡服务调用 1. 概述 1. Ribbon是什么 2. Ribbon能做什么 2. Ribbon负载均衡演示 1. 架构说明 2. Ribbon的POM依赖 3. Rest ...
- 【SpringCloud】Ribbon:负载均衡
什么是Ribbon? 并且Eureka中已经集成了Ribbon,所以我们无需引入新的依赖 如果要引入也是可以以的,依赖如下 <dependency><groupId>org.s ...
- 第六章 SpringCloud之Ribbon负载均衡
###################使用默认的负载均衡(轮询)############################# 1.pom.xml <?xml version="1.0&q ...
- 【SpringCloud】Ribbon 负载均衡
文章目录 1.概述 1.1 Ribbon在工作时分成两步 1.2 引入 1.2 替换方式 2.负载算法 2.1 IRule 接口 2.2 拓扑图 3. 负载均衡算法 4.RoundRobinRule源 ...
- SpringCloud源码:Ribbon负载均衡分析
本文主要分析 SpringCloud 中 Ribbon 负载均衡流程和原理. SpringCloud版本为:Edgware.RELEASE. 一.时序图 和以前一样,先把图贴出来,直观一点: 二.源码 ...
- JavaEE进阶知识学习-----SpringCloud(六)Ribbon负载均衡
Ribbon负载均衡 Ribbon概述 Spring Cloude Ribbon是基于Netfilx Ribbon实现的一套客户端 负载均衡的工具,简单说,Ribbon是Netfilix发布的开源项目 ...
- SpringCloud系列五:Ribbon 负载均衡(Ribbon 基本使用、Ribbon 负载均衡、自定义 Ribbon 配置、禁用 Eureka 实现 Ribbon 调用)...
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:Ribbon 负载均衡 2.具体内容 现在所有的服务已经通过了 Eureka 进行了注册,那么使用 Eureka 注册 ...
- 四、SpringCloud——Ribbon负载均衡Ribbon自定义
1 Ribbon简介 1)是什么 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具. 简单的说,Ribbon是Netflix发布的开源项目,主要功 ...
最新文章
- Android --- 解决 registerLocationListener 过时问题(百度地图)API
- 数据库oracle 笔试,数据库oracle笔试
- c语言scanf()函数的原理
- 清北学堂模拟day4 捡金币
- AMPL_网络项目问题
- 地铁票务管理系统_地铁票务管理是干什么
- 如何下载海淀区卫星地图高清版大图
- 计算机d盘无法格式化,为什么不能格式化D盘?D盘无法格式化的解决方法
- 学习verilog的经典好教材与资料
- 谈谈对java线程的理解(五)--------ReentrantLock之阻塞队列
- html5 视差地图,用HTML5构建高性能视差网站的图文代码详解
- JavaScript实现二级联动下拉菜单
- 查看tomcat的端口号
- 基于嵌入式技术的网络视频监控系统
- 再见!北京!再见!百度!
- 异或运算与奇偶校验的作用
- 21、backtrader的一些基本概念---市价单(market order)的创建和撮合逻辑
- Unity实现安卓游戏自动下载更新、安装。
- 花开花落,从前之前,后来以后
- 金融系-金融学名词解释汇编
热门文章
- 阿里云云计算 14 使用阿里云中的OSS
- 机器学习- 吴恩达Andrew Ng 编程作业技巧
- mod java 求余_java中求余%与取模floorMod的区别
- php_eol为什么没有换行,PHP PHP_EOL 换行符
- Tensor is not an element of this graph 解决方法
- python 中的[::-1]和[:-1]
- 回来bool的函数无return时返回true还是false
- EM 算法的推导和解释
- html评分图标,Bootstrap图标实现移动端的星星评分功能
- 用户增删改查 django生命周期 数据库操作