SpringCloud实战-Ribbon客户端负载均衡
前面我们已经完成了注册中心和服务提供者两个基础组件。接着介绍使用Spring Cloud Ribbon在客户端负载均衡的调用服务。
ribbon 是一个客户端负载均衡器,可以简单的理解成类似于 nginx的负载均衡模块的功能。
主流的LB方案可分成两类:
一种是集中式LB, 即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方;
另一种是进程内LB,将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于后者,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。
Ribbon的架构图:如下:
1.首先我们先在原来的基础上新建一个Ribbon模块,如下图:
现在我们单独使用ribbon,在Ribbon模块下添加依赖,如下图所示:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
修改application.yml文件,如下所示:
server:
port: 8082
spring:
application:
name: Ribbon-Consumer
#providers这个是自己命名的,ribbon,listOfServer这两个是规定的
providers:
ribbon:
listOfServers: localhost:8080,localhost:8081
在Ribbon模块下新建一个测试类如下代码 * Created by cong on 2018/5/8. */
@RestController
public class ConsumerController {
//注入负载均衡客户端
@Autowired
private LoadBalancerClient loadBalancerClient; @RequestMapping("/consumer")
public String helloConsumer() throws ExecutionException, InterruptedException {
//这里是根据配置文件的那个providers属性取的
ServiceInstance serviceInstance = loadBalancerClient.choose("providers");
//负载均衡算法默认是轮询,轮询取得服务
URI uri = URI.create(String.format("http://%s:%s", serviceInstance.getHost(), serviceInstance.getPort()));
return uri.toString();
}
运行结果如下:
会轮询的获取到两个服务的URL 访问第一次,浏览器出现http://localhost:8080 访问第二次就会出现http://localhost:8081
在这里给普及一下有哪些负载均衡算法:
1:简单轮询负载均衡(RoundRobin)
以轮询的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。
2:随机负载均衡 (Random)
随机选择状态为UP的Server
3:加权响应时间负载均衡 (WeightedResponseTime)
根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。
4:区域感知轮询负载均衡(ZoneAvoidanceRule)
复合判断server所在区域的性能和server的可用性选择server
有兴趣的还可以看一下我在Ngnix的随笔文章中列出的负载均衡算法实现:http://www.cnblogs.com/huangjuncong/p/8319182.html
如果想配置其他轮询算法在yml配置文件中配置,如下配置一个随机算法所示:
server:
port: 8082
spring:
application:
name: Ribbon-Consumer
#providers这个是自己命名的,ribbon,listOfServer这两个是规定的
providers:
ribbon:
listOfServers: localhost:8080,localhost:8081 ##如果不想选用默认的轮询的负载均衡算法,在这里做如下配置
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
接着在启动类动一下手脚让我们配置的随机算法的负载均衡生效,只需要实现一个实现了IRule接口的Bean即可,如下:
package hjc; import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate; @SpringBootApplication
public class RibbonApplication { public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
} @Bean
public IRule ribbonRule(){
return new RandomRule();
}
}
因此重新启动Ribbon启动类,得到的结果是随机的,如下所示:
浏览器随机出现http://localhost:8080 或者http://localhost:8081
那么问题来了,服务的地址是写死在配置文件中,如果某个服务挂了,那么还会把请求转发到挂掉的服务中,因此,解决的办法是,跟Eureka对接,结合一起用。就可以依靠Eureka动态的获取一个可用的服务列表,隔一段时间我就更新一次,
或者Eureka设置一个监听端口,某一个服务挂了,Eureka通知我,我会知道,变更服务列表,这样不久形成一个闭环了吗?这样就不存在高可用性问题了。跟Eureka配合一起用同时解决了的Ribbon的单点故障问题。
第一步,毫无疑问就是修改Ribbon模块的pom.xml文件,加入如下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
第二步,修改yml配置文件如下:
server:
port:
spring:
application:
name: Ribbon-Consumer eureka:
#客户端
client:
#注册中心地址
service-url:
defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/
这样就可以跟Eureka结合,这样Ribbon就可以通过Eureka动态的获取服务列表
接着在启动类加上服务发现注解,如下:
@EnableDiscoveryClient
启动类接着声明一个负载均衡的请求器@LoadBalanced,还有请求发起的工具RestTemplate
如下代码:
@SpringBootApplication
@EnableDiscoveryClient
public class RibbonApplication { public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
} @Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
} }
接着我们在上一节文章中的两个provider1,provider2模块添加一下测试代码:如下:
provider1:
package hjc.hello; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; /**
* Created by cong on 2018/5/8.
*/
@RestController
public class HelloController { @RequestMapping("/hello")
public String hello(){
return "hello1";
} }
provider2代码如下:
package hjc.hello; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; /**
* Created by cong on 2018/5/8.
*/
@RestController
public class HelloController { @RequestMapping("/hello")
public String hello(){
return "hello2";
} }
接着我们用RestTemplate进行面向服务调用,不再面向IP调用。
如下代码:
/**
* Created by cong on 2018/5/8.
*/
@RestController
public class ConsumerController { @Autowired
private RestTemplate restTemplate; @RequestMapping("/consumer")
public String helloConsumer() throws ExecutionException, InterruptedException { return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody(); }
接着启动Ribbon模块,我们看一下Eureka仪表盘,如下:
可以看到多了RIBBON-CONSUMER服务
接着我们继续在已经运行的Ribbon模块上,在浏览器输入localhost:8082,运行结果如下:
hello1或者hello2,
可以看到hello1 ,hello2轮询方式出现,因为默认就是轮询方式
到这里我们还发现Ribbon还是单点故障的,这里我来解释一下:
因为这里我是单独建立一个SpringBoot的Ribbon模块,实际使用并不是这样用的,Ribbon是客户端的负载均衡,是跟客户端绑定在一起的,我们实际运用的时候往往会在服务里面引入一个客户端负载均衡去连接到Eureka客户中心,
这样我们还存在Ribbon单点故障吗?不存在了,因为我们服务提供者就是高可用的,这样还是个单点吗?这里读者的思考必须转过弯来,这一篇随笔我只是为了演示Ribbon,实际使用并不是这样用的。
SpringCloud实战-Ribbon客户端负载均衡的更多相关文章
- springcloud 之Ribbon客户端负载均衡配置使用
pom.xml添加配置说明:这里服务注册与发现用的是Eureka,所以消费者端需要引入eureka,使用EurekaClient来调用服务 <dependency> <groupId ...
- SpringCloud实战2-Ribbon客户端负载均衡
https://www.cnblogs.com/huangjuncong/p/9022055.html
- springcloud(十二):Ribbon客户端负载均衡介绍
springcloud(十二):Ribbon客户端负载均衡介绍 Ribbon简介 使用分布式微服务脚骨的应用系统,在部署的时候通常会为部分或者全部微服务搭建集群环境,通过提供多个实例来提高系统的稳定型 ...
- spring cloud --- Ribbon 客户端负载均衡 + RestTemplate + Hystrix 熔断器 [服务保护] ---心得
spring boot 1.5.9.RELEASE spring cloud Dalston.SR1 1.前言 当超大并发量并发访问一个服务接口时,服务器会崩溃 ,不仅导致这个接口无法 ...
- spring cloud --- Ribbon 客户端负载均衡 + RestTemplate ---心得【无熔断器】
spring boot 1.5.9.RELEASE spring cloud Dalston.SR1 1.前言 了解了 eureka 服务注册与发现 的3大角色 ,会使用RestTem ...
- SpringBoot(三) - Ribbon客户端负载均衡,Zuul网关,Config配置中心
1.Ribbon客户端负载均衡 1.1 依赖 1.2 配置信息 # feign默认加载了ribbon负载均衡,默认负载均衡机制是:轮询 # 负载均衡机制是添加在消费端(客户端)的,如果改为随机,指定服 ...
- ③SpringCloud 实战:使用 Ribbon 客户端负载均衡
这是SpringCloud实战系列中第三篇文章,了解前面第两篇文章更有助于更好理解本文内容: ①SpringCloud 实战:引入Eureka组件,完善服务治理 ②SpringCloud 实战:引入F ...
- SpringCloud系列之客户端负载均衡Netflix Ribbon
1. 什么是负载均衡? 负载均衡是一种基础的网络服务,它的核心原理是按照指定的负载均衡算法,将请求分配到后端服务集群上,从而为系统提供并行处理和高可用的能力.提到负载均衡,你可能想到nginx.对于负 ...
- 笔记:Spring Cloud Ribbon 客户端负载均衡
Spring Cloud Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具,基于 Netflix Ribbon 实现,通过Spring Cloud 的封装,可以让我们轻松的将面向服 ...
随机推荐
- Linux信号实践(4) --可靠信号
Sigaction #include <signal.h> int sigaction(int signum, const struct sigaction *act, struct si ...
- (NO.00001)iOS游戏SpeedBoy Lite成形记(二十)
下面修改最为关键的matchRun方法里的代码: CCActionCallBlock *blk = [CCActionCallBlock actionWithBlock:^{ _finishedCou ...
- 018-继承-OC笔记
学习目标 1.[掌握]Xcode开发文档 2.[掌握]static关键字 3.[掌握]self关键字 4.[掌握]继承 5.[掌握]NSObject 6.[掌握]访问修饰符 7.[掌握]私有实例变量和 ...
- Dynamics CRM 通过OData查询数据URI中包含中文的情况
filter条件如下"?$filter=new_name eq '采购主管' and new_entityname eq 'new_purchaseenquiry' ",如果用这个 ...
- Mahout 系列之----共轭梯度
无预处理共轭梯度 要求解线性方程组 ,稳定双共轭梯度法从初始解 开始按以下步骤迭代: 任意选择向量 使得 ,例如, 对 若 足够精确则退出 预处理共轭梯度 预处理通常被用来加速迭代方法的收敛.要使用预 ...
- SpriteBuilder使用Shader Effect的另一种方法
记住你并不是必须要使用Effect节点去给一个特定的精灵应用效果. 你只要选择一个精灵然后切换至项目属性窗口(Item Properties tab),找到effects用户接口在CCSprite属性 ...
- OpenCV 使用光流法检测物体运动
OpenCV 可以使用光流法检测物体运动,贴上代码以及效果. // opticalflow.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" ...
- Linux文件系统管理命令(第二版)
Linux文件系统管理命令 常用命令 1.df命令 查看分区使用情况 常用选项 -h 比较人性化 -m 以兆字节显示分区使用情况 显示信息: Mounted on:挂载点 Filesystem:对应的 ...
- SpriteBuilder中同父节点的显示顺序
如下图: 到目前为止,GameScene依赖于节点在SpriteBuilder中的顺序去决定其绘制的顺序. level content(_levelNode)被首先绘制,然后GameMenuLayer ...
- 一键安装Android开发环境
一键安装Android开发环境 1 下载tadp-3.0r4-linux-x64.run 进入下面的地址下载: https://developer.nvidia.com/gameworksdownlo ...