SpringCloud学习 - Ribbon负载均衡(客户端)

  1. Ribbon负载均衡(客户端)

书签:

(1)@LoadBalanced 负载均衡

(2)Ribbon自带的负载规则

(3)Ribbon自定义负载规则

  1. @LoadBalanced 负载均衡

复制项目eureka-provider,生成eureka-provider-2,修改eureka-provider-2的端口成8091即可,请求返回的信息改变一下:

@GetMapping("/t")
public Object t(){
   return "msg from provider-2";// 后面加个2,方便对比
}

 

修改eureka-consumer项目启动类:主要是加上注解@LoadBalanced;请求服务提供者用服务名

package cn.ywj.eurekaconsumer;

import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@RestController
public class EurekaConsumerApplication {

   @Bean
   @LoadBalanced
   public RestTemplate getRestTemplate () {// 注入一个RestTemplate
      return new RestTemplate() ;
   }

   @Autowired
   private RestTemplate restTemplate;

   //@Autowired
   //private EurekaClient eurekaClient;

   @RequestMapping("/t")
   public Object t(){

      //InstanceInfo instanceInfo = eurekaClient.getNextServerFromEureka("EUREKA-PROVIDER", false);// 通过服务名可以拿到地址
      String str = restTemplate.getForObject("http://EUREKA-PROVIDER/t", String.class);// 直接用服务名请求
      return str;
   }

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

 

 

启动eureka-consumer项目,访问:http://localhost:8082/t 返回的结果有时是:msg from provider,有时是:msg from provider-2,轮来轮去。

 

  1. Ribbon自带的负载规则

package cn.ywj.eurekaconsumer;

import com.netflix.loadbalancer.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RibbonConfiguration {

    @Bean
    public IRule ribbonRule() {
        return new RoundRobinRule();// 轮循算法

        /*
        相关算法

        一、RoundRobinRule :系统默认的规则,通过简单地轮询服务列表来选择服务器

        二、AvailabilityFilteringRule 该规则会忽略以下服务器

            1、无法连接的服务器 在默认情况下,如果 次连接失败,该服务器将会被置为“路”的状态,该状态将持续 30 秒;如果再次连接失败, “短路”状态的持续时间
            将会以几何级数增加。可以通过修改 niws.loadbalancer. <clientName>.connectionFailureCountThreshold
            属性,来配置连接失败的次数

            2、并发数过高的服务器:如果连接到该服务器的并发数过高,也会被这个规则忽略,可以通过修改< lientName> .ribbon.ActiveConnectionsLirnit 属性
            来设最高并发数

        三、WeightedResponseTimeRule :为每个服务器赋予一个权重值 服务器的响应时间越长,该权重值就越少,这个规则会随机选择服务器,权重值有可能会决定服务器选择

        四、ZoneAvoidanceRule :该规则以区域、可用服务器为基础进行服务器选择。使用 Zone对服务器进行分类,可以理解为机架或者机房

        五、BestAvailableRule :忽略“短路”的服务器,并选择并发数较低的服务器。

        六、RandomRule :顾名思义,随机选择可用的服务器。

        七、RerRule 含有重试的选择逻辑,如果使用 RoundRobinRule 选择的服务器无法连接,那么将会重新选择服务器。*/
    }
}

 

 

  1. Ribbon自定义负载规则

参考RandomRule.java类,简单自定义一个规则 -- 只访问第一个服务

创建DiyRibbon.java

DiyRibbon.java不能被@ComponentScan扫到!

DiyRibbon.java不能被@ComponentScan扫到!

DiyRibbon.java不能被@ComponentScan扫到!

package diy.ribbon;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 此类不能被@ComponentScan扫到
 */
public class DiyRibbon extends AbstractLoadBalancerRule {


    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

    @Override
    public Server choose(Object o) {
        return choose(getLoadBalancer(), o);
    }

    protected int chooseRandomInt(int serverCount) {
        return ThreadLocalRandom.current().nextInt(serverCount);
    }
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        List<Server> upList = lb.getReachableServers();
        System.out.println("--->"+upList.size());
        if(upList != null && upList.size() > 0){
            return upList.get(0);// 拿第一个
        }
        return null;
    }
}

 

创建配置类:RibbonConfiguration.java

package cn.ywj.eurekaconsumer;

import com.netflix.loadbalancer.*;
import diy.ribbon.DiyRibbon;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RibbonConfiguration {

    @Bean
    public IRule ribbonRule() {

        return new DiyRibbon();// 自定义负载规则

        //return new RoundRobinRule();// 轮循算法

        /*
        相关算法

        一、RoundRobinRule :系统默认的规则,通过简单地轮询服务列表来选择服务器

        二、AvailabilityFilteringRule 该规则会忽略以下服务器

            1、无法连接的服务器 在默认情况下,如果 次连接失败,该服务器将会被置为“路”的状态,该状态将持续 30 秒;如果再次连接失败, “短路”状态的持续时间
            将会以几何级数增加。可以通过修改 niws.loadbalancer. <clientName>.connectionFailureCountThreshold
            属性,来配置连接失败的次数

            2、并发数过高的服务器:如果连接到该服务器的并发数过高,也会被这个规则忽略,可以通过修改< lientName> .ribbon.ActiveConnectionsLirnit 属性
            来设最高并发数

        三、WeightedResponseTimeRule :为每个服务器赋予一个权重值 服务器的响应时间越长,该权重值就越少,这个规则会随机选择服务器,权重值有可能会决定服务器选择

        四、ZoneAvoidanceRule :该规则以区域、可用服务器为基础进行服务器选择。使用 Zone对服务器进行分类,可以理解为机架或者机房

        五、BestAvailableRule :忽略“短路”的服务器,并选择并发数较低的服务器。

        六、RandomRule :顾名思义,随机选择可用的服务器。

        七、RerRule 含有重试的选择逻辑,如果使用 RoundRobinRule 选择的服务器无法连接,那么将会重新选择服务器。*/
    }
}

 

启动类加入注解:@RibbonClient

package cn.ywj.eurekaconsumer;

import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.net.MalformedURLException;
import java.net.URI;

@SpringBootApplication
@RestController
@RibbonClient(name = "eureka-provider", configuration = RibbonConfiguration.class)// name是服务注册者
public class EurekaConsumerApplication {

   @Bean
   @LoadBalanced
   public RestTemplate getRestTemplate () {// 注入一个RestTemplate
      return new RestTemplate() ;
   }

   @Autowired
   private RestTemplate restTemplate;

   //@Autowired
   //private EurekaClient eurekaClient;

   @RequestMapping("/t")
   public Object t(){

      //InstanceInfo instanceInfo = eurekaClient.getNextServerFromEureka("EUREKA-PROVIDER", false);// 通过服务名可以拿到地址
      String str = restTemplate.getForObject("http://EUREKA-PROVIDER/t", String.class);// 直接用服务名请求
      return str;
   }

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

测试结果:怎么刷新都只是返回第一个provider返回的信息。。。OK

猜你喜欢

转载自blog.csdn.net/u013845177/article/details/83001308