Ribbon


Ribbon [ˈrɪbən]

Ribbon是什么

  • Spring Cloud Ribbon是一个基于HTTP和TCP的 客户端 负载均衡 工具
    简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。

  • 它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。Spring Cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,包括后续我们将要介绍的Feign,它也是基于Ribbon实现的工具。所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构建微服务非常重要。

  • 面试造飞机, 工作拧螺丝

Ribbon能干嘛

  • LB(负载均衡 LB,即负载均衡(Load Balance),在微服务或分布式集群中经常用的一种应用。
  • 负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA。
  • 常见的负载均衡有软件Nginx,LVS,硬件 F5等。
  • 相应的在中间件,例如:dubbo和SpringCloud中均给我们提供了负载均衡,SpringCloud的负载均衡算法可以自定义。
  • 负载均衡的简单分类
    • 集中式LB 即在服务的消费方和提供方之间使用独立的LB设施 (可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方;
    • 将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

注意: Ribbon就属于进程内LB ,它只是一个类库,集成于消费方进程,消费方通过它来 获取到服务提供方的地址

具体操作

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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springcloud</artifactId><groupId>cn.com.codingce</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>springcloud-consumer-dept</artifactId><dependencies><!--我们需要拿到实体类, 所以要配置api -module--><dependency><groupId>cn.com.codingce</groupId><artifactId>springcloud-api</artifactId><version>1.0-SNAPSHOT</version></dependency><!--热部署工具--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--Ribbon--><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-ribbon --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-ribbon</artifactId><version>1.4.6.RELEASE</version></dependency><!--Eureka  客户端--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version></dependency></dependencies>
</project>

ConfigBean

package cn.com.codingce.springcloud.config;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 ConfigBean {   //configuration -- spring applicationContext.xml//配置负载均衡实现RestTemplate  @LoadBalanced//IRule//AvailabilityFilteringRule: 先会过滤掉, 跳闸, 访问故障服务器//RoundRobinRule    轮询//RandomRule    随机//RetryRule: 会按照轮询获取服务~ 如果服务获取失败, 则会在指定的时间内进行, 重试@Bean@LoadBalancedpublic RestTemplate getRestTemplate() {return new RestTemplate();}
}

DeptConsumerController

package cn.com.codingce.springcloud.controller;import cn.com.codingce.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import java.util.List;@RestController
public class DeptConsumerController {// 理解消费者, 不应该有service层//RestFul风格//(url, 实体: Map classs<T> responseType)@Autowiredprivate RestTemplate restTemplate;  //提供多种便捷访问远程http服务的方法//原 private static final String REST_URL_PREFIX = "http://localhost:8001";// Ribbon 我们这里是地址   因该是一个变量   通过服务来访问private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";@RequestMapping("/consumer/dept/add")public boolean add(Dept dept) {return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);}//http://localhost:8001/dept/list@RequestMapping("/consumer/dept/get/{id}")public Dept get(@PathVariable("id") Long id) {return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class );}@RequestMapping("/consumer/dept/list")public List<Dept> list() {return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list" , List.class );}}

自定义负载均衡

注意一点: 自定义类 单独拿出来 该类不能被@ComponentScan扫描到
项目截图

自定义CodingCeRandomRule

package cn.com.codingce.myrule;import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;import java.util.List;
import java.util.concurrent.ThreadLocalRandom;/*** 该类不能被@ComponentScan扫描到* @author xzMa*/
public class CodingCeRandomRule extends AbstractLoadBalancerRule {//自定义 每个服务, 访问5次, 换下一个服务(3个)//total = 0 默认=0 如果=5 我们指向下一个服务点private int total = 0;  //被调用的次数private int currentIndex = 0;   //当前是谁在提供服务public CodingCeRandomRule() {}//    @SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})public Server choose(ILoadBalancer lb, Object key) {if (lb == null) {return null;} else {Server server = null;while(server == null) {//线程中断if (Thread.interrupted()) {return null;}List<Server> upList = lb.getReachableServers(); //获得活着的服务List<Server> allList = lb.getAllServers();  //获得全部服务int serverCount = allList.size();if (serverCount == 0) {return null;}//int index = this.chooseRandomInt(serverCount);  //生成区间随机数//server = (Server)upList.get(index); //从活着的服务, 随机获取一个//===================================================================if (total < 5) {server = upList.get(currentIndex);total++;} else {total = 0;currentIndex++;//判断当前数量是否大于活着的数量if(currentIndex > upList.size()) {currentIndex = 0;}server = upList.get(currentIndex);  //从活着的服务中, 获取指定指定的服务进行操作}if (server == null) {Thread.yield();} else {if (server.isAlive()) {return server;}server = null;Thread.yield();}}return server;}}protected int chooseRandomInt(int serverCount) {return ThreadLocalRandom.current().nextInt(serverCount);}@Overridepublic Server choose(Object key) {return this.choose(this.getLoadBalancer(), key);}@Overridepublic void initWithNiwsConfig(IClientConfig clientConfig) {}
}

CodingCeRule

package cn.com.codingce.myrule;import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class CodingCeRule {@Beanpublic IRule myRule() {return new CodingCeRandomRule();//默认是轮询 现在我们定义为 CodingCeRandomRule// 本次自定义   频繁操作 会出现 500 错误 继续自定义写RetryRule}}

项目地址: https://github.com/xzMhehe/codingce-java

【Java进阶】Ribbon讲解实现案例相关推荐

  1. Java的算法讲解以及案例!

    算法是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,java算法就是采用Java语言来实现解决某一问题的清晰指令. 算法的特征: 输入性:有零个或多个外部量作为算法的输入 输出性:算法产生 ...

  2. java进阶案例下载_java进阶案例

    java进阶案例: 数据类型,字符,数值,范围,布尔 :byte -128~127. 面向对象:protect :重载与构造 (一). this封装:static:继承:多态: 1.方法覆盖:supe ...

  3. Java进阶:基于TCP的网络实时聊天室(socket通信案例)

    目录 开门见山 一.数据结构Map 二.保证线程安全 三.群聊核心方法 四.聊天室具体设计 0.用户登录服务器 1.查看当前上线用户 2.群聊 3.私信 4.退出当前聊天状态 5.离线 6.查看帮助 ...

  4. JAVA进阶案例 TCP编程之网络聊天工具(服务端)

    实现分析. 1.开启服务端 客户端选择'登录以后'后,提示输入用户名和密码,验证成功则进入好友列表界面 2.用户聊天 双击好友,进入好友聊天界面.在信息框编辑信息 点击发送 当客户端向服务端发送数据时 ...

  5. 视频教程-Java进阶高手课-Spring精讲精练-Java

    [ [这里是图片001] Java进阶高手课-Spring精讲精练 中国科学技术大学硕士研究生,丹麦奥尔堡大学访问学者,先后就职于eBay.蚂蚁金服.SAP等国内外一线互联网公司,在Java后端开发. ...

  6. Java 自学路线图之 Java 进阶自学

    文章目录 Java 自学路线图的第二阶段是 Java 语言进阶自学,在自学了第一阶段的 Java 基础自学后,大家对 Java 语言编程有了初步的了解和认识,建议在第一部分自学后整理一下自己的自学思路 ...

  7. Java进阶3 - 易错知识点整理(待更新)

    Java进阶3 - 易错知识点整理(待更新) 该章节是Java进阶2- 易错知识点整理的续篇: 在前一章节中介绍了 ORM框架,中间件相关的面试题,而在该章节中主要记录关于项目部署中间件,监控与性能优 ...

  8. java进阶书籍推荐(不包括基础)

    java进阶书籍推荐(不包括基础) 个人认为看书有两点好处: 能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超其他资料 对着书上的代码自己敲的时候方便 &q ...

  9. 2018年java进阶需要关注的公众号

    2018年java进阶需要关注的公众号 这里为正在学习Java的朋友汇总大量资源!只要你关注这些公众号,Java基础.面试.架构.思维导图.算法.互联网热点技术.数据库.服务器.网络安全等相关问题都可 ...

最新文章

  1. android8.1获取蓝牙地址,[蓝牙] Android 8.1 获取蓝牙设备地址无效;02:00:00:00:00:00
  2. 三位数除以两位数竖式计算没有余数_二年级数学第三十课:有余数的除法 例4 试商...
  3. PHP Web 2.0开发实战
  4. mysql 日期型中文报错_mysql日期类型默认值'0000-00-00' 报错,是什么问题?
  5. Java 文件目录显示
  6. 、nohup 不中断后台执行
  7. Java疯狂讲义读书笔记第一章
  8. MQL5由简到繁系列一
  9. centos6.5重置密码
  10. 正则表达式学习实践心得——来源于codesheep(羊哥)
  11. 31.Silverlight中WebClient+StreamResourceInfo+反射实现动态加载外部XAP程序
  12. 共享单车物联网技术简析
  13. web前端html5+css3学习笔记(1)
  14. 期望方差和贝叶斯概率
  15. ZBrush如何进行头骨的雕刻
  16. supermap三维地下管线
  17. 不同平台使用不同技术实现微信好友、朋友圈分享汇总(H5、taro、uni-app)
  18. php++i和i++区别_PHP和i,第1部分
  19. AOV网络——初了解
  20. CSS 布局 问题 及 解答

热门文章

  1. 京东 | AI人才联合培养计划
  2. 材料科学中的数据挖掘:晶体图神经网络解读与代码解析
  3. 今晚直播 | 北邮博士生纪厚业:异质图神经网络之模型和应用
  4. 偶像剪辑,一键获取:多模态联合建模的视频人物摘要
  5. 深度强化学习实战:Tensorflow实现DDPG - PaperWeekly 第48期
  6. 陕西师范大学第七届程序设计竞赛 C题 iko和她的糖
  7. Nexus【环境搭建 02】最新版本 nexus-3.35.0-02-unix.tar.gz 安装配置启动及测试(JDK版本+虚拟机参数配置说明)
  8. autolisp统计相同元素个数_统计学习基础知识
  9. rog live service是什么_王者荣耀五周年好礼送不停,玩游戏还能白嫖ROG游戏手机3?...
  10. html 画动画效果,html5 canvas绘制曲线动画特效