天天看点

spring cloud day02【 ribbon】

        ribbon是一种实现负载均衡的组件,我们知道常见的有nginx,实现负载均衡,nginx实现的主要是服务端的负载均衡,那么ribbon实现的是客户端的负载均衡

一、实现负载均衡

   1、 使用默认的负载均衡,由于eureka包含了负载均衡的依赖,所以不需要导入依赖

    只需要在实现客户端启动类配置如下注解

spring cloud day02【 ribbon】
spring cloud day02【 ribbon】

2、我们知道负载均衡实现有很多策略,那么默认实现的负载均衡策略是轮询,配置自定义的策略如下,首先我们需要在启动类上声名自定义注解如下

spring cloud day02【 ribbon】
spring cloud day02【 ribbon】

其中 CustomeRibbonConfig是我们自定义的注解 name表示作用于那一个项目。

下面的扫描注解,是因为我们配置的自定义策略会覆盖默认的轮询策略,我们需要对配置的自定义ribbon不扫描。

同时在这里我们可以通过 configuration参数看默认源码是如何实现这个策略的

spring cloud day02【 ribbon】
spring cloud day02【 ribbon】

源码是通过RibbonClientConfiguration  这个类的方法实现配置默认负载均衡策略

spring cloud day02【 ribbon】
spring cloud day02【 ribbon】

ribbon 提供了很多策略,可以进行选择,如下图

spring cloud day02【 ribbon】
spring cloud day02【 ribbon】

下面我负载均衡使用随机策略,代码实现如下

1
    
    
     2
    
    
     3
     
    
    
     4
    
    
     5
    
    
     6
    
    
     7
     
    
    
     8
    
    
     9
    
    
     10
    
    
     11
    
   
   
  
  
   
    
     
    
    
     
    
    
     
      
       @
       Configuration
      
     
     
      
       @
       ExcludeFromComponentScan
      
     
     
      
       public
       
       class
       
       CustomeRibbonConfig
       {
      
     
     
      
        @
       Autowired
      
     
     
       
       private
       
       IClientConfig
       
       config;
      
     
     
      
        @
       Bean
      
     
     
       
       public
       
       IRule
       
       ribbonRule(
       IClientConfig
       
       config)
       {
      
     
     
       
      
     
     
      
        
        
       
       return
       
       new
       
       RandomRule();
      
     
     
      
        }
      
     
     
      
       }
       
      
     
    
    
    
     
    
   
  
  
   
   
  
  
   
  
           

代码配置 @ExcludeFromComponentScan这个自定义注解是为了使componentScan不扫描我们的这个自定义策略。不覆盖原有策略。

二、通过配置实现自定义负载均衡

1、我们通过上面自定义类实现,其实我们可以省去上面复杂的代码,可以简化为如下配置

1
    
    
     2
    
    
     3
    
    
     4
    
   
   
  
  
   
    
     
    
    
     
    
    
     
      
       #针对某个服务进行自定义负载均衡策略
      
     
     
      
       zw-provider-user2:
      
     
     
      
       ribbon:
      
     
     
      
       NFLoadBalancerRuleClassName:com.netflix.loadbalancer.RandomRule
      
     
    
    
    
     
    
   
  
  
   
   
  
           

非常的so easy

2、上面的配置我们都是依赖eureka的,假如我们不依赖eureka,该如何实现ribbon呢

也是非常简单的,我们知道通过eureka通过vip实现映射,那么我们不依赖eureka,就应该做两件事,ribbon禁用eureka,配置服务端vip映射。

配置如下

1
    
    
     2
    
    
     3
    
    
     4
    
    
     5
    
    
     6
    
    
     7
    
    
     8
    
   
   
  
  
   
    
     
    
    
     
    
    
     
      
       #配置eureka不支持ribbon
      
     
     
      
       ribbon:
      
     
     
      
       eureka:
      
     
     
      
       enabled:false
      
     
     
      
       #服务端服务,以及服务端ip端口,因为不依赖eureka,所以必须指定ip
      
     
     
      
       zw-provider-user2:
      
     
     
      
       ribbon:
      
     
     
      
       listOfServers:localhost:7000
      
     
    
    
    
     
    
   
  
  
   
   
  
           

三、直接使用Ribbon API

    客户端使用代码如下,不解释了

1
    
    
     2
    
    
     3
    
    
     4
     
    
    
     5
    
    
     6
    
    
     7
    
    
     8
    
    
     9
    
   
   
  
  
   
    
     
    
    
     
    
    
     
      
       @
       Autowired
      
     
     
      
        
        
       
       private
       
       LoadBalancerClient
       
       loadBalancerClient;
      
     
     
      
        
        
        
        
       @
       GetMapping(
       "/test")
      
     
     
      
        
        
       
       public
       
       String
       
       test()
       {
      
     
     
      
        
        
        
        
       
       ServiceInstance
       
       serviceInstance
       
       =
       
       this.
       loadBalancerClient.
       choose(
       "zw-provider-user");
      
     
     
      
        
        
        
        
       
       System.
       out.
       println(
       "111"
       
       +
       
       ":"
       
       +
       
       serviceInstance.
       getServiceId()
       
       +
       
       ":"
       
       +
       
       serviceInstance.
       getHost()
       
       +
       
       "
      
      
               
       :"
       
       +
       
       serviceInstance.
       getPort());
      
     
     
      
     
     
      
        
        
        
        
       
       return
       
       "1";
      
     
     
      
        
        
       }
      
     
    
    
    
     
    
   
  
  
   
   
  
           

官方实例

1
     
    
    
     2
    
    
     3
    
    
     4
    
    
     5
     
    
    
     6
    
    
     7
    
    
     8
    
    
     9
    
    
     10
    
   
   
  
  
   
    
     
    
    
     
    
    
     
      
       public
       
       class
       
       MyClass
       {
      
     
     
      
       
       
       
       @
       Autowired
      
     
     
      
       
       
       
       
       private
       
       LoadBalancerClient
       
       loadBalancer;
      
     
     
      
     
     
      
       
       
       
       
       public
       
       void
       
       doStuff()
       {
      
     
     
      
       
       
       
       
       
       
       
       
       ServiceInstance
       
       instance
       
       =
       
       loadBalancer.
       choose(
       "stores");
      
     
     
      
       
       
       
       
       
       
       
       
       URI
       
       storesUri
       
       =
       
       URI.
       create(
       String.
       format(
       "http://%s:%s",
       
       instance.
       getHost(),
       
       instance.
       getPort()));
      
     
     
      
       
       
       
       
       
       
       
       
       //...dosomethingwiththeURI
      
     
     
      
       
       
       
       }
      
     
     
      
       }
      
     
    
    
    
     
    
   
  
  
   
   
  
           

其它问题

开发时遇到一个很奇葩的错误

服务端名称不能用_下划线

否则在执行如下代码时,由于不能返回值报空指针异常,本人用的是1.4.1.release版本

spring cloud day02【 ribbon】
spring cloud day02【 ribbon】

继续阅读