在某些时候,我们希望某个同步调用执行更长的时间(异步暂时不考虑),这个时候,首先就是要设置OpenFeign的timeout设定。

下面我们举例来说明,可以如何设定TimeOut参数。

一、环境

脱离环境说明问题就是流氓。

cloud的版本为 2021.0.0

spring-boot-starter-parent 本本是2.6.2

通过官网和下载的jar包可以看到,OpenFeign有关的版本是3.1.0。

于是我们取看下官网的文档。

二、概述

1.通过官网的timeout章节,我们可以看到设置timeout至少有两种方式:通过属性文件(properties/yml)和配置

2.这个版本的openFeign设计至少是比较合理的

三、代码

分为四个部分:

1.目标服务CustomerService的list接口

    @RequestMapping(value = "/list")
@ResponseBody
public Object list() throws InterruptedException { // TODO:
Thread.sleep(25000);
Map<String,Object> customer=new HashMap<String,Object>();
customer.put("name","lzf");
customer.put("sex","男");
customer.put("age","99");
customer.put("address","中华");
return customer;
}
以上代码故意演示25秒。

2.测试服务ConfigServiceTest的属性文件

feign:
client:
config:
default:
connectTimeout: 30000
readTimeout: 30000

connectTimeout--连接超时

readTimeout--读取超时

二者的区别在于:readTimeout只有成功连接后才会触发。所以如果连接总是没有问题,但是执行太久,那么就必须设定readTimeout。

并非二者必须配对使用。

--

注意:default关键字标识对所有client生效,如果是想针对某个服务,可以直接写服务名称,例如这里可以写 CustomerService.

3.测试服务ConfigServiceTest的java配置

配置类

public class CustomerServiceFeignInter {

    @Bean
public Integer connectTimeOut() {
return 30000;
} @Bean
public Integer readTimeOut() {
return 30000;
} @Bean
public ErrorDecoder feignErrorDecoder() {
return new ErrorHandler();
} @Bean
public RequestInterceptor currentUserRequestInterceptor() {
return (RequestTemplate template) -> {
//Map<String, Collection<String>> header=template.request().headers();
//System.out.println(JSON.toJSONString(header, true));
String token = LoginCache.get();
System.out.println(token);
template.header("Authorization", token);
};
} }

注:根据关方文档,config还有另外一种下发,如下:

@Import(FeignClientsConfiguration.class)
class FooController { private FooClient fooClient; private FooClient adminClient; @Autowired
public FooController(Client client, Encoder encoder, Decoder decoder, Contract contract, MicrometerCapability micrometerCapability) {
this.fooClient = Feign.builder().client(client)
.encoder(encoder)
.decoder(decoder)
.contract(contract)
.addCapability(micrometerCapability)
.requestInterceptor(new BasicAuthRequestInterceptor("user", "user"))
.target(FooClient.class, "https://PROD-SVC"); this.adminClient = Feign.builder().client(client)
.encoder(encoder)
.decoder(decoder)
.contract(contract)
.addCapability(micrometerCapability)
.requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin"))
.target(FooClient.class, "https://PROD-SVC");
}
}

服务接口bean

@FeignClient(value = "CustomerService",configuration= CustomerServiceFeignInter.class)
@Component
public interface CustomerServiceOpenFeignInterface {
@RequestMapping(value = "/customer/list")
public Object list();
}

注:根据spring官网的说明,如果有属性和java配置的时候,属性处于优先低位,java配置对应部分被无视。

4.测试服务ConfigServiceTest的测试代码

    @RequestMapping(value = "/timeout")
@ResponseBody
public PublicReturn timeout() { // TODO:
try{
Object result=customerService.list();
Map<String,Object> resultMap=new HashMap<>();
resultMap.put("customer",result);
PublicReturn re= PublicReturn.getSuccessful("ok",resultMap);
return re;
}
catch (Exception e){
return PublicReturn.getUnSuccessful(e.getMessage());
}
}

四、测试和结论

1.如果只是设置属性,那么可以生效,在超过25秒之后,可以看到返回结果。

{
"flag": 1,
"message": "ok",
"data": {
"customer": {
"address": "中华",
"sex": "男",
"name": "lzf",
"age": "99"
}
}
}

2.如果只是设置java配置(即上文的CustomerServiceFeignInter),那么结果同1

3.如果二者都有设置,且属性的timeOut是5秒,而配置还是30秒,那么结果是属性胜出,客户端5秒之后报告异常

feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 5000
compression:
request:
enabled: true
min-request-size: 2048
response:
enabled: true
    @RequestMapping(value = "/timeout")
@ResponseBody
public PublicReturn timeout() { // TODO:
long start=System.currentTimeMillis();
try{
Object result=customerService.list();
Map<String,Object> resultMap=new HashMap<>();
resultMap.put("customer",result);
PublicReturn re= PublicReturn.getSuccessful("ok",resultMap);
return re;
}
catch (Exception e){
long end=System.currentTimeMillis();
return PublicReturn.getUnSuccessful("连接异常"+e.getMessage()+",当前耗费时间"+(end-start));
}
}

结果:

{
"flag": 0,
"message": "连接异常Read timed out executing GET http://CustomerService/customer/list,当前耗费时间5178",
"data": {}
}

属性配置胜出!

五、相干问题-压缩

如果觉得是因为没有压缩导致的timeout或者性能等考虑,那么可以启动压缩,尽量避免超时。

具体设置见前文。

六、相关问题-异步

如果实在不想等太久,那么可以考虑采用异步的方式调用。

关于异步的调用,可以参考https://www.jb51.net/article/212227.htm#_label2

    @Bean
public CustomerServiceOpenFeignInterface originFeignClient(SpringEncoder springEncoder, SpringDecoder springDecoder) {
return AsyncFeign.asyncBuilder()
.encoder(springEncoder)
.decoder(springDecoder)
.target(CustomerServiceOpenFeignInterface.class, "http://localhost.charlesproxy.com:8090");
}

测试代码

@GetMapping("testApi")
public String testAsyncClient() throws ExecutionException, InterruptedException {
List<CompletableFuture<String>> results = new ArrayList<>();
for(int i = 0; i < 10; i++) {
results.add(originFeignClient.api(i+""));
}
Thread.sleep(3000);
int index = 0;
for (CompletableFuture<String> result : results) {
String str = result.get();
log.info(String.format("%d, result:%s, ", index, str));
index++;
}
return "success";
}

或者官网的文档

七、结论

openFeign越来越完善的情况下,我们倾向于直接使用它的功能。

不过openFeign的一些写法,我也不是很苟同--例如在破坏原有编码习惯的情况下,编写代码,例如下面的:

public interface UserService {

    @RequestMapping(method = RequestMethod.GET, value ="/users/{id}")
User getUser(@PathVariable("id") long id);
} @RestController
public class UserResource implements UserService { } package project.user; @FeignClient("users")
public interface UserClient extends UserService { }

看起来比较怪异,我个人不是很习惯和接受,已经强烈要求大伙不那么写。

SpringCloud开发之OpenFeign timeout和压缩等问题的更多相关文章

  1. Android安全开发之ZIP文件目录遍历

    1.ZIP文件目录遍历简介 因为ZIP压缩包文件中允许存在“../”的字符串,攻击者可以利用多个“../”在解压时改变ZIP包中某个文件的存放位置,覆盖掉应用原有的文件.如果被覆盖掉的文件是动态链接s ...

  2. Asp.net Mvc模块化开发之“部分版本部分模块更新(上线)”

    项目开发从来就不是一个简单的问题.更难的问题是维护其他人开发的项目,并且要修改bug.如果原系统有重大问题还需要重构. 怎么重构系统不是本文探讨的问题,但是重构后如何上线部署和本文关系密切.这个大家可 ...

  3. ArcGIS Engine开发之旅05---空间数据库

    原文:ArcGIS Engine开发之旅05---空间数据库 1  Geodatabase概念 Geodatabase是ArcInfo8引入的一种全新的面向对象的空间数据模型,是建立在DBMS之上的统 ...

  4. Android开发之Java必备基础

    Android开发之Java必备基础 Java类型系统 Java语言基础数据类型有两种:对象和基本类型(Primitives).Java通过强制使用静态类型来确保类型安全,要求每个变量在使用之前必须先 ...

  5. iOS多线程开发之GCD(中篇)

    前文回顾: 上篇博客讲到GCD的实现是由队列和任务两部分组成,其中获取队列的方式有两种,第一种是通过GCD的API的dispatch_queue_create函数生成Dispatch Queue:第二 ...

  6. Android 安全开发之 ZIP 文件目录遍历

    1.ZIP文件目录遍历简介 因为ZIP压缩包文件中允许存在"../"的字符串,攻击者可以利用多个"../"在解压时改变ZIP包中某个文件的存放位置,覆盖掉应用原 ...

  7. Android开发之旅3:android架构

    引言 通过前面两篇: Android 开发之旅:环境搭建及HelloWorld Android 开发之旅:HelloWorld项目的目录结构 我们对android有了个大致的了解,知道如何搭建andr ...

  8. 高效开发之SASS篇 灵异留白事件——图片下方无故留白 你会用::before、::after吗 link 与 @import之对比 学习前端前必知的——HTTP协议详解 深入了解——CSS3新增属性 菜鸟进阶——grunt $(#form :input)与$(#form input)的区别

    高效开发之SASS篇   作为通往前端大神之路的普通的一只学鸟,最近接触了一样稍微高逼格一点的神器,特与大家分享~ 他是谁? 作为前端开发人员,你肯定对css很熟悉,但是你知道css可以自定义吗?大家 ...

  9. .NET Core 跨平台 GUI 开发之 GTtkSharp 初级篇

    .NET Core 跨平台 GUI 开发之 GTtkSharp 初级篇 本文作为初级篇,适合已经安装好.NET Core 环境以及 Gtk 环境,并具备了 C#开发基础知识,能跑一些简单的例子,希望更 ...

  10. iOS多线程开发之GCD(中级篇)

    前文回顾: 上篇博客讲到GCD的实现是由队列和任务两部分组成,其中获取队列的方式有两种,第一种是通过GCD的API的dispatch_queue_create函数生成Dispatch Queue:第二 ...

随机推荐

  1. 2018-8-10-WPF-如何画出1像素的线

    title author date CreateTime categories WPF 如何画出1像素的线 lindexi 2018-08-10 19:16:53 +0800 2018-2-13 17 ...

  2. 老外为了在MacBook上玩原神,让M1支持了所有iOS应用 | Github每周精彩分享第一期

    大家好,这里是每周更新的Github有趣项目分享,我是每周都在吃瓜的蛮三刀酱. 我会从Github热门榜里选出 高质量.有趣,牛B 的开源项目进行分享. 废话不多说,看看最近有什么有意思的Github ...

  3. R1_ES知识图谱

    业务量增加,优化..优化... 学习... 学习..... 阮一鸣,eBay Pronto 平台技术负责人,管理了 eBay 内部上百个 Elasticsearch 集群,数据规模超过 4000 节点 ...

  4. kali 设置 Java 版本,并更换为 1.8 版本

    kali 设置 Java 版本,并更换为 1.8 版本 1.安装 JDK 1.下载java 1.8 :https://repo.huaweicloud.com/java/jdk/8u202-b08/j ...

  5. 如何使用Splashtop在家里进行有效的新人入职培训

    编辑搜图 请点击输入图片描述 今天的新闻有点不简单,不得了. 简而言之,利用Splashtop可以在家里进行有效的新人入职培训.最棒的地方就在于--两个用户可以远程访问同一台计算机,并且可以看到彼此的 ...

  6. C数据结构线性表:实现顺序表的增删改查&完整篇

    文章目录 ①前言 顺序表结构体的定义 ②初始化顺序表 ③插入新的元素 插入的时候需要特别注意的几点 ④删除元素 第一个删除元素功能实现 第二个删除元素功能实现 对代码下面中**i- -**的说明(第二 ...

  7. Clion代码自动格式化保存

    目录 前言 使用外部工具Artistic Style Clion 插件配置 注意 前言 使用Clion的时候,可以自动格式化代码的操作. 使用外部工具Artistic Style 序号 名称 地址 1 ...

  8. element-plus表格添加删除行很慢

    如果添加第一行或第二行就很慢,那么这个不是row-key的原因. 很有可能是nuxt的调试工具监控组件原因,可以试着把工具关了看看 devtools: { enabled: false }, 发布后不 ...

  9. springcloud整合stream解决项目升级的多个消息中间件的收发问题

    cloud stream (一)简介Spring Cloud Stream 是一个用来为微服务应用构建消息驱动能力的框架.它可以基于 Spring Boot 来创建独立的.可用于生产的 Spring ...

  10. Django 的 ORM

    Django 的 ORM: 注意: 需要提前创建好数据库,Django不会自动创建数据库