Spring Cloud 集成了 Ribbon 并结合 Eureka 可以实现客户端的负载均衡,使用 @LoadBalanced 修饰的 RestTemplate 类拥有了负载均衡功能,在 Spring 容器启动时,会为这些修饰过的 RestTemplate 添加拦截器,拦截器中使用 LoadBalancerClient 来处理请求,LoadBalancerClient 是 Spring 封装的负载均衡客户端,通过这样间接的处理,使得 RestTemplate 拥有了负载均衡的功能。下面我们在 Spring Cloud 中使用 Ribbon 示例如下:

  • 创建项目

    创建名称为 spring-cloud-ribbon-client 的 Spring Cloud 项目,修改 POM.xml 中增加以下依赖项:

    <?xmlversion="1.0"encoding="UTF-8"?>

    <projectxmlns="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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

     
     

    <groupId>org.lixue</groupId>

    <artifactId>spring-cloud-ribbon-client</artifactId>

    <version>1.0-SNAPSHOT</version>

    <packaging>jar</packaging>

    <name>spring-cloud-ribbon-client</name>

    <description>spring-cloud-ribbon-client</description>

     
     

    <parent>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-parent</artifactId>

    <version>1.5.4.RELEASE</version>

    <relativePath/><!--lookupparentfromrepository-->

    </parent>

     
     

    <properties>

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

    <java.version>1.8</java.version>

    <spring-cloud.version>Dalston.SR5</spring-cloud.version>

    </properties>

    <dependencies>

    <dependency>

    <groupId>org.springframework.cloud</groupId>

    <artifactId>spring-cloud-starter-eureka</artifactId>

    </dependency>

    <dependency>

    <groupId>org.springframework.cloud</groupId>

    <artifactId>spring-cloud-starter-ribbon</artifactId>

    </dependency>

    <dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-test</artifactId>

    <scope>test</scope>

    </dependency>

    </dependencies>

    <dependencyManagement>

    <dependencies>

    <dependency>

    <groupId>org.springframework.cloud</groupId>

    <artifactId>spring-cloud-dependencies</artifactId>

    <version>${spring-cloud.version}</version>

    <type>pom</type>

    <scope>import</scope>

    </dependency>

    </dependencies>

    </dependencyManagement>

    <build>

    <plugins>

    <plugin>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-maven-plugin</artifactId>

    </plugin>

    </plugins>

    </build>

    </project>

  • 创建 Ribbon 配置类

    Spring Cloud 中,可以将自定义的负载均衡规则以及自定义 Ping、ServerList 、ServerListFilter 和ServerListUpdater 等增加到服务器调用者,下面的 MyPing 和 MyServerListFilter 类为自定义类,注意,如果希望该 Ribbon 配置类只用于部分服务调用,则一定不能处于使用该 @ComponentScan 注解类的同一个包中,如果处于同一个包中,会被所有 Ribbon 使用。

    package org.lixue.ribbon;

     
     

    import com.netflix.loadbalancer.IPing;

    import com.netflix.loadbalancer.Server;

    import com.netflix.loadbalancer.ServerListFilter;

    import org.springframework.context.annotation.Bean;

     
     

    public class MyRibbonConfig{

    @Bean

    public IPing getPing(){

    return new MyPing();

    }

     
     

    @Bean

    public ServerListFilter<Server> getServerListFilter(){

    return new MyServerListFilter();

    }

    }

    除了使用自定义配置类外,还可以使用配置文件的方式来配置定义各个属性,配置项和单独使用 Ribbon 一致,比如上面类的属性,定义到 application.yml 中,如下:

    helloworld-provider:

    ribbon:

    # 配置 IPing 的实现类

    NFLoadBalancerPingClassName:org.lixue.ribbon.MyPing

    # 用于处理服务器列表拦截过滤

    NIWSServerListFilterClassName:org.lixue.ribbon.MyServerListFilter

     
     

  • 创建配置类

    将 Rest 服务调用的 RestTemplate 增加 @LoadBalanced 和 @Bean 注解标注,表示该 RestTemplate 支持负载均衡。

    package org.lixue.ribbonclient;

     
     

    import org.springframework.cloud.client.loadbalancer.LoadBalanced;

    import org.springframework.context.annotation.Bean;

    import org.springframework.context.annotation.Configuration;

    import org.springframework.web.client.RestTemplate;

     
     

    @Configuration

    public class RestClientConfiguration{

    @LoadBalanced

    @Bean

    public RestTemplate restTemplate(){

    return new RestTemplate();

    }

    }

  • 创建客户端类

    客户端类比较简单,使用 RestTemplate 实例,请求Rest 服务的 Url 即可,Url 的不是具体的地址,而是根据名称来调用服务,示例:http://helloworld-provider/speak ,表示调用 helloworld-provider 服务的 speak ,最终请求的的地址是通过解析 helloworld-provider 服务的注册 Eureka 的地址,通过负载均衡决定实际的 Url 地址。

    package org.lixue.ribbonclient;

     
     

    import org.lixue.ribbon.MyRibbonConfig;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.cloud.netflix.ribbon.RibbonClient;

    import org.springframework.stereotype.Component;

    import org.springframework.web.client.RestTemplate;

     
     

    import java.io.UnsupportedEncodingException;

    import java.net.URLEncoder;

    // 如果使用配置文件,则无需使用 @RibbonClient 注解

    @RibbonClient(name="helloworld-provider",configuration=MyRibbonConfig.class)

    @Component

    public class HelloWorldServiceClient{

    @Autowired

    private RestTemplate restTemplate;

     
     

    public String speak(Stringbody) throws UnsupportedEncodingException{

    StringencodeBody="";

    if(body!=null){

    encodeBody="?body="+URLEncoder.encode(body,"utf-8");

    }

    try{

    return restTemplate.getForObject("http://helloworld-provider/speak"+encodeBody,String.class);

    }catch(Exceptionex){

    ex.printStackTrace();

    System.out.println("Exceptionisclass"+ex.getClass().getName());

    return ex.getMessage();

    }

    }

    }

     
     

  • 创建 REST 服务

    package org.lixue.ribbonclient;

     
     

    import org.springframework.beans.factory.annotation.Autowired;

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

    import org.springframework.web.bind.annotation.RequestMethod;

    import org.springframework.web.bind.annotation.RequestParam;

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

     
     

    import java.io.UnsupportedEncodingException;

    @RestController

    public class InvokerController{

     
     

    @Autowired

    private HelloWorldServiceClient helloWorldServiceClient;

     
     

    @RequestMapping(name="speak",method=RequestMethod.GET)

    public String speak(@RequestParam(name="body",required=false) String body)throws UnsupportedEncodingException{

    return helloWorldServiceClient.speak(body);

    }

    }

     
     

  • 增加配置

    调整
    src/main/resources 目录中的 application.yml 配置文件,调整后配置如下:

    #配置应用名称

    spring:

    application:

    name:spring-cloud-ribbon-client

    #服务端口

    server:

    #设置eureka服务注册中心的地址,如果多个以逗号分割

    eureka:

    client:

    service-url:

    #defaultZone表示默认的区域的eureka服务地址,多个使用逗号分割

    defaultZone:http://eurekaserver01:9000/eureka/,http://eurekaserver02:9000/eureka/

    # 使用代码配置类无需配置

    helloworld-provider:

    ribbon:

    NFLoadBalancerPingClassName:org.lixue.ribbon.MyPing

    NIWSServerListFilterClassName:org.lixue.ribbon.MyServerListFilter

     
     

  • 测试验证

    启动 eureka-server 服务、启动多个 service-provider 服务(服务器地址或端口区分),启动该项目,访问地址 http://localhost:8085/speak ,多刷新几次可以看到分别访问了不同的 service-provider 服务,如下:

    hello world port:8001

    hello world port:8002

常用配置

<client> 表示的调用服务名称;<namespace> 为配置的命名空间,默认为 ribbon;如果是全局配置,则 <client>.<namespace>使用 ribbon 替换,例如,ribbon.listOfServers 表示全局的服务器列表;

设置连接服务超时时间(毫秒)

<client>.<namespace>.ReadTimeout

60000

设置读取服务超时时间(毫秒)

<client>.<namespace>.OkToRetryOnAllOperations

false

对所有操作请求都进行重试

<client>.<namespace>.MaxAutoRetriesNextServer

  

切换实例的重试次数

<client>.<namespace>.MaxAutoRetries

  

对当前实例的重试次数

<client>.<namespace>.NFLoadBalancerRuleClassName

  

配置负载均衡规则 IRule 的实现类

<client>.<namespace>.NFLoadBalancerClassName

  

配置负载均衡实现类

<client>.<namespace>.NIWSServerListClassName

  

服务器列表处理类,用来维护服务器列表,Ribbon 已经实现动态服务列表

<client>.<namespace>.NIWSServerListFilterClassName

  

用于处理服务器列表拦截过滤

 
 

 
 

Spring Cloud(Dalston.SR5)--Ribbon 中间层负载均衡的更多相关文章

  1. Spring Cloud:使用Ribbon实现负载均衡详解(下)

    在上一篇文章(Spring Cloud:使用Ribbon实现负载均衡详解(上))中,我对 Ribbon 做了一个介绍,Ribbon 可以实现直接通过服务名称对服务进行访问.这一篇文章我详细分析一下如何 ...

  2. Spring Cloud:使用Ribbon实现负载均衡详解(上)

    1. 什么是 Ribbon? Spring Cloud Ribbon 是一套实现客户端负载均衡的工具.注意是客户端,当然也有服务端的负载均衡工具,我们后面再介绍.可以认为 Ribbon 就是一个负载均 ...

  3. 3.Spring Cloud初相识--------Ribbon客户端负载均衡

    前言: 在生产环境中,未避免单点故障,每个微服务都会做高可用部署. 通白的说,就是每一个一模一样的服务会根据需求提供多分在多台机器上. 那么在大并发的情况下,如何分配服务可以快速得到响应,就成为了我们 ...

  4. Spring Cloud第四篇 | 客户端负载均衡Ribbon

    ​ 本文是Spring Cloud专栏的第四篇文章,了解前三篇文章内容有助于更好的理解本文: ​Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Cl ...

  5. 史上最全Spring Cloud Alibaba--Nacos教程(涵盖负载均衡、配置管理、多环境切换、配置共享/刷新、灰度、集群)

    能够实现Nacos安装 基于Nacos能实现应用负载均衡 能基于Nacos实现配置管理 配置管理 负载均衡 多环境切换 配置共享 配置刷新 灰度发布 掌握Nacos集群部署 1 Nacos安装 Nac ...

  6. Spring Cloud(Dalston.SR5)--Zuul 网关-微服务集群

    通过 url 映射的方式来实现 zuul 的转发有局限性,比如每增加一个服务就需要配置一条内容,另外后端的服务如果是动态来提供,就不能采用这种方案来配置了.实际上在实现微服务架构时,服务名与服务实例地 ...

  7. Spring Cloud(Dalston.SR5)--Feign 声明式REST客户端

    Spring Cloud 对 Feign 进行了封装,集成了 Ribbon 并结合 Eureka 可以实现客户端的负载均衡,Spring Cloud 实现的 Feign 客户端类名为 LoadBala ...

  8. Spring Cloud(Dalston.SR5)--Eureka 服务消费

    服务被注册.发布到 Eureka 服务器后,需要有程序去发现他,并且进行调用,称为服务消费,一个服务可能会部署多个实例,调用过程可能涉及负载均衡.服务器查找等问题,这些问题 Netflix 项目已经帮 ...

  9. Spring Cloud(Dalston.SR5)--Zuul 网关

    我们使用 Spring Cloud Netflix 中的 Eureka 实现了服务注册中心以及服务注册与发现:而服务间通过 Ribbon 或 Feign 实现服务的消费以及均衡负载:使用Hystrix ...

随机推荐

  1. Java学习笔记9(面象对象9:多态)

    多态概述 多态是继封装.继承后,面对对象的第三大特性. 现实事物经常会出现多态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态. Java作为面向对象的语言,同样可以描述一 ...

  2. python中闭包

    闭包是指内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure). 闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变 ...

  3. mysqli扩展库的预处理

    预处理的特点:1.效率高,执行速度快 2.安全性高,可以防止sql注入 $mysqli  中的函数 $stmt=$mysqli->prepare($sql);             预备一条s ...

  4. async/await学习笔记

    async/await 的目的是简化使用 promises 的写法.     让我们来看看下面的例子: // 一个标准的 JavaScript 函数 function getNumber1() { r ...

  5. Ubuntu add sudo

    为了安全起见,ubuntu中的普通用户一般没有root权限,因此即使知道管理员密码也无法使用sudo,但这个情况可以通过加入sudoer列表或者加入sudo组来改变. 拓展: 不管使用哪种方式,使得一 ...

  6. HSTS 与 307 状态码

    最近线上产品突然在 Chrome 浏览器上出现 307 状态码,并跳转到 https 版.由于 https 尚未部署完毕,导致了相当严重的后果. 但是 307 代码是什么含义呢?页面又为何会出现 30 ...

  7. shell 脚本中将输出内容赋值给一个变量时的换行问题

    for ((i=0; i<4; i++) do ....... done 如果使用 echo $a 输出变量,则变量中的 换行都会被忽略掉,所有内容输出到一行 而使用 echo "$a ...

  8. 洛谷 P4779 :【模板】单源最短路径(标准版)(Dijkstra+堆优化+链式前向星)

    题目背景 2018 年 7 月 19 日,某位同学在 NOI Day 1 T1 归程 一题里非常熟练地使用了一个广为人知的算法求最短路. 然后呢? 100→60: Ag→Cu: 最终,他因此没能与理想 ...

  9. 自我复制的3D打印机

    RepRap 是人类历史上第一部可以自我复制型的机器. https://reprap.org/wiki/RepRap RepRap 是一部可以生成塑料实物的免费桌面型 3D 打印机.由于 RepRap ...

  10. hdu4549 M斐波那契数列 矩阵快速幂+快速幂

    M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = aF[1] = bF[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a, b, n,你能求出F[n]的 ...