spring cloud --- Ribbon 客户端负载均衡 + RestTemplate ---心得无熔断器
Posted 岑惜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring cloud --- Ribbon 客户端负载均衡 + RestTemplate ---心得无熔断器相关的知识,希望对你有一定的参考价值。
spring boot 1.5.9.RELEASE
spring cloud Dalston.SR1
1.前言
了解了 eureka 服务注册与发现 的3大角色 ,会使用RestTemplate 在消费者 调用提供者 的服务了,
那么如果引入了 集群 ,让提供者集群化 ,那么消费者如何调用 服务呢?
答案是使用 Ribbon 客户端负载均衡 ,与nginx不同 ,Nginx是服务端的负载均衡 ,Ribbon则是运行在客户端的,原理是客户端从eureka 获取服务列表信息 ,然后根据在客户端
配置文件定义的 Ribbon 负载均衡策略来寻找要访问具体是那台服务器【即服务提供者,因为是集群 ,因此是不同的服务器 运行一样的代码,做一样的事情,因此注册在eureka上的应用名是一样的 ,但是ip或端口不同】
2.操作
(1)在消费者 的 pom.xml引入 Ribbon依赖包
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency>
完成的pom.文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.atguigu.springcloud</groupId> <!-- 父级maven模块的工程名字--> <artifactId>microservicecloud</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.example</groupId> <artifactId>demo-my-cen-test</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo-my-cen-test</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!-- 引入同级的maven--> <dependency> <groupId>com.example</groupId> <artifactId>demo-my-cen-2-2</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!-- <dependency>--> <!-- <groupId>org.yaml</groupId>--> <!-- <artifactId>snakeyaml</artifactId>--> <!--<!– <version>${version}</version>–>--> <!-- </dependency>--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency><!-- 自己定义的api --> <groupId>com.atguigu.springcloud</groupId> <artifactId>microservicecloud-api</artifactId> <version>${project.version}</version> </dependency> <!-- Ribbon相关 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <!-- <dependency>--> <!-- <groupId>org.springframework.cloud</groupId>--> <!-- <artifactId>spring-cloud-starter-config</artifactId>--> <!-- </dependency>--> <!-- 修改后立即生效,热部署 --> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
(2)
工程结构
(3)配置 RestTemplate,注册bean, ,配合注解 @LoadBalanced ,开启负载均衡
完成的配置文件
package com.example.demomycentest.cfgBean; import com.netflix.loadbalancer.BestAvailableRule; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RetryRule; import com.netflix.loadbalancer.RoundRobinRule; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class MyConfigBean { @Bean ////添加注解@LoadBalanced,开启负载均衡。。。就这么简单 @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } //设置负载均衡策略 @Bean public IRule myRule() { //其他看看 https://www.cnblogs.com/htyj/p/10705472.html // //该策略通过遍历负载均衡器中维护的所有实例,会过滤调故障的实例,并找出并发请求数最小的一个,所以该策略的特征是选择出最空闲的实例 //return new BestAvailableRule(); //轮询策略,其实里面就是一个计数器 return new RoundRobinRule(); } }
更过负载均衡策略可以查看这篇博文 : https://www.cnblogs.com/htyj/p/10705472.html
基本常用的默认策略 有 :
- RandomRule:
实现了从服务实例清单中随机选择一个服务实例的功能
- RoundRobinRule:
实现了按照线性轮询的方式一次选择每个服务实例的功能
- RetryTule:
实现了一个具备重试机制的实例选择功能
- WeightedRespinseTimeRule:
该策略是对RoundRobinRule的扩展,增加了根据实例的运行情况来计算权重,并根据权重来挑选实例,已达到更优的分配效果。
- ClientConfigEnabledRoundRobinRule
该策略较为特殊,我们一般不直接使用它。因为它本身并没有实现什么特殊的处理逻辑,真如代码中所示,在他的内部定义了一个RoundRobinRule策略,而choose函数的实现也正是使用了RoundRobinRule的线性轮询机制,所以它实现的功能实际上RoundeRobinRule相同。
虽然不能直接使用该策略,但是可以通过继承该策略,默认的choose就实现了线性轮询机制,但是可以在子类中实现更高级的策略
- BestAvailableRule
该策略通过遍历负载均衡器中维护的所有实例,会过滤调故障的实例,并找出并发请求数最小的一个,所以该策略的特征是选择出最空闲的实例
(4)application.yml文件配置
server:
port: 565
spring:
application:
name: demo-my-cen-test
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包
url: jdbc:mysql://localhost:3306/clinic?characterEncoding=utf-8 # 数据库名称
username: root
password: mysql
dbcp2:
min-idle: 5 # 数据库连接池的最小维持连接数
initial-size: 5 # 初始化连接数
max-total: 5 # 最大连接数
max-wait-millis: 200 # 等待连接获取的最大超时时间
eureka:
client:
register-with-eureka: false # 当前微服务不注册到eureka中(消费端)
service-url:
defaultZone: http://localhost:7001/eureka/
# 如果有注册中心不在线,但是写上了地址,会报错
# ,http://localhost:7002/eureka/,http://localhost:7003/eureka/
(5)controller层
package com.example.demomycentest.controller; //import com.example.demomycen22.pojo.Food; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @Controller public class GGController { private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT1"; /** * 使用 使用restTemplate访问restful接口非常的简单粗暴无脑。 (url, requestMap, * ResponseBean.class)这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。 */ @Autowired private RestTemplate restTemplate; @RequestMapping("/bb") @ResponseBody public String bb(){ // Food d = new Food(); // d.setApple("苹果"); // d.setEgg("鸡蛋"); // System.out.println(d); System.out.println("调用服务,开启负载均衡Ribbon"); //使用restTemplate 直接调用 ,postForObject 是post请求方式 ,getForObject是get请求方式,根据服务提供者的接口选择,这个是需要提前知道服务提供者的接口格式的 return restTemplate.getForObject(REST_URL_PREFIX + "/ask", String.class); } }
(6)启动类需要使用注解@EnableEurekaClient ,注册为eureka客户端
3.测试
(1)提前准备好了2个 服务提供者作为集群,端口分别是8001,8003 ,一个服务注册中心,端口7001 ,本服务消费者端口565
(2)查看eureka控制面板
ok,运行正常
8001端口业务截图
8003端口业务截图
消费者565端口的业务 在 第二节(5)controller层 有源码,这里就不展示了
(3)去浏览器调用消费者接口 ,输入 http://localhost:565/bb
访问第一次
访问第2次
访问第三次
完美 !!!
因为是使用了轮询负载均衡策略 ,【就是轮流访问集群的每个服务器】,Ribbon会根据策略选择访问具体是哪个服务
以上是关于spring cloud --- Ribbon 客户端负载均衡 + RestTemplate ---心得无熔断器的主要内容,如果未能解决你的问题,请参考以下文章
笔记:Spring Cloud Feign Ribbon 配置
Spring Cloud Ribbon 整合 Hystrix
Spring Cloud Netflix:ribbon.NIWSServerListClassName 和ribbon.listOfServers 有啥区别?
如何覆盖 Spring Cloud Ribbon 中的ribbon.serverListRefreshInterval 默认值?