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

一、客户端负载均衡

负载均衡是对系统的高可用、网络压力的缓解和处理能力扩容的重要手段之一。我们常说的负载均衡是指服务端负载均衡,其中分为硬件负载均衡和软件负载均衡。硬件负载均衡主要通过在服务器节点中回见安装专门用于负载均衡的设备,比如F5等;而软件负载均衡则是通过在服务器上安装一些具有负载均衡功能或模块的软件来完成请求分发工作,比如Nginx等,不论是采用硬件负载均衡还是软件负载均衡,只要是服务端负载均衡都能以类似如下图的架构方式构建起来。

硬件负载均衡的设备或是软件负载均衡的软件模块都会维护一个下挂可用的服务端清单,通过心跳检测来剔除故障的服务端节点以保证清单中都是可以正常访问的服务端节点,当客户端发送请求道负载均衡设备的时候,该设备按某种算法(eg:线性轮询、按权重负载、按流量负载等)从维护的可用服务端清单中取出一台服务端的地址,然后进行转发。

客户端负载均衡和服务端负载均衡最大的不同点在于上面所提及的服务清单所存储的位置。在客户端负载均衡中,所有客户端节点都维护这自己要访问的服务端清单,而这些服务端的清单来自于服务注册中心。通服务端负载均衡的架构类似,在客户端负载均衡中也需要心跳去维护服务端清单的健康性,这个步骤要与服务注册中心配合完成、在Spring Cloud实现的服务治理框架中,默认会创建针对各个服务治理框架的Ribbon自动化整合配置,比如Euruka中的org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration,Consul中的org.apringframework.cloud.consul.discovery.RibbonCounsulAutoConn。在实际使用的时候,我们通过查看这两个类的实现,以找到他们的配置详情来帮助我们更好的使用它。

通过Spring Cloud Ribbon的封装,我们在微服务架构中使用客户端负载均衡调用非常简单,只需要如下两步:

  • 服务提供者只需要启动多个服务实例并注册到一个注册中心或是多个相关联的服务注册中心。
  • 服务消费者直接通过调用被@LocdBalanced注解修饰过的RestTemplate来实现面向服务的接口调用。

二、RestTemplate详解

RestTemplate针对不同请求类型和参数类型的服务调用实现。

1、GET请求

在RestTemplate中,对GET请求可以通过如下两个方法进行调用实现

第一种:getForEntity函数,该方法返回的是ResponseEntity,该对象时Spring对HTTP请求响应的封装,其中主要存储了HTTP的几个重要元素,比如HTTP请求状态码的枚举对象HttpStatus、在它的服了你HttpEntity中还存储着HTTP请求头信息对象HttpHeaders已经泛型类型的请求体对象。eg:访问USER-SERVER服务的/user请求,同时最后一个参数didi会替换url中的{1}占位符,而返回的ResponseEntity对象中的body内容类型会根据第二个参数转换为String类型。

 RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://USER-SERVICE/user?name={1}",String.class,"didi");
String body = responseEntity.getBody();

如果我们希望返回的body是一个User对象类型,也可以如下:

 RestTemplate restTemplate = new RestTemplate();
ResponseEntity<User> responseEntiry = restTemplate.getForEntity("http://USER-SERVICE/user?name={1}",User.class,"didi");
User body = responseEntity.getBody();

上述是比较常用的方法,getForEntity函数实际上提供了以下三种不同的重载实现:

getForEntity(String url,Class responseType,Object ... urlVariables):该方法提供;额三个参数,其中url为请求的地址,responseType为请求相应提body的包装类型,urlVariables为url中的参数绑定。GET请求的参数绑定通常使用url中拼接的方式,比如:http://USER-SERVICE/user?name=didi.我们可以像这样将自己的参数拼接到url中,但是更好的方式是在url中使用占位符并配合参数urlVariable参数实现GET请求的参数绑定,比如url定义为http://USER-SERVICE/user?name={1},调用的时候使用getForEntity{"http://USER-SERVICE/user?name={1}",String.class,"didi"}其中第三个参数didi会替换url中的{1}占位符。

getForEntity(String url,Class responseType,Map urlVariables):该方法中,只有urlVariables的参数类型与上述的方法不同。这里使用了Map类型,所以使用该方法进行参数绑定时需要在占位符中指定Map中参数的key值,比如url定义为http://USER-SERVICE/user?name=${name}在Map类型的urlVariables中,我们就需要put一个key为name的参数来绑定url中{name}占位符的值

eg:

 RestTemplate restTemplate = new RestTemplate();
Map<String,String> params = new HashMap<>();
params.put("name","data");
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://USER-SERVICE/user?name={name}",String.class ,params);

getForEntity(URI  url ,Class ResponseType):该方法使用URI对象来代替之前的url和urlVariables参数来指定访问地址和参数绑定。URI是JDK java.net包下的一个类,它表示一个统一资源标识符引用

 RestTemplate restTemplate = new RestTemplate();
UriComponents uriComponents = UriComponentsBuilder.fromriString("http://USER-SERVICE/user?name=${name}").build().expand("dodo").encode();
URI uri = uriComponents.toUri();
ResponseEntity<String> responseEntity = restTemplate.getForEntity(url,String.class).getBody();

第二种:getForObject函数

该方法可以理解为getForEntity的进一步封装,通过HttpMessageConvertExtractor对HTTP的请求响应体body内容进行转接,实现请求直接返回包装好的对象内容。eg:

 RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(uri,String.class)

当body是一个User对象时,可以直接这样实现eg:

 RestTemplate restTemplate = new RestTemplate();
User result = restTemplate.getForObject(uri,User.class);

当不需要关注请求响应除body外的其他内容时,该函数非常好用,可以少有从Response中获取body的步骤。它与getForEntity函数类似,也提供了三种不同的重载实现

getForObject(String url,Class responseType,Object...urlVariables):与getForEntity的方法类似,url参数指定访问的地址,responseType参数定义该方法的返回类型,url参数指定访问的地址,responseType参数定义该方法的返回类型,urlVariables参数为url中占位符对应的参数

getForObject(String url,Class responseType,Map urlVariables):在该甘薯中,使用Map类型的urlVariable替代上面数组形式的urlVariable,因此使用时在url中需要将占位符的名称与Map类型的key一一对应设置

getForObject(URI url,Class responseType):该方法使用URI对象来代替之前的url和urlVariable参数使用。

2、POST请求

在RestTemplate中,对POST请求时可以通过如下三个方法进行调用实现。

第一种:postForEntity函数。该方法同GET请求中的getForEntity类型,会在调用后返回ResponseEntity<T>对象,其中T为请求响应的body类型,eg:使用postForEntity提交POST请求道USER--SERVICE服务的/user接口,提交的body内容为user对象,请求响应返回的body类型为String.

 RestTemplate restTemplate = new RestTemplate();
User user = new User("didi",);
ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://USER-SERVICE/user",user,String.class);
String body = responseEntity.getBody();

postForEntity函数也实现了三种不同的重载方法

postForEntity(String url,Object request,Class responseType,Object...urlVariables)

posrForEntity(String url,Object request,Class  responseType,Map uriVariables)

postForEntity(URI uri ,Object request,Class responseType)

第二种:postForObject函数,该方法也跟getForObject的类型类似,它的作用是简化postForEntity的后续处理。通过直接将请求响应的body内容包装成对象类返回使用,eg:

 RestTemplate restTemplate = new RestTemplate()l
User user = new User("didi",);
String postResult = restTemplate.postForObject("http://USER-SERVICE/user",user,String.class);

postForObject函数也实现了三种不同的重载方法

postForObject(String url,Object request,Class responseType,Object...urlVariables)

postForObject(String url,Object request,Class  responseType,Map uriVariables)

postForObject(URI uri ,Object request,Class responseType)

第三种:postForLocation函数,该方法实现了以POST请求提交资源,并返回新资源的URI,比如下面的例子

 User user = new User("didi",);
URI responseURI = restTemplate.postForLocation("http://USER-SERVICE/user",user);

postForLocation函数也实现了三种不同的重载方法

postForLocation(String url,Object request,bject...urlVariables)

postForLocation(String url,Object request,Class  responseType,Map uriVariables)

postForLocation(URI uri ,Object request,Class responseType)

3、PUT请求

在RestTemplate中,对PUT请求可以通过put方法进行调用实现,比如:

 RestTemplate restTemplate = new RestTemplate();
Long id = 1000L;
User user = new User("didi",);
restTemplate.put("http://USER-SERVICE/user/{1}",user,id);

put函数三种不同的重载方法:

put(String url,Object request,bject...urlVariables)

put(String url,Object request,Map uriVariables)

put(URI uri ,Object request)

put函数为void类型,所以没有返回内容,也就没有其他函数定义的responseType参数,除此之外的其他传入参数定义与用法与postForObject基本一致。

4、DELETE请求

在RestTemplate中,对DELETE请求可以通过delete请求方法进行调用实现,eg:

 RestTemplate restTemplate = new RestTemplate();
Long id = 1000L;
restTemplate.delete("http://USER-SERVICE/user/{1}",id);

delete函数三种不同的重载:

delete(String url,bject...urlVariables)

delete(String url,Map uriVariables)

delete(URI uri )

由于我们在进行REST请求时,通常将DELETE请求的唯一标识拼接在url中,所以DELETE请求也不需要request的body信息。url指定DELETE请求的位置,urlVariables绑定url中的参数即可。

【SpringCloud微服务实战学习系列】客户端负载均衡Spring Cloud Ribbon的更多相关文章

  1. 【SpringCloud微服务实战学习系列】服务治理Spring Cloud Eureka

    Spring Cloud Eureka是Spring Cloud Netflix微服务中的一部分,它基于NetFlix Sureka做了二次封装,主要负责完成微服务架构中的服务治理功能. 一.服务治理 ...

  2. 【SpringCloud微服务实战学习系列】配置详解

    前言 Spring Boot针对常用的开发场景提供了一系列自动化配置来减少原本复杂而又几乎很少改动的模板化配置内容. 一.配置文件 Spring Boot的默认配置文件位置为src/main.reso ...

  3. 【SpringCloud微服务实战学习系列】创建应用及解析

    一.创建应用 使用官方Spring Initializr工具生成基础项目(http://start.spring.io/) 导入Intellij idea中 目录结构如下: 二.目录结构说明: src ...

  4. SpringCloud---客户端负载均衡---Spring Cloud Ribbon

    1.概述 1.1 Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具: 基于Netflix Ribbon实现: 通过Spring Cloud的封装,可以轻松将面向服务 ...

  5. SpringCloud学习(SPRINGCLOUD微服务实战)一

    SpringCloud学习(SPRINGCLOUD微服务实战) springboot入门 1.配置文件 1.1可以自定义参数并在程序中使用 注解@component @value 例如 若配置文件为a ...

  6. springcloud微服务实战--笔记

    目前对Springcloud对了解仅限于:“用[注册服务.配置服务]来统一管理其他微服务” 这个水平.有待提高 Springcloud微服务实战这本书是翟永超2017年5月写的,时间已经过去了两年,略 ...

  7. SpringCloud微服务实战——搭建企业级开发框架(十二):OpenFeign+Ribbon实现负载均衡

      Ribbon是Netflix下的负载均衡项目,它主要实现中间层应用程序的负载均衡.为Ribbon配置服务提供者地址列表后,Ribbon就会基于某种负载均衡算法,自动帮助服务调用者去请求.Ribbo ...

  8. SpringCloud微服务实战——第三章服务治理

    Spring Cloud Eureka 服务治理 是微服务架构中最核心最基本的模块.用于实现各个微服务实例的自动化注册与发现. 服务注册: 在服务治理框架中,都会构建一个注册中心,每个服务单元向注册中 ...

  9. SpringCloud微服务实战——第一章序言读书笔记

    什么是微服务架构 是系统架构上的一种设计风格,将独立的系统拆分成多个小型服务,这些小型服务都在各自独立的进程中运行,服务之间基于HTTP的RESTful API进行通信协作. 每个小型服务都围绕各自的 ...

随机推荐

  1. 哪个中年IT男不是一边面对危机,一边咬牙硬抗【转】

    来自: 懂懂笔记 对于 2017 年年末那则令人哀伤的消息,相信很多同龄人都会触目伤怀.面对公司的强制性劝退,深圳中兴网信科技有限公司某研发组主管从办公楼上一跃而下,用最决绝的方式结束了宝贵的生命. ...

  2. python接口自动化28-requests-html爬虫框架

    前言 requests库的好,只有用过的人才知道,最近这个库的作者又出了一个好用的爬虫框架requests-html.之前解析html页面用过了lxml和bs4, requests-html集成了一些 ...

  3. PHP ~与各加速工具的性能对比~

    参与测试的加速器:Xcache,Opcache,hhvm   Xcache简介 前面已经介绍了PHP加速器的原理和功用(参见LAMP架构之PHP-FPM 服务器),xcache作为目前使用广泛的PHP ...

  4. ubuntu 安装JDK1.6(jdk-6u45-linux-x64.bin)

    ubuntu 安装JDK1.6 首先在官网下载JKD1.6 linux的版本:http://www.oracle.com/technetwork/java/javasebusiness/downloa ...

  5. windows 系统中的 afd 驱动

    afd 的全称是 Ancillary Function Driver for WinSock,是 windows 系统网络部分的核心工具.同 Linux 类似,windows 的 socket 最终也 ...

  6. linux一些稍微高级的命令

    cut 命令:提取文件中指定的字段(列).字符内容.单词的默认分隔符为空格. cut [选项]... [文件]... 选项: -b  按照字节切 -c  按照字符切 -d  指定分割符 -f   指定 ...

  7. 【C语言】字节对齐问题(以32位系统为例)

    1. 什么是对齐? 现代计算机中内存空间都是按照字节(byte)划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型 ...

  8. gitlab 502 报错

    这里从网上查到文章,我这里看了一下我这里是unicorn的问题 说一下情况:这里我们的一个前端修改了大量的打包,并进行了打包.然后提交merge request  分支到master,结果看到页面50 ...

  9. 第三部分:Android 应用程序接口指南---第二节:UI---第六章 对话框

    第6章 对话框 一个对话框是一个小窗口,提示用户做出决定或输入额外的信息,一个对话框不填充屏幕并且通常用于在程序运行时中断,然后弹出通知提示用户,从而直接影响到正在运行的程序.图6-1就是对话框的外观 ...

  10. 升级python(linux)

    查看系统当前python版本 2: [root@wangyuelou ~]# python     Python 2.4.3 (#1, May  5 2011, 16:39:10)     [GCC ...