SpringCloud开发之OpenFeign timeout和压缩等问题
在某些时候,我们希望某个同步调用执行更长的时间(异步暂时不考虑),这个时候,首先就是要设置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和压缩等问题的更多相关文章
- Android安全开发之ZIP文件目录遍历
1.ZIP文件目录遍历简介 因为ZIP压缩包文件中允许存在“../”的字符串,攻击者可以利用多个“../”在解压时改变ZIP包中某个文件的存放位置,覆盖掉应用原有的文件.如果被覆盖掉的文件是动态链接s ...
- Asp.net Mvc模块化开发之“部分版本部分模块更新(上线)”
项目开发从来就不是一个简单的问题.更难的问题是维护其他人开发的项目,并且要修改bug.如果原系统有重大问题还需要重构. 怎么重构系统不是本文探讨的问题,但是重构后如何上线部署和本文关系密切.这个大家可 ...
- ArcGIS Engine开发之旅05---空间数据库
原文:ArcGIS Engine开发之旅05---空间数据库 1 Geodatabase概念 Geodatabase是ArcInfo8引入的一种全新的面向对象的空间数据模型,是建立在DBMS之上的统 ...
- Android开发之Java必备基础
Android开发之Java必备基础 Java类型系统 Java语言基础数据类型有两种:对象和基本类型(Primitives).Java通过强制使用静态类型来确保类型安全,要求每个变量在使用之前必须先 ...
- iOS多线程开发之GCD(中篇)
前文回顾: 上篇博客讲到GCD的实现是由队列和任务两部分组成,其中获取队列的方式有两种,第一种是通过GCD的API的dispatch_queue_create函数生成Dispatch Queue:第二 ...
- Android 安全开发之 ZIP 文件目录遍历
1.ZIP文件目录遍历简介 因为ZIP压缩包文件中允许存在"../"的字符串,攻击者可以利用多个"../"在解压时改变ZIP包中某个文件的存放位置,覆盖掉应用原 ...
- Android开发之旅3:android架构
引言 通过前面两篇: Android 开发之旅:环境搭建及HelloWorld Android 开发之旅:HelloWorld项目的目录结构 我们对android有了个大致的了解,知道如何搭建andr ...
- 高效开发之SASS篇 灵异留白事件——图片下方无故留白 你会用::before、::after吗 link 与 @import之对比 学习前端前必知的——HTTP协议详解 深入了解——CSS3新增属性 菜鸟进阶——grunt $(#form :input)与$(#form input)的区别
高效开发之SASS篇 作为通往前端大神之路的普通的一只学鸟,最近接触了一样稍微高逼格一点的神器,特与大家分享~ 他是谁? 作为前端开发人员,你肯定对css很熟悉,但是你知道css可以自定义吗?大家 ...
- .NET Core 跨平台 GUI 开发之 GTtkSharp 初级篇
.NET Core 跨平台 GUI 开发之 GTtkSharp 初级篇 本文作为初级篇,适合已经安装好.NET Core 环境以及 Gtk 环境,并具备了 C#开发基础知识,能跑一些简单的例子,希望更 ...
- iOS多线程开发之GCD(中级篇)
前文回顾: 上篇博客讲到GCD的实现是由队列和任务两部分组成,其中获取队列的方式有两种,第一种是通过GCD的API的dispatch_queue_create函数生成Dispatch Queue:第二 ...
随机推荐
- dotnet 读 WPF 源代码笔记 提升调试效率的 NamedObject 类型
本文来聊聊 WPF 那些值得称赞的设计中的 NamedObject 类型.在 WPF 中,有很多值得我学习的设计开发思想,其中就包括本文将要介绍的 NamedObject 类型.此类型的定义仅仅只是为 ...
- 2018-2-13-win10-uwp-从StorageFile获取文件大小
title author date CreateTime categories win10 uwp 从StorageFile获取文件大小 lindexi 2018-2-13 17:23:3 +0800 ...
- Mysql带条件取多条随机记录
有个文章段落表part,有两种类型的段落,即part_type取1或2,要从表中随机取多条任意类型的段落,比如3条. 方法一 ORDER BY后接RAND() select * from part w ...
- k8s安全---安全机制之RBAC授权(14)
一.k8s 安全管理:认证.授权.准入控制概述 k8s 对我们整个系统的认证,授权,访问控制做了精密的设置:对于 k8s 集群来说,apiserver 是整 个集群访问控制的唯一入口,我们在 k8s ...
- Gin框架
目录 gin的参数获取 header参数 post Raw json 请求示例 gin的参数获取 package main import ( "fmt" "github. ...
- postgresql性能优化2:sql语句和缓存配置
1.看执行计划 EXPLAIN, 此命令用于查看SQL的执行计划 总的来说sql的执行计划是一个树形层次结构, 一般来说阅读上遵从层级越深越优先, 同一层级由上到下的原则. 来跟着铁蛋老师读: 层级越 ...
- java学习之旅(day.06)
switch多选择结构 多选择结构还有一个实现方式就是switch case switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支 switch(expression ...
- .net Core中实现SHA加密
#region 用SHA1加密字符串 /// <summary> /// 用SHA1加密字符串 /// </summary> /// <param name=" ...
- 中国十大IT技术社区,你都知道哪些?
中国5大新型IT技术社区与5大传统IT技术社区,你都知道哪些? 社区是聚集一类具有相同爱好或者相同行业的群体,IT技术社区就是聚集了IT行业内的技术人,在技术社区可以了解到行业的最新进展,学习最前沿的 ...
- python安装OCR识别库
(1)安装过程 参考的这个博客:https://blog.csdn.net/lanxianghua/article/details/100516187?depth_1-utm_source=distr ...