返回
Hoxton-WebFlux-突破重试后依旧访问相同实例的解决方案
见解分享
2023-09-10 06:30:15
在《Spring Cloud升级之路 - Hoxton - 7. 后续更新(WebFlux等)》的最后,笔者讲述了Ribbon如何避免重试相同的实例,通过traceId隔离负载均衡的position,但没有考虑在负载均衡过程中,实例列表的更新。
WebFlux 出现背景
在Spring Cloud早期版本,Ribbon被普遍认为是实现负载均衡的最佳实践,但随着Spring Cloud的发展,Ribbon暴露了一些不足。
- Ribbon只支持HTTP/HTTPS协议的负载均衡,并且不支持服务间的调用,在处理WebFlux时,存在一定的问题。
- 在WebFlux中,通常需要多次重试才能成功。而在Ribbon中,如果使用了自定义负载均衡器,这些重试请求可能会被路由到相同的实例上。
WebFlux工作原理
WebFlux是Spring Cloud Hoxton中引入的新特性,它解决了Ribbon在处理WebFlux请求时存在的问题。WebFlux的工作原理如下:
- WebFlux使用随机算法选择第一个实例,并将请求路由到该实例。
- 如果请求失败,WebFlux会根据用户配置的重试策略,随机选择一个不同的实例,并将请求路由到该实例。
- WebFlux会一直重试,直到请求成功或者达到用户配置的最大重试次数。
WebFlux与Ribbon对比
WebFlux与Ribbon相比,具有以下优点:
- 支持更广泛的协议,除了HTTP/HTTPS之外,还支持TCP、UDP等协议。
- 支持服务间的调用。
- 具有更好的容错性。
WebFlux使用示例
我们通过一个简单的示例来说明如何使用WebFlux。
在pom.xml文件中,添加以下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-webflux</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
在application.properties文件中,添加以下配置:
spring.cloud.loadbalancer.ribbon.enabled=false
spring.cloud.loadbalancer.webflux.enabled=true
在代码中,使用@LoadBalanced
注解来标识需要负载均衡的Bean:
@LoadBalanced
@Bean
public WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
然后,就可以使用WebClient来发送请求了:
WebClient webClient = webClientBuilder().build();
Mono<String> response = webClient.get()
.uri("http://my-service/hello")
.retrieve()
.bodyToMono(String.class);
WebFlux局限性
WebFlux也存在一些局限性:
- 不支持所有Ribbon的功能,例如ZoneAvoidanceRule。
- 在某些情况下,WebFlux的性能可能不如Ribbon。
WebFlux注意事项
在使用WebFlux时,需要注意以下几点:
- 确保WebFlux与Ribbon的版本兼容。
- 在使用WebFlux时,需要配置重试策略。
- 在某些情况下,WebFlux的性能可能不如Ribbon,因此需要进行性能测试。
结语
WebFlux是Spring Cloud Hoxton中引入的新特性,它解决了Ribbon在处理WebFlux请求时存在的问题。WebFlux具有更好的容错性和支持更广泛的协议等优点,但是在使用WebFlux时,也需要注意它的局限性和注意事项。