导语
  目前在开发中主要的负载均衡方案分为两种;一种是集中式的负载均衡,在生产者和消费者之间通过F5或者是Nginx来进行负载均衡,而另一种则是在客户端自己进行负载均衡,也就是说请求客户端可以根据自己的能力来进行负载。Ribbon就是属于客户端负载均衡的一种。

文章目录

  • Ribbon介绍
  • Ribbon的使用
    • 创建项目导入依赖
    • 编写测试类
    • RestTemplate 整合 Ribbon使用
      • Get方式调用
      • Post方式
  • 总结

Ribbon介绍

  Ribbon 的主要模块如下:

  • ribbon-loadbalancer 负载均衡模块,可以单独的进行使用,也可以整合到其他模块中进行使用,其中主要提供的就是Ribbon自定义实现的一些负载均衡算法
  • ribbon-eureka: 基于Eureka进行封装的模块,主要使用可以方便的集成到Eureka中。
  • ribbon-transport:主要是基于Netty的多协议支持,例如TCP、UDP、HTTP等。
  • ribbon-httpclient: 基于Apache HttpClient 进行封装的REST Ful风格的客户端,天然集成了负载均衡算法,可以在项目中直接进行接口的调用。
  • ribbon-example:从名称上可以看到就是给出了一些ribbon的示例代码。
  • ribbon-core:核心代码模块。

Ribbon的使用

  通过下面一个小例子来看看Ribbon在实际项目中如何使用。

创建项目导入依赖

<?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"><modelVersion>4.0.0</modelVersion><groupId>com.nihui.springcloud.ribbon</groupId><artifactId>base-ribbon</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>com.netflix.ribbon</groupId><artifactId>ribbon</artifactId><version>2.2.2</version></dependency><dependency><groupId>com.netflix.ribbon</groupId><artifactId>ribbon-core</artifactId><version>2.2.2</version></dependency><dependency><groupId>com.netflix.ribbon</groupId><artifactId>ribbon-loadbalancer</artifactId><version>2.2.2</version></dependency><dependency><groupId>io.reactivex</groupId><artifactId>rxjava</artifactId><version>1.0.10</version></dependency></dependencies></project>

编写测试类

public class MainApplication {public static void main(String[] args) {List<Server> serviceList = Arrays.asList(new Server("localhost",8080),new Server("localhost",8083));ILoadBalancer loadBalancer = LoadBalancerBuilder.newBuilder().buildFixedServerListLoadBalancer(serviceList);for (int i = 0; i < 5; i++) {String result  = LoadBalancerCommand.<String>builder().withLoadBalancer(loadBalancer).build().submit(new ServerOperation<String>() {public Observable<String> call(Server server) {try {String addr = "http://" + server.getHost() + ":" +server.getPort() + "/user/hello";System.out.println("调用地址" + addr);URL url = new URL(addr);HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");connection.connect();InputStream in = connection.getInputStream();byte[] data = new byte[in.available()];in.read(data);return Observable.just(new String(data));} catch (Exception e) {return Observable.error(e);}}}).toBlocking().first();System.out.println("调用结果"+result);}}
}

  通过上面这个例子主要是看看,Ribbon如何进行负载均衡操作,其中在接口调用的最底层还是通过HttpURLConnection。当然因为是RESTFul风格的调用,也可以使用其他的HTTP客户端工具进行操作。

RestTemplate 整合 Ribbon使用

  在上面的例子中使用了HTTP客户端进行调用,在Spring提供了一个用来进行HTTP调用的模板类。这就是RestTemplate。
  那么怎么使用RestTemplate来整合Ribbon进行调用呢,首先就来说明一下Spring RestTemplate如何进行使用。

Get方式调用

  首先要做的事情就是将RestTemplate注入到Spring的容器中,SpringBoot中支持的容器注入方式如下

@Configuration
public class BeanConfiguration{@Beanpublic RestTemplate getRestTemplate(){return new RestTemplate();}
}

  建立一个用来测试的接口类,并且增加两个接口,

@RestController
public class HouseController {@GetMapping("/house/data")public HouseInfo getData(@RequestParam(name = "name") String name){return new HouseInfo(1L,"北京","朝阳","花园小区");}@GetMapping("/house/data/{name}")public String getName(@PathVariable(name = "name")String name){return name;}
}

  建立一个用来调用该接口的类

@RestController
public class HouseClientController {@Autowiredprivate RestTemplate restTemplate;@GetMapping("/call/data")public HouseInfo getData(@RequestParam("name") String name){return restTemplate.getForObject("http://localhost:8081/house/data?name="+name,HouseInfo.class);}@GetMapping("/call/data/{name}")public String getData2(@PathVariable("name") String name){return restTemplate.getForObject("http://localhost:8081/house/data/{name}",String.class,name);}}

  获取数据的方式通过getForObject方法来进行,这个方法有如下的三个重载方法

  • url: 请求的API地址,有两种方式,一种是url字符串,一种是通过URI的方式
  • responseType: 表示返回值类型
  • uriVariables: PathVariable 参数,有两种参数,一种是可变参数,一种是通过Map的方式进行
 @Override@Nullablepublic <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException {RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);HttpMessageConverterExtractor<T> responseExtractor =new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);}@Override@Nullablepublic <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);HttpMessageConverterExtractor<T> responseExtractor =new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);}@Override@Nullablepublic <T> T getForObject(URI url, Class<T> responseType) throws RestClientException {RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);HttpMessageConverterExtractor<T> responseExtractor =new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);return execute(url, HttpMethod.GET, requestCallback, responseExtractor);}

  当然除了使用上面这种方法,还可以用getForEntity的方式进行操作。

    @GetMapping("/call/dataEntity")public HouseInfo getData(@RequestParam("name") String name){ResponseEntity<HouseInfo> entity = restTemplate.getForEntity("http://localhost:8080/house/data?name=" + name, HouseInfo.class);if (entity.getStatusCodeValue()==200){return entity.getBody();}return null;}

  getForEntity方法可以获取到返回状态,请求头信息等等,通过getBody获取到响应的内容,其他的都是与getForObject是相同的也是有三种实现重载的方式。

Post方式

  在上述的代码中加入如下的的一个操作方法

    @PostMapping("/house/save")public Long addData(@RequestBody HouseInfo houseInfo){System.out.println(houseInfo.getCity());return 10001L;}

  在调用接口中编写如下的操作类使用postForObject()

    @GetMapping("/call/add")public Long add(){HouseInfo houseInfo = new HouseInfo();return restTemplate.postForObject("http://localhost:8080/call/add",houseInfo,Long.class);}

  当然postForObject方法也有如下的三种重载方法

 @Override@Nullablepublic <T> T postForObject(String url, @Nullable Object request, Class<T> responseType,Object... uriVariables) throws RestClientException {RequestCallback requestCallback = httpEntityCallback(request, responseType);HttpMessageConverterExtractor<T> responseExtractor =new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);}@Override@Nullablepublic <T> T postForObject(String url, @Nullable Object request, Class<T> responseType,Map<String, ?> uriVariables) throws RestClientException {RequestCallback requestCallback = httpEntityCallback(request, responseType);HttpMessageConverterExtractor<T> responseExtractor =new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);}@Override@Nullablepublic <T> T postForObject(URI url, @Nullable Object request, Class<T> responseType)throws RestClientException {RequestCallback requestCallback = httpEntityCallback(request, responseType);HttpMessageConverterExtractor<T> responseExtractor =new HttpMessageConverterExtractor<>(responseType, getMessageConverters());return execute(url, HttpMethod.POST, requestCallback, responseExtractor);}

  除了get和Post方法,RestTemplate还提供了PUT ,DELETE等操作方法,当然还有一个所有请求都可以发送的方法就是exchange方法。

总结

  这篇博客中主要介绍了在Spring 中RestTemplate的使用,当然在实际开发中通过这种方式可以有效的化简在使用Ribbon的时候进行的调用方式,能更好的整合Ribbon。简化了开发的步骤,提高开发效率

Spring Cloud 微服务实战系列-Ribbon入门RestTemplate 介绍相关推荐

  1. Spring Cloud 微服务实战系列-Ribbon整合RestTemplate实现负载均衡

    导语   在Spring Cloud项目中想要整合Ribbon只需要在pom文件中加入对应的依赖就可以了,那么在这次的分享中就来看看在Ribbon怎么通过RestTemplate来进行负载均衡,以及扩 ...

  2. Spring Cloud 微服务实战系列-Spring Boot再次入门(一)

    导语   看到标题大家都疑惑,为什么叫做再入门呢?在之前的博客中也分享过相关的内容,但为了让Spring Cloud 微服务实战系列更加完整就再次编写一个入门的内容,也是为了这个系列的内容更加的完整, ...

  3. Spring Cloud 微服务实战系列-Eureka注册中心(二)

    导语   之前的分享中,简单的介绍了SpringBoot的入门知识以及如何使用Eureka搭建服务注册中心,这一次的分享主要是来讲解一些在Eureka中的常用的配置,方便大家在使用Eureka的时候可 ...

  4. Spring Cloud 微服务实战系列-Eureka注册中心(一)

    导语   在这一个系列的分享中,笔者主要是来分享在实战实际操作中的一些使用场景,了解了实战的操作中的使用场景才能更好的从实战中的问题出发找到自己需要的原理性的东西,找到原理性的东西之后才可以更好的根据 ...

  5. Spring Cloud 微服务实战系列-Spring Boot再次入门(二)

    导语   在之前的一篇中简单的介绍一些在SpringBoot中常见的使用方式,已经如何实现自定义的一些配置,设置等等的内容,这一次的分享中来介绍一些在Spring Boot 中的高级用法,这样会对Sp ...

  6. 手把手,嘴对嘴教你Spring Cloud 微服务实战 -- 前言

    Spring Cloud 总结 博主接触到Spring Cloud 大概已经一年多了,当时Spring Cloud微服务框架已经是潮流了,不会一点都不好意思出去面试.并且主流技术基本上都在谈论微服务, ...

  7. Spring Cloud 微服务实战笔记

    Spring Cloud 微服务实战笔记 微服务知识 传统开发所有业务逻辑都在一个应用中, 开发,测试,部署随着需求增加会不断为单个项目增加不同业务模块:前端展现也不局限于html视图模板的形式,后端 ...

  8. Spring Cloud 微服务实战精品文章大汇总,错过了血亏!

    随着互联网的高速发展,庞大的用户群体和快速的需求变化已经成为了传统架构的痛点.在这种情况下,如何从系统架构的角度出发,构建出灵活.易扩展的系统来快速响应需求的变化,同时,随着用户量的增加,如何保证系统 ...

  9. Spring Cloud微服务实战(五)-应用通信

    订单服务源码 https://github.com/Wasabi1234/SpringCloud_OrderDemo 商品服务源码 https://github.com/Wasabi1234/Spri ...

最新文章

  1. Google今天的logo
  2. python画图-Python数据可视化之画图
  3. [CentOS Python系列] 六.阿里云搭建Django网站详解
  4. java 泛型 extends 多个
  5. PHP高德地图描点,引用高德地图描点画行动轨迹
  6. sqlite-常用语句
  7. CentOS 7.8使用devtoolset-9使用高版本gcc version 9.3.1
  8. Python easy_insatll 安装包
  9. jdbc连接mysql驱动包_jdbc连接数据库驱动包
  10. mysql concat 索引_mysql-查看数据库、索引、表大小
  11. ArmLinux BOOTLOADER全程详解
  12. winxp netbeui install
  13. Hive 窗口函数lead、lag
  14. UrlRewrite的使用
  15. 9款最佳iPhone WiFi工具和网络分析工具,附下载链接
  16. Linux环境下安装tomcat并配置开机自启
  17. 2023年云南大学现代技术教育考研上岸前辈备考经验
  18. 总结MongoDB采用MongoRepository进行查询
  19. 5.Ansible中的任务执行控制
  20. Cesium鹰眼<利用Cesium本身你的二维地图和三维地图构成>

热门文章

  1. 安装配置Exchange 问题集
  2. Shell脚本里调用Python程序
  3. Optimizing regular expressions in Java
  4. sysctl修改内核参数
  5. 全网最全Python爬虫工具使用指南
  6. javascript浮点数学习总结之0.1+0.2
  7. OFCMS 项目开源 java cms 系统 内容管理系统
  8. 为 Confluence 6 配置发送邮件消息
  9. 如何通过解决精益问题提高敏捷团队生产力
  10. 解决nginx下connect() to 127.0.0.1:3000 failed