本系列代码地址: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.验证重试配置正确性(3)的更多相关文章

  1. SpringCloud升级之路2020.0.x版-34.验证重试配置正确性(1)

    本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 在前面一节,我们利用 resilience4j 粘合了 OpenFeign 实现了断路器. ...

  2. SpringCloud升级之路2020.0.x版-34.验证重试配置正确性(2)

    本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 我们继续上一节针对我们的重试进行测试 验证针对限流器异常的重试正确 通过系列前面的源码分析 ...

  3. SpringCloud升级之路2020.0.x版-35. 验证线程隔离正确性

    本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 上一节我们通过单元测试验证了重试的正确性,这一节我们来验证我们线程隔离的正确性,主要包括: ...

  4. SpringCloud升级之路2020.0.x版-33. 实现重试、断路器以及线程隔离源码

    本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 在前面两节,我们梳理了实现 Feign 断路器以及线程隔离的思路,并说明了如何优化目前的负 ...

  5. SpringCloud升级之路2020.0.x版-36. 验证断路器正确性

    本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 上一节我们通过单元测试验证了线程隔离的正确性,这一节我们来验证我们断路器的正确性,主要包括 ...

  6. SpringCloud升级之路2020.0.x版-13.UnderTow 核心配置

    本系列代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford Undertow ...

  7. SpringCloud升级之路2020.0.x版-14.UnderTow AccessLog 配置介绍

    本系列代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford server: u ...

  8. SpringCloud升级之路2020.0.x版-1.背景

    本系列为之前系列的整理重启版,随着项目的发展以及项目中的使用,之前系列里面很多东西发生了变化,并且还有一些东西之前系列并没有提到,所以重启这个系列重新整理下,欢迎各位留言交流,谢谢!~ Spring ...

  9. SpringCloud升级之路2020.0.x版-41. SpringCloudGateway 基本流程讲解(1)

    本系列代码地址:https://github.com/JoJoTec/spring-cloud-parent 接下来,将进入我们升级之路的又一大模块,即网关模块.网关模块我们废弃了已经进入维护状态的 ...

随机推荐

  1. Cookbook:pandas的学习之路——10 Minutes to pandas

    按照pandas官网上10 Minutes to pandas的快速练习: 一 .对象创建: 导入练习所需要的工具包: 通过列表中的值创建序列Series,pandas在创建序列的同时会默认为列表中值 ...

  2. Hutool时间和日期相关工具

    日期时间工具 获取当前时间(1) public class HDateAndTime { public static void main(String[] args) { //获取当前时间 Date ...

  3. [USACO10NOV]Buying Feed G

    part 1 暴力 不难发现有一个 $\mathcal O(K^2n)$ 的基础 dp: $$f_{i,j+l}=\min(f_{i,j+l},f_{i-1,j}+(x_i-x_{i-1})jj+c_ ...

  4. After Effects 图层属性及属性组结构详解

    根据结构类型的属性分类 在 After Effects 的脚本开发中,图层的属性可被区分为三种类型:PROPERTY.INDEXED_GROUP 和 NAMED_GROUP .通过使用app.proj ...

  5. 每日总结:Java课堂测试第三阶段第一次优化 (2021.9.20)

    package jisuan2; import java.util.*;public class xiaoxue { public static void main(String[] args) { ...

  6. CF1082G Petya and Graph(最小割,最大权闭合子图)

    QWQ嘤嘤嘤 感觉是最水的一道\(G\)题了 顺便记录一下第一次在考场上做出来G qwqqq 题目大意就是说: 给你n个点,m条边,让你选出来一些边,最大化边权减点权 \(n\le 1000\) QW ...

  7. k8s学习笔记(3)- kubectl高可用部署,扩容,升级,回滚springboot应用

    前言:上一篇通过rancher管理k8s,部署服务应用扩容,高可用,本篇介绍kubectl命令行部署高可用集群节点,测试升级.扩容等 1.测试环境:3节点k3s,使用其中2节点(ubuntunode1 ...

  8. 【java】【作业】定义课程信息;继承和组合练习

    问题: 定义课程信息类,包含课程编号.课程名称及学生成绩.编程实现对软件工程专业的某班级的所有课程成绩统计,包括平均成绩.最高成绩.最低成绩,并打印成绩等级分布律. 分析 初分析: 父类(课程信息类) ...

  9. Sequence Model-week1编程题3-用LSTM网络生成爵士乐

    Improvise a Jazz Solo with an LSTM Network 实现使用LSTM生成音乐的模型,你可以在结束时听你自己的音乐,接下来你将会学习到: 使用LSTM生成音乐 使用深度 ...

  10. [no code] Scrum Meeting 博客目录

    项目 内容 2020春季计算机学院软件工程(罗杰 任健) 2020春季计算机学院软件工程(罗杰 任健) 作业要求 Scrum Meeting博客目录 我们在这个课程的目标是 远程协同工作,采用最新技术 ...