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. 《统计学习方法》笔记(3):k近邻

    k近邻(KNN)是相对基本的机器学习方法,特点是不需要建立模型,而是直接根据训练样本的数据对测试样本进行分类. 1.k近邻的算法? 算法对测试样本进行分类的一般过程如下: 1)根据给定的k值,搜索与测 ...

  2. js常用到的方法积累

    //获取对象长度的方法 function countObjLen(obj) { var count = 0; for (var property in obj) { if (Object.protot ...

  3. maven工程的多环境配置方案(profile)

    前言: 写一篇水文来打发下时间吧^_^. 在应用开发中, 总会遇到开发/测试/预发布/线上环境, 其环境不同, 其具体的配置项也有所不同, 因此如何快速的切换各个环境配置, 进行打包配置, 成了一个小 ...

  4. Unity 3D光源-Point Light点光源详解/灯泡、模拟灯光效果教程

    Unity4大光源之点光源 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享. ...

  5. camp待补

    待修莫对 序列自动机 几何积分 沈阳 M 待删除背包  : 分组背包 K-LIS, K次二分(插到最后stop) 问题转化为LIS bzoj2131 hdu4055 最小线段覆盖环 实时路况 分治+f ...

  6. MyBatis 遍历数组放入in中

    必须要遍历出数组的值放入in中 如果直接将"'2','3','4','5','6','7','8'" 字符串放入in中,只会查出 inv_operate_type的值为2的数据,因 ...

  7. 一次scrapy失败的提示信息:由于连接方在一段时间后没有正确答复或连接的主机没有反 应,连接尝试失败

    2017-10-31 19:09:26 [scrapy.extensions.logstats] INFO: Crawled 8096 pages (at 67 pages/min), scraped ...

  8. js的数据类型。

    字符串   String 数字    Number 布尔    Boolean Null     空 Undefined Object   对象  Array 数组   json   function ...

  9. export的变量另开一个终端失效解决方法

    有时候,我们需要把一个export的变量全局话,否则每开一个终端又需要重新export,很是麻烦 首先直接export某个变量的话就只能在当前子终端生效,另开一个终端就失效了 如果修改.bash_pr ...

  10. mysql将某数据库的全部权限赋给某用户,提示1044错误Access denied

    mysql> grant all privileges on zabbix.* to zabbix@localhost identified by 'zabbix'; ERROR 1044 (4 ...