spring cloud 客户端负载均衡 - Ribbon

Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,基于Netflix Ribbon实现的,Ribbon不像注册中心、网关那样须要单独部署,它是做为一个工具直接集成到Service里。后面要讲到的Feign里面也集成了Ribbon。git

一、手动搭建一个客户端负载均衡

准备工做:github

  • 准备一个由 peer一、peer2 构成的配置中心
  • 准备一个由 service-1(8091)、service-1(8092) 构成的服务端集群
  • 准备一个Ribbon客户端

添加pom依赖web

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
View Code

Ribbon客户端,使用@EnableDiscoveryClient向Eureka注册:spring

@SpringBootApplication
@EnableDiscoveryClient
public class RibbonServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run( RibbonServiceApplication.class, args );
    }

    /**
     * 实例化RestTemplate,经过@LoadBalanced注解开启均衡负载
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
View Code

调用Service-1提供的服务:后端

@Service
public class UserService {

    @Autowired
    private RestTemplate restTemplate;

    public UserDto getUser(Long userId) {
        ResponseEntity<UserDto> responseEntity = restTemplate.getForEntity("http://service-1/getUser/{1}", UserDto.class, userId);
        return responseEntity.getBody();
    }
}
View Code

依次启动注册中心、Service-1两个实例和Ribbon,所有启动成功后,能够看到service-1启动了两个实例,以下图所示: 架构

访问 Ribbon 客户端接口:http://localhost:9000/user/getByUserId负载均衡

刷新页面,后端Service-1的两个实例分别输出日志:dom

service-1:8091ide

8091 provides servicespring-boot

service-1:8092

8092 provides service
8092 provides service

系统架构如图所示:

 二、Ribbon配置

自动化配置

上面搭建负载均衡过程当中没有任何Ribbon相关的配置,是由于Spring Cloud整合Eureka和Ribbon时作了不少默认配置。

在没有引入Spring Cloud Eureka时,Spring Cloud Ribbon 已经默认实现了这些配置bean:

  • IClientConfig :Ribbon客户端配置,默认采用 com.netflix.client.config.DefaultClientConfigImpl 

  • IRule :Ribbon的负载均衡策略,默认采用 com.netflix.loadbalancer.ZoneAvoidanceRule

  • IPing:Ribbon实例心跳检查策略,默认采用 com.netflix.loadbalancer.NoOpPing,经过看实现能够看出:不会检查实例是否可用,始终返回true

  • ServerList:服务实例清单维护列表,默认采用 com.netflix.loadbalancer.ConfigurationBasedServerList

  • ServerListFilter :服务实例清单过滤机制,默认采用 org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter

  • ILoadBalancer :负载均衡器,默认采用 com.netflix.loadbalancer.ZoneAwareLoadBalancer

自定义配置:代码+RibbonClient方式

@RibbonClient(value = "service-1", configuration = MyRibbonConfig.class)
public class RibbonServiceApplication {

自定义负载为随机时:

@Configuration
public class MyRibbonConfig {
    @Bean
    public IRule ribbonRule() {   new RandomRule();   }
}

当自定义负载换为轮询时:

@Configuration
public class MyRibbonConfig {
    @Bean
    public IRule ribbonRule() {   new RoundRobinRule();   }
}

分别在上面两种状况下刷新页面 http://localhost:9000/user/getByUserId (以刷新8次为例,观察service-1两个实例控制台打印的log):

  • 当为 RandomRule 时发现service-1在8091和8092两个实例随机提供服务。
  • 当为 RoundRobinRule 时发现service-1在8091和8092两个实例轮流提供服务。

自定义配置:代码+配置文件方式(Components of load balancer

在properties里配置,经过反射方式建立,配置方式以下:

以 `<clientName>.ribbon.` 为前缀,加上下面的属性名(属性名来自 org.springframework.cloud.netflix.ribbon.PropertiesFactory 类):

NFLoadBalancerClassName
NFLoadBalancerRuleClassName
NFLoadBalancerPingClassName
NIWSServerListClassName
NIWSServerListFilterClassName

配置ribbon负载方式(针对service-1服务设置):

service-1:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

将自定义类赋给对应的属性能够作到服务级别的自定义配置。

三、附录

  本文Demo地址:Ribbon Service

相关文章
相关标签/搜索