SpringCloud实战2-Ribbon客户端负载均衡

本文涉及的产品
应用型负载均衡 ALB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 前面我们已经完成了注册中心和服务提供者两个基础组件。接着介绍使用Spring Cloud Ribbon在客户端负载均衡的调用服务。 ribbon 是一个客户端负载均衡器,可以简单的理解成类似于 nginx的负载均衡模块的功能。

前面我们已经完成了注册中心和服务提供者两个基础组件。接着介绍使用Spring Cloud Ribbon在客户端负载均衡的调用服务。

ribbon 是一个客户端负载均衡器,可以简单的理解成类似于 nginx的负载均衡模块的功能

主流的LB方案可分成两类:

  一种是集中式LB, 即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方;

  另一种是进程内LB,将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于后者,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

 

  Ribbon的架构图:如下:

 

1.首先我们先在原来的基础上新建一个Ribbon模块,如下图:

现在我们单独使用ribbon,在Ribbon模块下添加依赖,如下图所示:

<dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-ribbon</artifactId>
       <version>1.4.0.RELEASE</version>
</dependency>

 修改application.yml文件,如下所示:

server:
  port: 8082
spring:
  application:
    name: Ribbon-Consumer
#providers这个是自己命名的,ribbon,listOfServer这两个是规定的
providers:
  ribbon:
    listOfServers: localhost:8080,localhost:8081

在Ribbon模块下新建一个测试类如下代码 * Created by cong on 2018/5/8. */

@RestController
public class ConsumerController {

  //注入负载均衡客户端
 @Autowired
private LoadBalancerClient loadBalancerClient; @RequestMapping("/consumer") public String helloConsumer() throws ExecutionException, InterruptedException {
     //这里是根据配置文件的那个providers属性取的
ServiceInstance serviceInstance = loadBalancerClient.choose("providers");
      //负载均衡算法默认是轮询,轮询取得服务
URI uri = URI.create(String.format("http://%s:%s", serviceInstance.getHost(), serviceInstance.getPort())); return uri.toString();
  }

运行结果如下:

  会轮询的获取到两个服务的URL 访问第一次,浏览器出现http://localhost:8080  访问第二次就会出现http://localhost:8081

 

在这里给普及一下有哪些负载均衡算法:

  

  1:简单轮询负载均衡(RoundRobin)

       以轮询的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。

 

   2:随机负载均衡 (Random)

       随机选择状态为UP的Server

 

   3:加权响应时间负载均衡 (WeightedResponseTime)

     根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。

 

   4:区域感知轮询负载均衡(ZoneAvoidanceRule)

       复合判断server所在区域的性能和server的可用性选择server

 

有兴趣的还可以看一下我在Ngnix的随笔文章中列出的负载均衡算法实现:http://www.cnblogs.com/huangjuncong/p/8319182.html

如果想配置其他轮询算法在yml配置文件中配置,如下配置一个随机算法所示:

server:
  port: 8082
spring:
  application:
    name: Ribbon-Consumer
#providers这个是自己命名的,ribbon,listOfServer这两个是规定的
providers:
  ribbon:
    listOfServers: localhost:8080,localhost:8081

##如果不想选用默认的轮询的负载均衡算法,在这里做如下配置
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

 

接着在启动类动一下手脚让我们配置的随机算法的负载均衡生效,只需要实现一个实现了IRule接口的Bean即可,如下:

package hjc;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class RibbonApplication {

    public static void main(String[] args) {
        SpringApplication.run(RibbonApplication.class, args);
    }

    @Bean
    public IRule ribbonRule(){
        return new RandomRule();
    }
}

因此重新启动Ribbon启动类,得到的结果是随机的,如下所示:

  浏览器随机出现http://localhost:8080 或者http://localhost:8081

 

那么问题来了,服务的地址是写死在配置文件中,如果某个服务挂了,那么还会把请求转发到挂掉的服务中,因此,解决的办法是,跟Eureka对接,结合一起用。就可以依靠Eureka动态的获取一个可用的服务列表,隔一段时间我就更新一次,

或者Eureka设置一个监听端口,某一个服务挂了,Eureka通知我,我会知道,变更服务列表,这样不久形成一个闭环了吗?这样就不存在高可用性问题了。跟Eureka配合一起用同时解决了的Ribbon的单点故障问题

 

第一步,毫无疑问就是修改Ribbon模块的pom.xml文件,加入如下依赖:

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

第二步,修改yml配置文件如下:

server:
  port: 8082
spring:
  application:
    name: Ribbon-Consumer

eureka:
#客户端
  client:
#注册中心地址
    service-url:
      defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/

这样就可以跟Eureka结合,这样Ribbon就可以通过Eureka动态的获取服务列表

 

接着在启动类加上服务发现注解,如下:

@EnableDiscoveryClient

 

启动类接着声明一个负载均衡的请求器@LoadBalanced,还有请求发起的工具RestTemplate

如下代码:

@SpringBootApplication
@EnableDiscoveryClient
public class RibbonApplication {

    public static void main(String[] args) {
        SpringApplication.run(RibbonApplication.class, args);
    }


    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

 

接着我们在上一节文章中的两个provider1,provider2模块添加一下测试代码:如下:

provider1:

package hjc.hello;


import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created by cong on 2018/5/8.
 */
@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello(){
        return "hello1";
    }

}

provider2代码如下:

package hjc.hello;


import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created by cong on 2018/5/8.
 */
@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello(){
        return "hello2";
    }

}

 

接着我们用RestTemplate进行面向服务调用,不再面向IP调用。

如下代码:

/**
 * Created by cong on 2018/5/8.
 */
@RestController
public class ConsumerController {



    @Autowired
    private  RestTemplate restTemplate;

    @RequestMapping("/consumer")
    public String helloConsumer() throws ExecutionException, InterruptedException {

        return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody();

}

接着启动Ribbon模块,我们看一下Eureka仪表盘,如下:

 

可以看到多了RIBBON-CONSUMER服务

 

接着我们继续在已经运行的Ribbon模块上,在浏览器输入localhost:8082,运行结果如下:

  hello1或者hello2,

可以看到hello1 ,hello2轮询方式出现,因为默认就是轮询方式

 

到这里我们还发现Ribbon还是单点故障的,这里我来解释一下:

  因为这里我是单独建立一个SpringBoot的Ribbon模块,实际使用并不是这样用的,Ribbon是客户端的负载均衡,是跟客户端绑定在一起的,我们实际运用的时候往往会在服务里面引入一个客户端负载均衡去连接到Eureka客户中心,

这样我们还存在Ribbon单点故障吗?不存在了,因为我们服务提供者就是高可用的,这样还是个单点吗?这里读者的思考必须转过弯来,这一篇随笔我只是为了演示Ribbon,实际使用并不是这样用的。

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
25天前
|
消息中间件 监控 Java
如何将Spring Boot + RabbitMQ应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + RabbitMQ应用程序部署到Pivotal Cloud Foundry (PCF)
31 6
|
25天前
|
Java 关系型数据库 MySQL
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
45 5
|
25天前
|
缓存 监控 Java
如何将Spring Boot应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot应用程序部署到Pivotal Cloud Foundry (PCF)
35 5
|
1月前
|
负载均衡 监控 网络协议
SpringCloud之Ribbon使用
通过以上步骤,就可以在Spring Cloud项目中有效地使用Ribbon来实现服务调用的负载均衡,提高系统的可靠性和性能。在实际应用中,根据具体的业务场景和需求选择合适的负载均衡策略,并进行相应的配置和优化,以确保系统的稳定运行。
75 15
|
1月前
|
负载均衡 算法 Java
除了 Ribbon,Spring Cloud 中还有哪些负载均衡组件?
这些负载均衡组件各有特点,在不同的场景和需求下,可以根据项目的具体情况选择合适的负载均衡组件来实现高效、稳定的服务调用。
90 5
|
22天前
|
负载均衡 Java Nacos
常见的Ribbon/Spring LoadBalancer的负载均衡策略
自SpringCloud 2020版起,Ribbon被弃用,转而使用Spring Cloud LoadBalancer。Ribbon支持轮询、随机、加权响应时间和重试等负载均衡策略;而Spring Cloud LoadBalancer则提供轮询、随机及Nacos负载均衡策略,基于Reactor实现,更高效灵活。
54 0
|
3月前
|
负载均衡 Java Nacos
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
微服务介绍、SpringCloud、服务拆分和远程调用、Eureka注册中心、Ribbon负载均衡、Nacos注册中心
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
|
3月前
|
负载均衡 Java 开发者
Ribbon框架实现客户端负载均衡的方法与技巧
Ribbon框架为微服务架构中的客户端负载均衡提供了强大的支持。通过简单的配置和集成,开发者可以轻松地在应用中实现服务的发现、选择和负载均衡。适当地使用Ribbon,配合其他Spring Cloud组件,可以有效提升微服务架构的可用性和性能。
48 0
|
25天前
|
负载均衡 前端开发 应用服务中间件
负载均衡指南:Nginx与HAProxy的配置与优化
负载均衡指南:Nginx与HAProxy的配置与优化
44 3
|
6月前
|
缓存 负载均衡 算法
解读 Nginx:构建高效反向代理和负载均衡的秘密
解读 Nginx:构建高效反向代理和负载均衡的秘密
134 2