Ribbon简介

需要解决的问题:
① 如何在配置Eureka Client注册中心时不去硬编码Eureka Server的地址?
② 在微服务不同模块间进行通信时,如何不去硬编码服务提供者的地址?
③ 当部署多个相同微服务时,如何实现请求时的负载均衡? 
实现负载均衡方式1:通过服务器端实现负载均衡(nginx)

实现负载均衡方式2:通过客户端实现负载均衡。
Ribbon是什么?
Ribbon是Netflix发布的云中间层服务开源项目,其主要功能是提供客户端实现负载均衡算法。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,Ribbon是一个客户端负载均衡器,我们可以在配置文件中Load Balancer后面的所有机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。
下图展示了Eureka使用Ribbon时的大致架构: 

Ribbon工作时分为两步:第一步选择Eureka Server,它优先选择在同一个Zone且负载较少的Server;第二步再根据用户指定的策略,再从Server取到的服务注册列表中选择一个地址。其中Ribbon提供了很多策略,例如轮询round robin、随机Random、根据响应时间加权等。

Ribbon的使用

集成Ribbon以及简单使用

如何集成Ribbon?
查看Spring cloud官方文档,搜索Ribbon。
① 首先引入Ribbon依赖
按照官方的意思是需要加入以下依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
但是其实是不需要的加入这个依赖的,在spring-cloud-starter-eureka依赖中就已经包含了Ribbon Starter (上节已知spring-cloud-starter-eureka-server 是为编写Eureka Server提供依赖,spring-cloud-starter-eureka是为编写Eureka Client提供依赖),因此只需要Eureka Client具有spring-cloud-starter-eureka依赖即可。即在POM中需要有 
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
② 如何使用Ribbon
上节示例中是使用RestTemplate进行Eureka Client(包括服务提供者以及服务消费者,在这里其实是服务消费者使用RestTemplate)之间的通信,为RestTemplate配置类添加@LoadBalanced注解即可,如下所示: 
@Bean
@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();
}
③ 如何解决硬编码
使用添加@LoadBalanced注解后的RestTemplate调用服务提供者的接口时,可以使用虚拟IP替代真实IP地址。所谓的虚拟IP就是服务提供者在application.properties或yml文件中配置的spring.application.name属性的值。示例如下: 
@GetMapping("/movie/{id}")
public User findById(@PathVariable Long id) {// VIP: Virtual IP http://microservice-provider-user/即虚拟IP 服务提供者的ServiceId (spring.application.name)return this.restTemplate.getForObject("http://microservice-provider-user/simple/" + id, User.class);
}

运行测试:依次启动Eureka Server和Eureka Clients(服务提供者和服务消费者)

访问测试:

负载均衡测试:依次启动Eureka Servler 和 Eureka Client(一个服务消费者movie 两个不同端口号相同的服务提供者)
在服务提供者端访问4次 


发现两个服务提供者user分别被调用了2次,说明Ribbon默认的负载均衡策略是轮询。

自定义RibbonClient

如何为服务消费者自定义Ribbon Client?
① 代码自定义RibbonClient
所谓的自定义Ribbon Client的主要作用就是使用自定义配置替代Ribbon默认的负载均衡策略,注意:自定义的Ribbon Client是有针对性的,一般一个自定义的Ribbon Client是对一个服务提供者(包括服务名相同的一系列副本)而言的。自定义了一个Ribbon Client 它所设定的负载均衡策略只对某一特定服务名的服务提供者有效,但不能影响服务消费者与别的服务提供者通信所使用的策略。根据官方文档的意思,推荐在 springboot主程序扫描的包范围之外进行自定义配置类。其实纯代码自定义RibbonClient的话有两种方式:
方式一:在springboot主程序扫描的包外定义配置类,然后为springboot主程序添加@RibbonClient注解引入配置类 
@Configuration
public class TestConfiguration {@Autowiredprivate IClientConfig config;@Beanpublic IRule ribbonRule(IClientConfig config) { // 自定义为随机规则return new RandomRule();}
}

注意:@RibbonClient注解中的name属性是指服务提供者的服务名(即当前消费者使用自定义配置与其通信的服务提供者的spring.application.name的属性)

@RibbonClient(name = "microservice-provider-user",configuration = TestConfiguration.class)
方式二:在与springboot主程序的同一级目录新建RibbonClient的配置类,但是必须在springboot扫描的包范围内排除掉,方法是自定义注解标识配置类,然后在springboot的添加@ComponentScan根据自定义注解类型过滤掉配置类
自定义注解 
public @interface ExcludeFromComponentScan {
}

自定义配置类

@Configuration
@ExcludeFromComponentScan
public class TestConfiguration1 {@Autowiredprivate IClientConfig config;@Beanpublic IRule ribbonRule(IClientConfig config) { // 自定义为随机规则return new RandomRule();}
}

在springboot主程序上添加注解

@RibbonClient(name = "microservice-provider-user",configuration = TestConfiguration1.class)
@ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = ExcludeFromComponentScan.class)})

运行测试:


②  通过配置文件自定义RibbonClient
官方文档地址:http://cloud.spring.io/spring-cloud-static/Camden.SR7/#_customizing_the_ribbon_client_using_properties

意思就是:配置RibbonClient规则是 
<服务名>.ribbon.<类型>=与类型对应的类名(也可以自定义) 
类型可以为一下几个: 
NFLoadBalancerClassName: 应该实现 ILoadBalancer接口
NFLoadBalancerRuleClassName: 应该实现 IRule接口
NFLoadBalancerPingClassName: 应该实现 IPing接口
NIWSServerListClassName: 应该实现ServerList接口
NIWSServerListFilterClassName: 应该实现ServerListFilter接口
详解:
独立使用Spring Cloud Ribbon,在没有引入Spring Cloud Eureka服务治理框架时, 默认接口实现类:
1.IClientConfig:Ribbon的客户端配置,默认采用com.netflix.cilent.config.DefaultClientConfigImpl实现。
2.IRule:Ribbon的负载均衡策略,默认采用com.netflix.loadbalancer.ZoneAvoidanceRule实现,该策略能够在多区 域环境下选择出最佳区域的实例访问。
3.IPing:Ribbon的实例检查策略,默认采用com.netflix.loadbalancer.NoOpPing实现,该检查策略是一种特殊实现方式,实际上它并不会检查实例是否可用,而是始终返回True,默认认为所有实例都可用。
4.ServerList<Server>:服务实例清单的维护机制,默认采用com.netflix.loadbalancer.ConfigurationBasedServerList实现。
5.ServerListFilter<Server>:服务实例清单过滤机制,默认采用org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter实现,该策略能够优先过滤出与请求调用方处于同区域的服务实例。
6.ILoadBalancer:负载均衡器,默认采用com.netflix.loadbalancer.ZoneAwareLoadBalancer实现,它具备区域感知能力
Spring Cloud Eureka和Spring Cloud Ribbon结合使用,Ribbon默认接口实现类:
1.IPing:Ribbon的实例检查策略,默认采用com.netflix.niws.loadbalancer.NIWSDiscoveryPing实现,该检查策略是一种特殊实现方式,实际上它并不会检查实例是否可用,而是始终返回True,默认认为所有实例都可用
2.ServerList<Server>:服务实例清单的维护机制,默认采用com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList实现,将所有服务清单交给Eureka的服务治理机制进行维护
其中最常用的是配置RibbonClient的负载均衡规则,如下所示:
application.yml中添加
users:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule
自带的IRule实现类有以下几个:
BestAvailableRule 选择最小请求数
ClientConfigEnabledRoundRobinRule 轮询
RandomRule 随机选择一个server
RoundRobinRule 轮询选择server
RetryRule 根据轮询的方式重试
WeightedResponseTimeRule 根据响应时间去分配一个weight ,weight越低,被选择的可能性就越低(响应时间加权)
ZoneAvoidanceRule 根据server的zone区域和可用性来轮询选择
注意:如果多种整合方式都存在的话是存在优先级的,即 文件配置优先级 > 代码配置优先级 > 默认配置优先级
使用示例如下:在application.yml中添加如下配置即可为请求microservice-provider-user的服务提供者时设置随机策略。

microservice-provider-user:ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

经过测试是完全可行的。

Ribbon脱离Eureka使用

官方描述地址:http://cloud.spring.io/spring-cloud-static/Camden.SR7/#spring-cloud-ribbon-without-eureka

Eureka是用于服务发现和服务注册、以及使用服务名来解决服务消费者和服务提供者通信时地址的硬编码问题的。如果Ribbon脱离了Eureka,那么在服务消费者端就无法根据服务名通过心跳机制从EurekaServer端获取对应服务提供者的IP以及端口号。这时就需要在服务消费者端配置对应服务提供者的地址列表,然后Ribbon才能通过配置文件或者自定义的RibbonClient或者默认的配置获取负载均衡的轮询策略进行请求分发。
配置方式:
第一步:检查是否引入了Eureka。如果服务在依赖中添加了spring-cloud-starter-eureka,这种情况下如果想使Ribbon脱离Eureka使用的话就需要将Eureka禁用掉。仅仅需要添加以下配置,如果没有引入Eureka就不需要禁用。 
ribbon:eureka:enabled: false

第二步:配置某服务提供者的地址列表以及均衡策略(默认是轮询)

<服务提供者名称>:ribbon:listOfServers: localhost:7901,localhost:7902NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

因为我的Demo中引入了Eureka,所以我的配置如下所示:

ribbon:eureka:enabled: falsemicroservice-provider-user:ribbon:listOfServers: localhost:7901,localhost:7902NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

具体代码已上传GitHub,地址:https://github.com/liuxun1993728/ribbonDemo

SpringCloud实战微服务之——Ribbon详解相关推荐

  1. Apollo微服务配置中心详解

    Apollo微服务配置中心详解 前言 一.Apollo架构 (一)简介 (二)角色介绍 (三)服务端实现 (四)客服端实现 二.Apollo部署 (一)准备数据库 (二)配置服务 1. 手动部署 (1 ...

  2. java实现的微服务架构_详解Java 微服务架构

    一.传统的整体式架构 传统的整体式架构都是模块化的设计逻辑,如展示(Views).应用程序逻辑(Controller).业务逻辑(Service)和数据访问对象(Dao),程序在编写完成后被打包部署为 ...

  3. (三)SpringCloud实战微服务

    一.微服务架构概述 1.1 微服务特性以及优点 每个服务可以独立运行在自己的进程里 一系列独立运行的微服务(goods,order,pay,user,search-)共同构建了整个系统 每个服务为独立 ...

  4. 使用SpringCloud实战微服务

    转:https://blog.csdn.net/ittechnologyhome/article/details/73824784 一微服务架构概述 1.1 微服务特性以及优点 每个服务可以独立运行在 ...

  5. SpringCLoud实战微服务之——微服务简介以及入门使用

    微服务概述 微服务是什么?微服务解决了什么问题?微服务有什么特点? 单体架构是什么? 一个归档包包含了应用所有功能的应用程序,我们通常称之为单体应用.架构单体应用的架构风格,我们称之为单体架构,这是一 ...

  6. 首席架构师推荐:史上最全微服务架构简史详解!

    本文将介绍微服务架构和相关的组件,介绍他们是什么以及为什么要使用微服务架构和这些组件.本文侧重于简明地表达微服务架构的全局图景,因此不会涉及具体如何使用组件等细节. 要理解微服务,首先要先理解不是微服 ...

  7. SpringCloud学习笔记002---Spring Cloud实战微服务准备

    =============================================================  开始使用Spring Cloud实战微服务 =============== ...

  8. Aooms_基于SpringCloud的微服务基础开发平台实战_002_工程构建

    为什么80%的码农都做不了架构师?>>>    一.关于框架更名的一点说明 最近在做年终总结.明年规划.还有几个项目需要了结.出解决方案,事情还比较多,死了不少脑细胞,距离上一篇文章 ...

  9. SpringCloud+Vue微服务教程与实战(1)--全新的开始

    点此查看全部文字教程.视频教程.源代码 本文目录 1. 背景 2. 微服务架构的优缺点 3. 实现技术 4. 开发环境 5. 小结 1. 背景 之前已经讲过SSM完整的教程,我个人觉得是相当不错的,附 ...

  10. SpringCloud+CloudAlibaba微服务初阶入门

    内容目录 微服务 为什么要用微服务? SpringCloud生态(旧版) 项目搭建 规范的创建父工程 父模块的pom的常用依赖 创建子模块 1.建module(maven) 2.改pom 3.写Yml ...

最新文章

  1. 用TensorFlow实现自编码器Autoencoders
  2. 调用startActivityForResult,onActivityResult无响应的问题
  3. make: *** [ext/fileinfo/libmagic/apprentice.lo] Er
  4. 【设计模式】单一职责原则
  5. python grpc 并发_用Python进行gRPC接口测试(二)
  6. java int.parse_java数据类型转换,parseXXX(String)或valueOf(String)有什么区别?
  7. 【UML】如何记忆UML类图的画法
  8. Django设计理念
  9. 图解 React-router 源码
  10. 与指定数字相同的数的个数(信息学奥赛一本通-T1102)
  11. 烂泥:ubuntu中使用virt-manager图形化新建虚拟机
  12. 操作系统(4)状态机视角下的程序执行
  13. accumulate
  14. qtqpixmap不出现图片_亚马逊对产品图片有哪些基本要求
  15. 朗文当代高级英语辞典android,朗文当代高级英语辞典最新版下载-朗文当代高级英语辞典第6版appv4.5.2 安卓版 - 极光下载站...
  16. 【详细】endnote中英文文献混排
  17. MySQL的性能分析关键字,explain,及其返回值代表的意思
  18. 经典游戏打砖块(粗糙版)
  19. Maxwell和Simplorer联合仿真设置注意事项
  20. electron下载失败_解决方案汇总

热门文章

  1. 杭电 oj 1006 Tick and Tick 个人题解
  2. 适用于ARM开发板的Armbian Linux22.08发布
  3. Infor CloudSuite Industrial (SyteLine) IDO 行授权 设置
  4. 74HC573芯片介绍
  5. 语义化版本号 Sematic Versioning
  6. 加拿大计算机工程研究生,加拿大维多利亚大学电子与计算机工程系副教授诚招硕士研究生 - 导师招生 - 小木虫 - 学术 科研 互动社区...
  7. 金融科技赋能 互融云手机回租系统 实现资产全流程在线运营管理
  8. java中计算文件的md5,Java计算文件MD5值代码
  9. 骄傲地宣布一件事:月入3万的目标还没实现
  10. 10. logback详解,Flink流处理案例及Hive和Hbase的整合