• 微服务是什么?它的优缺点有哪些?
  • Spring Boot简介
  • Spring Boot项目搭建步骤(超详细)
  • 使用Eureka编写服务提供者
  • 使用Eureka编写服务消费者
  • Eureka注册中心开启密码认证
  • Spring Cloud使用Eureka集群搭建实现高可用服务注册中心
  • Eureka自我保护模式和InstanceID的配置
  • Eureka开发时快速移除失效服务
  • Eureka开发时快速移除失效服务
  • Spring Cloud Ribbon(负载均衡器)介绍及使用
  • Spring Cloud Ribbon结合RestTemplate实现负载均衡
  • Spring Cloud Ribbon配置详解
  • Spring Cloud使用Feign调用服务接口
  • Spring Cloud Feign的自定义配置及使用
  • Spring Cloud Hystrix缓存与合并请求
  • Spring Cloud Zuul网关的介绍及使用
  • Spring Cloud Zuul过滤器介绍及使用(传递数据、拦截请求和异常处理)
  • Spring Cloud使用Zuul实现容错回退功能
  • Spring Cloud Zuul请求响应信息输出
  • Spring Cloud实现Zuul自带的Debug功能
  • Spring Cloud Gateway整合Eureka路由转发
  • Spring Cloud Gateway的常用路由断言工厂
  • Spring Cloud Gateway过滤器工厂的使用
  • Spring Cloud Gateway全局过滤器(GlobalFilter)
  • Smconf(分布式配置管理框架)概述
  • Apollo(分布式配置中心)核心概念及核心功能介绍
  • Apollo本地部署详细步骤
  • Apollo Portal管理后台的使用
  • Apollo高可用设计分析
  • Spring Cloud使用Sleuth在应用中进行日志跟踪
  • Spring Cloud Sleuth与ELK(日志分析系统)配合使用
  • Spring Cloud整合Zipkin进行服务跟踪
  • JWT(Json Web Token)是什么?
  • Spring Cloud基于JWT创建统一的认证服务
  • Zuul中传递Token到路由的服务中
  • Spring Boot Admin的介绍及使用
  • Swagger是什么?Swagger怎么用?
  • 使用Zuul聚合多个微服务的Swagger文档
  • 微服务架构下如何获取用户信息并认证?
  • 服务降级是什么?Spring Cloud如何实现?
  • Guava Cache本地缓存介绍及使用
  • 防止缓存雪崩的方案
  • Spring Cloud Ribbon(负载均衡器)介绍及使用

    目前主流的负载方案分为以下两种:

    • 集中式负载均衡,在消费者和服务提供方中间使用独立的代理方式进行负载,有硬件的(比如 F5),也有软件的(比如 Nginx)。
    • 客户端自己做负载均衡,根据自己的请求情况做负载,Ribbon 就属于客户端自己做负载。

    Spring Cloud Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具,它基于 Netflix Ribbon 实现。通过 Spring Cloud 的封装,可以让我们轻松地将面向服务的 REST 模版请求自动转换成客户端负载均衡的服务调用。

    Spring Cloud Ribbon 虽然只是一个工具类框架,它不像服务注册中心、配置中心、API 网关那样需要独立部署,但是它几乎存在于每一个 Spring Cloud 构建的微服务和基础设施中。因为微服务间的调用,API 网关的请求转发等内容,实际上都是通过 Ribbon 来实现的(https://github.com/Netflix/ribbon)。

    Ribbon 模块

    Ribbon 模块介绍如下表 1 所示。

    名 称 说 明
    ribbon-loadbalancer 负载均衡模块,可独立使用,也可以和别的模块一起使用。
    Ribbon 内置的负载均衡算法都实现在其中。
    ribbon-eureka 基于 Eureka 封装的模块,能够快速、方便地集成 Eureka。
    ribbon-transport 基于 Netty 实现多协议的支持,比如 HTTP、Tcp、Udp 等。
    ribbon-httpclient 基于 Apache HttpClient 封装的 REST 客户端,集成了负载均衡模块,可以直接在项目中使用来调用接口。
    ribbon-example Ribbon 使用代码示例,通过这些示例能够让你的学习事半功倍。
    ribbon-core 一些比较核心且具有通用性的代码,客户端 API 的一些配置和其他 API 的定义。

    Ribbon 使用

    我们使用 Ribbon 来实现一个最简单的负载均衡调用功能,接口就用《使用Eureka编写服务提供者》提供的 /user/hello 接口,需要启动两个服务,一个是 8081 的端口,一个是 8083 的端口。

    然后创建一个新的 Maven 项目 ribbon-native-demo,在项目中集成 Ribbon,在 pom.xml 中添加如下代码所示的依赖。

    1. <dependency>
    2. <groupId>com.netflix.ribbon</groupId>
    3. <artifactId>ribbon</artifactId>
    4. <version>2.2.2</version>
    5. </dependency>
    6. <dependency>
    7. <groupId>com.netflix.ribbon</groupId>
    8. <artifactId>ribbon-core</artifactId>
    9. <version>2.2.2</version>
    10. </dependency>
    11. <dependency>
    12. <groupId>com.netflix.ribbon</groupId>
    13. <artifactId>ribbon-loadbalancer</artifactId>
    14. <version>2.2.2</version>
    15. </dependency>
    16. <dependency>
    17. <groupId>io.reactivex</groupId>
    18. <artifactId>rxjava</artifactId>
    19. <version>1.0.10</version>
    20. </dependency>

    接下来我们编写一个客户端来调用接口,代码如下所示。

    1. // 服务列表
    2. List<Server> serverList = Lists.newArrayList(new Server("localhost", 8081), new Server("localhost", 8083));
    3. // 构建负载实例
    4. ILoadBalancer loadBalancer = LoadBalancerBuilder.newBuilder().buildFixedServerListLoadBalancer(serverList);
    5. // 调用 5 次来测试效果
    6. for (int i = 0; i < 5; i++) {
    7. String result = LoadBalancerCommand.<String>builder().withLoadBalancer(loadBalancer).build()
    8. .submit(new ServerOperation<String>() {
    9. public Observable<String> call(Server server) {
    10. try {
    11. String addr = "http://" + server.getHost() + ":" + server.getPort() + "/user/hello";
    12. System.out.println(" 调用地址:" + addr);
    13. URL url = new URL(addr);
    14. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    15. conn.setRequestMethod("GET");
    16. conn.connect();
    17. InputStream in = conn.getInputStream();
    18. byte[] data = new byte[in.available()];
    19. in.read(data);
    20. return Observable.just(new String(data));
    21. } catch (Exception e) {
    22. return Observable.error(e);
    23. }
    24. }
    25. }).toBlocking().first();
    26. System.out.println(" 调用结果:" + result);
    27. }

    上述这个例子主要演示了 Ribbon 如何去做负载操作,调用接口用的最底层的 HttpURLConnection。当然你也可以用别的客户端,或者直接用 RibbonClient 执行程序,可以看到控制台输出的结果如下:

    控制台输出结果
    图 1 控制台输出结果

    从输出的结果中可以看到,负载起作用了,8083 调用了 3 次,8081 调用了 2 次。