SpringCloud升级之路2020.0.x版-34.验证重试配置正确性
Posted 干货满满张哈希
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud升级之路2020.0.x版-34.验证重试配置正确性相关的知识,希望对你有一定的参考价值。
本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent
我们继续上一节针对我们的重试进行测试
验证针对可重试的方法响应超时异常重试正确
我们可以通过 httpbin.org 的 /delay/响应时间秒
来实现请求响应超时。例如 /delay/3
就会延迟三秒后返回。这个接口也是可以接受任何类型的 HTTP 请求方法。
我们先来指定关于 Feign 超时的配置 Options:
//SpringExtension也包含了 Mockito 相关的 Extension,所以 @Mock 等注解也生效了
@ExtendWith(SpringExtension.class)
@SpringBootTest(properties =
//关闭 eureka client
"eureka.client.enabled=false",
//默认请求重试次数为 3
"resilience4j.retry.configs.default.maxAttempts=3",
//指定默认响应超时为 2s
"feign.client.config.default.readTimeout=2000",
)
@Log4j2
public class OpenFeignClientTest
@SpringBootApplication
@Configuration
public static class App
@Bean
public DiscoveryClient discoveryClient()
//模拟两个服务实例
ServiceInstance service1Instance1 = Mockito.spy(ServiceInstance.class);
ServiceInstance service1Instance3 = Mockito.spy(ServiceInstance.class);
Map<String, String> zone1 = Map.ofEntries(
Map.entry("zone", "zone1")
);
when(service1Instance1.getMetadata()).thenReturn(zone1);
when(service1Instance1.getInstanceId()).thenReturn("service1Instance1");
when(service1Instance1.getHost()).thenReturn("httpbin.org");
when(service1Instance1.getPort()).thenReturn(80);
DiscoveryClient spy = Mockito.spy(DiscoveryClient.class);
//微服务 testService1 有一个实例即 service1Instance1
Mockito.when(spy.getInstances("testService1"))
.thenReturn(List.of(service1Instance1));
return spy;
我们分别定义会超时和不会超时的接口:
@FeignClient(name = "testService1", contextId = "testService1Client")
public interface TestService1Client
@GetMapping("/delay/1")
String testGetDelayOneSecond();
@GetMapping("/delay/3")
String testGetDelayThreeSeconds();
编写测试,还是通过获取调用负载均衡获取实例的次数确定请求调用了多少次。
@Test
public void testTimeOutAndRetry() throws InterruptedException
Span span = tracer.nextSpan();
try (Tracer.SpanInScope cleared = tracer.withSpanInScope(span))
//防止断路器影响
circuitBreakerRegistry.getAllCircuitBreakers().asJava().forEach(CircuitBreaker::reset);
long l = span.context().traceId();
RoundRobinWithRequestSeparatedPositionLoadBalancer loadBalancerClientFactoryInstance
= (RoundRobinWithRequestSeparatedPositionLoadBalancer) loadBalancerClientFactory.getInstance("testService1");
AtomicInteger atomicInteger = loadBalancerClientFactoryInstance.getPositionCache().get(l);
int start = atomicInteger.get();
//不超时,则不会有重试,也不会有异常导致 fallback
String s = testService1Client.testGetDelayOneSecond();
//没有重试,只会请求一次
Assertions.assertEquals(1, atomicInteger.get() - start);
//防止断路器影响
circuitBreakerRegistry.getAllCircuitBreakers().asJava().forEach(CircuitBreaker::reset);
start = atomicInteger.get();
//超时,并且方法可以重试,所以会请求 3 次
try
s = testService1Client.testGetDelayThreeSeconds();
catch(Exception e)
Assertions.assertEquals(3, atomicInteger.get() - start);
验证针对不可重试的方法响应超时异常不能重试
对于 GET 方法,我们默认是可以重试的。但是一般扣款这种涉及修改请求的接口,我们会使用其他方法例如 POST。这一类方法一般请求超时我们不会直接重试的。我们还是通过 httporg.bin 的延迟接口进行测试:
@FeignClient(name = "testService1", contextId = "testService1Client")
public interface TestService1Client
@PostMapping("/delay/3")
String testPostDelayThreeSeconds();
编写测试,还是通过获取调用负载均衡获取实例的次数确定请求调用了多少次。
@Test
public void testTimeOutAndRetry() throws InterruptedException
Span span = tracer.nextSpan();
try (Tracer.SpanInScope cleared = tracer.withSpanInScope(span))
//防止断路器影响
circuitBreakerRegistry.getAllCircuitBreakers().asJava().forEach(CircuitBreaker::reset);
long l = span.context().traceId();
RoundRobinWithRequestSeparatedPositionLoadBalancer loadBalancerClientFactoryInstance
= (RoundRobinWithRequestSeparatedPositionLoadBalancer) loadBalancerClientFactory.getInstance("testService1");
AtomicInteger atomicInteger = loadBalancerClientFactoryInstance.getPositionCache().get(l);
int start = atomicInteger.get();
//不超时,则不会有重试,也不会有异常导致 fallback
String s = testService1Client.testPostDelayThreeSeconds();
//没有重试,只会请求一次
Assertions.assertEquals(1, atomicInteger.get() - start);
微信搜索“我的编程喵”关注公众号,每日一刷,轻松提升技术,斩获各种offer:
以上是关于SpringCloud升级之路2020.0.x版-34.验证重试配置正确性的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud升级之路2020.0.x版-7.从Bean到SpringCloud
SpringCloud升级之路2020.0.x版-44.避免链路信息丢失做的设计
SpringCloud升级之路2020.0.x版-41. SpringCloudGateway 基本流程讲解
SpringCloud升级之路2020.0.x版-22.Spring Cloud LoadBalan