`
234390216
  • 浏览: 10233057 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:462625
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1775522
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1398366
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:395023
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:679990
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:530894
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1183954
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:467934
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:151399
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:68154
社区版块
存档分类
最新评论

Spring Cloud(08)——客户端负载工具Ribbon

阅读更多

客户端负载工具Ribbon

Ribbon是Netflix公司提供的一个客户端负载工具,Spring Cloud也对其进行了集成支持。使用Ribbon需要在pom.xml中添加如下依赖。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

为了使用LoadBalancerClient,还需要在Classpath下存在RestTemplate,为此引入如下依赖。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
</dependency>

然后在@Configuration类上使用@org.springframework.cloud.netflix.ribbon.RibbonClient声明一个Ribbon Client,指定Client的名称。如下代码声明了一个名称为hello的Ribbon Client。

@SpringBootApplication
@RibbonClient("hello")
public class Application {

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

然后可以通过下面的方式指定服务端的地址,其中hello是上面声明的Ribbon Client的名称。

hello.ribbon.listOfServers=http://localhost:8900,http://localhost:8901

然后可以在应用中注入org.springframework.cloud.client.loadbalancer.LoadBalancerClient,并通过它来获取服务端地址了。

@SpringBootTest(classes=Application.class)
@RunWith(SpringRunner.class)
public class RibbonTest {

    @Autowired
    private LoadBalancerClient loadBalancerClient;
    
    @Test
    public void test() {
        String serviceId = "hello";
        for (int i=0; i<5; i++) {
            ServiceInstance instance = this.loadBalancerClient.choose(serviceId);
            System.out.println(i + ". " + instance.getUri());
        }
    }
    
}

上面的代码就通过LoadBalancerClient连续获取了5次服务端地址,运行代码你会看到如下这样的输出。

0. http://localhost:8900
1. http://localhost:8901
2. http://localhost:8900
3. http://localhost:8901
4. http://localhost:8900

Spring Cloud会注册Ribbon Client需要的IRule、IPing和ILoadBalancer等bean,它们由org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration负责注册。我们可以通过注册自己的相关类型的bean来覆盖默认的bean定义,比如下面的代码就指定了使用的IRule是基于轮询的RoundRobinRule实现。

@Configuration
public class RibbonConfiguration {

    @Bean
    public IRule rule() {
        return new RoundRobinRule();
    }
    
}

也可以通过@RibbonClients的defaultConfiguration指定通用的配置信息。

@SpringBootApplication
@RibbonClient(value="hello")
@RibbonClients(defaultConfiguration=RibbonConfiguration.class)
public class Application {

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

也可以专门为某个Ribbon Client定义特殊配置信息,此时可以通过@RibbonClient的configuration属性指定需要应用的@Configuration配置类。

@SpringBootApplication
@RibbonClient(value="hello", configuration=RibbonConfiguration.class)
public class Application {

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

Ribbon Client的配置参数也可以通过application.properties进行配置,属性名格式是clientName.ribbon.property。比如下面的配置指定了名称为hello的Ribbon Client的服务地址和使用的IRule。更多的配置参数可以参考com.netflix.client.config.CommonClientConfigKey的API文档,这些参数的默认值可以参考com.netflix.client.config.DefaultClientConfigImpl

hello.ribbon.listOfServers=http://localhost:8900,http://localhost:8901
hello.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule

使用配置文件指定的参数比使用@RibbonClient(value="hello", configuration=RibbonConfiguration.class)指定的配置拥有更高的优先级。

 

Ribbon和Eureka一起使用

当应用中存在Eureka Client时,可以不通过hello.ribbon.listOfServers=http://localhost:8900,http://localhost:8901写死hello客户端对应的服务地址。此时可以通过Eureka Client从Eureka Server获取服务地址,从而达到动态获取服务地址的目的。此时如果声明了名为hello的Ribbon Client,则会从Eureka Server获取serviceId为hello的服务对应的地址。

eureka.client.registerWithEureka=false
eureka.client.serviceUrl.defaultZone=http://localhost:8089/eureka/

如果应用中存在Eureka Client,但不希望通过Eureka Client来获取Ribbon Client对应的服务地址,可以指定ribbon.eureka.enabled=false

hello.ribbon.listOfServers=http://localhost:8900,http://localhost:8901
ribbon.eureka.enabled=false
eureka.client.registerWithEureka=false
eureka.client.serviceUrl.defaultZone=http://localhost:8089/eureka/

 

RestTemplate负载

RestTemplate可以和Ribbon一起使用,使其具备负载能力。在对应的RestTemplate对应的bean上加上@LoadBalanced可以使其拥有负载能力。

@Configuration
public class RibbonConfiguration {

    @Bean
    public IRule rule() {
        return new RoundRobinRule();
    }
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }
    
}

在使用的时候需要把host改为对应的serviceId,比如有一个服务hello,我们想访问它提供的/api/abc服务,即可以访问http://hello/api/abc。内部在访问的时候会自动把hello替换为服务hello的一个具体地址(它可能是通过ribbon.listOfServers指定的,也可能是直接从Eureka获取的)。

@Autowired
private RestTemplate restTemplate;

@GetMapping("hello")
public String hello() {
    String result = this.restTemplate.getForObject("http://hello/api/hello/abc", String.class);
    return result;
}

如果你的应用中需要同时有多个RestTemplate,有的需要有负载均衡功能,有的不需要有,则可以在应用中创建多个RestTemplate类型的bean,然后根据需要用@Primary指定一个为自动注入时默认使用的。比如下面我们定义了默认注入的是拥有负载均衡功能的RestTemplate。

@Bean
@LoadBalanced
@Primary
public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder.build();
}

@Bean
public RestTemplate commonRestTemplate(RestTemplateBuilder builder) {
    return builder.build();
}

 

WebClient负载

 

方式一

WebClient也是可以负载的,与RestTemplate类似,它需要定义一个WebClient.Builder类型的bean,并使用@LoadBalanced标注。

@Bean
@LoadBalanced
public WebClient.Builder webClientBuilder() {
    return WebClient.builder();
}

然后使用的时候就注入WebClient.Builder,通过它创建一个WebClient对象。WebClient进行访问时URI中的host也是需要使用服务名。

@Autowired
private WebClient.Builder webClientBuilder;

@GetMapping("webClient/hello")
public Mono<String> hello() {
  return this.webClientBuilder.build().get().uri("http://hello/api/hello/abc").retrieve().bodyToMono(String.class);
}

 

方式二

方式二是注入一个LoadBalancerExchangeFilterFunction类型的bean,该bean将由Spring Cloud自动创建。然后在通过WebClient.Builder创建WebClient时指定该ExchangeFilterFunction,这样创建出来的WebClient也是具有负载功能的。

@Autowired
private LoadBalancerExchangeFilterFunction lbFunction;

@GetMapping("webClient/lbFunction")
public Mono<String> lbFunction() {
    return WebClient.builder().baseUrl("http://hello")
        .filter(lbFunction)
        .build()
        .get()
        .uri("/api/hello/abc")
        .retrieve()
        .bodyToMono(String.class);
}

 

自动重试

Ribbon和Spring Retry一起使用的时候可以在调用远程服务失败时发起重试。需要先加入spring retry依赖。

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>

然后可以通过MaxAutoRetries指定最多重试次数,比如ribbon.MaxAutoRetries=2指定所有的Ribbon客户端在发起请求时最多重试两次,第一次调用不算在重试次数中。可以通过MaxAutoRetriesNextServer配置最多重试的服务器数量,第一个服务器是不算的。比如MaxAutoRetries=2,MaxAutoRetriesNextServer=1,那么会在第一台服务器上最多调用3次,在第二台服务器上也最多调用3次,如果还有第三台服务器,则第三台服务器不会再调用了。Ribbon默认只对GET请求进行重试,如果需要对POST请求也进行重试,则可以配置ribbon.OkToRetryOnAllOperations=true。还可以通过retryableStatusCodes来指定需要进行重试的Http状态码,比如只希望在状态码为500或502时进行重试,则配置ribbon.retryableStatusCodes=500,502。默认情况只要服务器通讯正常都不会重试,即状态码不管是404还是502等都不会发起重试,只有建立连接失败或者请求超时会重试。所以如果我们需要在状态码为502的时候也能发起重试则需要指定retryableStatusCodes。

ribbon.MaxAutoRetries=2
ribbon.MaxAutoRetriesNextServer=2
ribbon.OkToRetryOnAllOperations=true
ribbon.retryableStatusCodes=404,502

示例代码如下。

@GetMapping("retry/{sub}")
public String retryAny(@PathVariable("sub") String sub) {
    String result = this.restTemplate.getForObject("http://hello/{sub}", String.class, sub);
    return result;
}

如果Classpath下存在Spring Retry的相关jar包,但是又不希望使用它,则可以指定spring.cloud.loadbalancer.retry.enabled=false

 

参考文档

(注:本文是基于Spring cloud Finchley.SR1所写)

分享到:
评论

相关推荐

    SpringCloud——客户端负载平衡器(Ribbon)

    Ribbon是一个客户端负载均衡器,它可以很好地控制HTTP和TCP客户端的行为。

    方志朋版——深入理解Spring Cloud与微服务构建.pdf

    再者,Spring Cloud Netflix Ribbon和Spring Cloud OpenFeign是客户端负载均衡器,它们负责在调用远程服务时进行负载均衡,提高系统的可用性。Ribbon是基于HTTP和TCP的客户端负载均衡器,而OpenFeign则提供了一种...

    SpringCloud——声明性REST客户端(Feign)

    【SpringCloud——声明性REST客户端(Feign)】 在分布式微服务架构中,服务之间的通信是至关重要的。Spring Cloud提供了一种优雅的方式,通过Feign客户端来实现这一目标。Feign是一个声明式的Web服务客户端,它...

    SpringCloud——断路器(Hystrix)

    Ribbon 是 Netflix 提供的一个客户端负载均衡器,它可以在 Spring Cloud 中与 Hystrix 集成,为每个服务实例添加断路器保护。在 Ribbon 中配置 Hystrix,你需要创建一个 HystrixCommand 或者 ...

    SpringCloud集成Python服务

    首先,让我们了解SpringCloud的核心组件之一——Eureka。Eureka是SpringCloud的服务注册与发现组件,它允许各个微服务实例向中心注册,并且提供服务发现功能。在集成Python服务时,我们需要在Python端实现一个Eureka...

    Springcloud Zuul config eureka ribbon实例

    在本实例中,我们主要探讨的是Spring Cloud框架中的几个关键组件——Zuul、Config、Eureka和Ribbon,这些都是微服务架构中的重要工具。让我们逐一解析这些组件及其作用。 首先,Spring Cloud Config是一个集中式的...

    spring cloud 实战教程

    Spring Cloud作为Java领域的热门框架,为构建分布式系统提供了丰富的工具集,包括服务发现、负载均衡、断路器、配置管理等关键功能。本书将引领读者逐步探索这一技术栈的精髓。 首先,书中会介绍微服务架构的基本...

    SpringCloud——路由器和过滤器(Zuul)

    5. **负载均衡**:Zuul可以集成Ribbon进行客户端负载均衡,自动分发请求到不同的服务实例。 **Zuul的过滤器** 1. **Pre过滤器**:在路由之前执行,用于身份验证、日志记录等操作。 2. **Route过滤器**:处理路由...

    《深入理解Spring Cloud与微服务构建》学习笔记(十七)~路由网关Spring Cloud Zuul~负载均衡

    在Spring Cloud中,Ribbon是默认的客户端负载均衡器,它与Eureka(服务注册与发现组件)结合使用,可以从Eureka服务注册中心获取服务列表,并根据预定义的策略进行负载分配。 当客户端向Zuul发送请求时,Zuul会利用...

    spring-cloud-example-ribbon

    其中,Ribbon是Spring Cloud的一个客户端负载均衡器,它允许我们从一组服务器列表中智能地选择一个服务器进行请求,从而实现服务间的调用。本文将深入探讨Spring Cloud Ribbon的核心概念、配置以及实际应用。 一、...

    SpringCloud —— Ribbon 负载均衡算法

    在SpringCloud体系中,Ribbon 是一个客户端负载均衡器,它与Eureka、Consul等服务注册中心配合使用,帮助客户端在请求服务时实现服务间的负载均衡。Ribbon 提供了多种负载均衡策略,其中最常见的是轮询算法...

    SpringCloud案例(集成了Eureka、Ribbon、Feign)

    **SpringCloud案例(集成了Eureka、Ribbon、Feign)** 在分布式系统中,Spring Cloud作为一套微服务解决方案,提供了丰富的组件来帮助开发者构建可扩展的云原生应用。本案例聚焦于Spring Cloud的核心组件——Eureka、...

    SpringCloud源码-01.zip

    本篇将围绕SpringCloud的核心组件进行源码分析,包括Eureka服务注册与发现、Ribbon客户端负载均衡、Hystrix断路器、Zuul路由网关以及Config分布式配置中心,旨在帮助读者深入理解这些组件的工作原理。 一、Eureka:...

    SpringCloud笔记-images

    描述中的"SpringCloud笔记——images"进一步确认了这是一个以图片为主的Spring Cloud教程,可能包含了一些截图、流程图或架构图,以直观地展示Spring Cloud如何在实际项目中运作。 在"Springcloud笔记.assets"和...

    客户端负载均衡器Ribbon(实验代码)

    客户端负载均衡器Ribbon是Netflix开发的一个开源组件,主要用于实现微服务架构中的客户端负载均衡功能。在本实验代码中,我们将深入理解Ribbon的工作原理及其在实际应用中的配置与使用。 Ribbon是一个轻量级的库,...

    springcloud原版pdf学习

    Spring Cloud通过Ribbon和Feign实现了客户端负载均衡,这些组件能够根据Restful API自动进行服务调用。 Hystrix是Spring Cloud中的断路器组件,它用于防止服务雪崩,通过隔离服务调用、降级处理和熔断机制,提高了...

    java面试——SpringCloud面试专题.zip

    9. **Spring Cloud LoadBalancer负载均衡**:在Spring Cloud中,LoadBalancer用于客户端负载均衡,它提供了与Ribbon和Feign集成的解决方案,可以在服务调用时实现负载均衡。 10. **Spring Cloud OpenFeign声明式...

    SpringCloud与五大组件的整合.zip

    2. **Ribbon**:Ribbon是Netflix提供的一个客户端负载均衡器,它嵌入在服务消费者中。当服务消费者发起请求时,Ribbon会根据预设的策略(如轮询、随机等)选择一个服务实例进行调用。通过Ribbon,可以实现客户端的...

    Springcloud学习源码记录

    参考记录: ... 所有的SpringCloud能够实现三大模块: 服务发现——Netflix ...客户端负载均衡——Netflix Ribbon 断路器——Netflix Hystrix 服务网关——Netflix Zuul 分布式配置——Spring Cloud Config

    Spring Cloud eureka服务注册DEMO

    Spring Cloud提供了Ribbon和Feign这两个客户端负载均衡器,它们与Eureka结合使用,可以自动选择服务实例进行请求。Ribbon是低级库,适用于自定义客户端,而Feign是基于Ribbon的声明式HTTP客户端,使得服务调用更加...

Global site tag (gtag.js) - Google Analytics