Spring Cloud 讲解 (二) | Spring Cloud Ribbon 客户端负载均衡

Spring Cloud Ribbon

1. 负载均衡器

为了实现系统的高可用、缓解网络压力等,往往要考虑使用集群,而谈到集群,就不得不考虑负载均衡的问题。

负载均衡分为 客户端负载均衡 服务端负载均衡

1.1 负载均衡器的作用:

维护服务端清单,通过心跳监测来剔除有故障的服务端节点,确保清单中的都是可以正常访问的服务端节点。
当客户端发送请求到负载均衡设备时,该设备按照某种算法(轮询、加权、随机等)从清单中取出一台服务端地址,然后进行转发。

而客户端负载均衡和服务端负载均衡的最大不同点在于 服务清单所存储的位置。

另外客户端所持有的服务清单来源于服务注册中心,并且需要自己去维护清单的可用性(需要与注册中心配合)。

通常我们所说的负载均衡都指的是服务端负载均衡,不过这次所介绍的,则是如何使用 Ribbon 来实现客户端的负载均衡。

那为什么Spring Cloud 采用了客户端负载均衡,而不是我们常用的服务端负载均衡呢?

1.2 客户端负载均衡的优点:

对于服务端负载均衡,分为两种,即硬件和软件,硬件类如常见的F5,软件类如Nginx,通常还需再购买一个Nginx服务器,不论是哪一种,都需要额外支出一笔开销。客户端负载均衡可以省去这一部分开销,因为它是在自身处设定了一个调度算法,在向服务器发起请求的时候,利用算法确定向哪台服务器发起请求,随后发起实际请求。这些都是客户端内部程序实现,因此不需要额外的负载均衡器软硬件投入。

2. 使用 Ribbon 实现客户端负载均衡

Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具类框架,不需要像Spring Cloud Eureka 那样独立部署。

作用:微服务间的调用、API网关的请求转发等,通过使用ribbon,可以轻松实现客户端负载均衡。

使用Spring Cloud Ribbon,我们在微服务中使用客户端负载均衡非常的简单:

2.1 启动多个服务实例,并注册到服务注册中心。

创建 a1_service 和 a2_service ,服务名称均设置成 aService,端口分别为8180、8181,如下:

# a1_service 的 application.yml

server:
  port: 8180  #服务的端口

spring:
  application:
    name: aService #服务命名, 注意:不能使用下划线等

eureka:
    client:
      service-url:
        defaultZone: http://localhost:1111/eureka/ #指定服务注册中心的地址
# a2_service 的 application.yml

server:
  port: 8181  #服务的端口

spring:
  application:
    name: aService #服务命名 注意:不能使用下划线等!

eureka:
    client:
      service-url:
        defaultZone: http://localhost:1111/eureka/ #指定服务注册中心的地址

分别启动a1_service和a2_service, 访问服务注册中心( http://localhost:1111/eureka/ ),两个服务均注册成功:

2.2 调用服务的一方使用被注解 @LoadBalanced 修饰的RestTemplate 来实现向服务接口的调用。

创建子服务 ribbon_service,主程序文件 以及 application.yml 内容如下:

@EnableEurekaClient //激活服务发现
@SpringBootApplication
public class RibbonServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(RibbonServiceApplication.class, args);
    }

    @Bean
    @LoadBalanced //使用客户端负载均衡
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
spring:
  application:
    name: ribbonService #服务命名, 注意:不能使用下划线等

server:
  port: 9000  #服务端口

eureka:
  client:
    service-url:
      defaultZone: http://localhost:1111/eureka/  #指定注册中心地址

另外 pom.xml 中也要引入依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    <version>1.4.5.RELEASE</version>
</dependency>

继续在ribbon_service下创建一个HelloControl.java,来请求 aService 服务的接口:

@RestController
public class HelloControl {

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/hi")
    public void hiAction() {

        for (int i = 0; i < 4; i ++) {

            String line = restTemplate.getForEntity("http://ASERVICE/hello",
                    String.class).getBody() + "\t" +
                    "time: " + System.currentTimeMillis();

            System.out.println(line);
        }
    }
}

浏览器中访问:http://localhost:9000/hi,会发现控制台打印出如下:

Hello , I am from: aService 8181    time: 1541498155051
Hello , I am from: aService 8180    time: 1541498155145
Hello , I am from: aService 8181    time: 1541498155150
Hello , I am from: aService 8180    time: 1541498155155

可以看出,aService 的两个不同端口(8180、8181)的子服务轮流被调用,即客户端负载均衡。

点击获取本节:示例代码


版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接。
✿ 获取更多,请戳这儿

Comments
Write a Comment