zoukankan      html  css  js  c++  java
  • Spring Cloud(Dalston.SR5)--Ribbon 中间层负载均衡

    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:

      port:8085

      #设置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>.ConnectTimeout

    60000

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

    <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

      

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

       

       

  • 相关阅读:
    [Linux] day04——Linux 入门
    react 资源汇总
    画原型图工具
    Atom 插件安装
    react 编写组件 五
    webstom 配置git 后左侧菜单栏配色调整
    Webstorm 不识别es6 import React from ‘react’——webstorm不支持jsx语法怎么办
    Es6 之for of
    一个react的完整项目展示
    前后端分离 接口管理神器——Rap本地搭建
  • 原文地址:https://www.cnblogs.com/li3807/p/8916774.html
Copyright © 2011-2022 走看看