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. 你知道怎么用Idea抽取方法、创建class吗?

    liJ IDEA的快捷键是进行重构的利器,坊间盛传,完全使用IDEA快捷键重构的代码,是不需要写测试用例保护的 本文就分享一个使用IDEA抽取方法及创建新的class的方法 工具/原料   Intel ...

  2. GB2312汉字编码字符集对照表

    第01区 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F A1A0 . . ・ ˉ ˇ ¨ " 々 ― - | - ' ' A1B0 &quo ...

  3. table中head表头固定,body滚动

    <style type="text/css"> .table-head { background-color: #; color: #; } .table-body { ...

  4. 常见Web应用程序漏洞

    不完善的身份验证措施 .这类漏洞包括应用程序登录机制中的各种缺陷,可能会使攻击者破解保密性不强的密码.发动蛮力攻击或完全避开登录. 不完善的访问控制措施.这一问题涉及的情况包括:应用程序无法为数据和功 ...

  5. shell统计当前文件夹下的文件个数、目录个数

    1. 统计当前文件夹下文件的个数 ls -l |grep "^-"|wc -l 2. 统计当前文件夹下目录的个数 ls -l |grep "^d"|wc -l ...

  6. nginx php

    server { listen 443; server_name www.awkj.com; ssl on; ssl_certificate cert/214683879970617.pem; ssl ...

  7. PHP 设计模式系列 —— 工厂方法模式(Factory Method)(转)

    1.模式定义 定义一个创建对象的接口,但是让子类去实例化具体类.工厂方法模式让类的实例化延迟到子类中. 2.问题引出 框架需要为多个应用提供标准化的架构模型,同时也要允许独立应用定义自己的域对象并对其 ...

  8. 深入理解Java中的多态

    一.什么是多态? 多态指同一个实体同时具有多种形式.它是面向对象程序设计(OOP)的一个重要特征.如果一个语言只支持类而不支持多态,只能说明它是基于对象的,而不是面向对象的. 二.多态是如何实现的? ...

  9. tflearn weights获取与存储

    参考: http://tflearn.org/examples/

  10. 初学C#windows程序

    window 操作系统中,处处是窗体 优点:简单 强大 方便 灵活 步骤: 新建项目 项目类型 visual C#项目 模板 window应用程序 用partial 将同一个窗体的代码分开放在两个文件 ...