通过FeignClient如何获取文件流steam is close问题

网友投稿 590 2022-07-23


目录FeignClient获取文件流 steam is close问题原因解决办法FeignClient注解参数日志级别配置服务超时、重试、降级和熔断

FeignClient获取文件流 steam is close问题

inputstream.read 报错 steam is close

原因

idea debug启动导致

解决办法

直接启动

FeignClient注解参数

name:指定FeignClient的名称,如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现url: url一般用于调试,可以手动指定@FeignClient调用的地址decode404:当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignExceptionconfiguration: Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contractfallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口fallbackFactory: 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码path: 定义当前FeignClient的统一前缀

日志级别配置

默认Feign是不打印任何日志的,下面我们来开启Feign的日志,Feign有四种日志级别:

NONE【性能最佳,适用于生产】:不记录任何日志(默认值)。BASIC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间。HEADERS:记录BASIC级别的基础上,记录请求和响应的header。FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。

在application.yml 中添加以下内容,将该Feign接口的日志级别设置为DEBUG:

# 定义feign客户端所在的路径,需要设置日志级别为debug

logging.level: com.example.customer.service.CustomerService: debug

# user为服务名,单个配置客户端日志级别设置,如果需要全局配置,把user更换为default

feign.client.config.user.loggerLevel: FULL

调用日志信息截图

2020-06-07 14:06:27.671 DEBUG 24961 --- [nio-8081-exec-3] c.e.customer.service.CustomerService     : [CustomerService#getUser] ---> GET http://user/user HTTP/1.12020-06-07 14:06:27.671 DEBUG 24961 --- [nio-8081-exec-3] c.e.customer.service.CustomerService     : [CustomerService#getUser] ---> END HTTP (0-byte body)2020-06-07 14:06:27.678 DEBUG 24961 --- [nio-8081-exec-3] c.e.customer.service.CustomerService     : [CustomerService#getUser] <--- HTTP/1.1 200  (7ms)2020-06-07 14:06:27.679 DEBUG 24961 --- [nio-8081-exec-3] c.e.customer.service.CustomerService     : [CustomerService#getUser] connection: keep-alive2020-06-07 14:06:27.679 DEBUG 24961 --- [nio-8081-exec-3] c.e.customer.service.CustomerService     : [CustomerService#getUser] content-type: application/json2020-06-07 14:06:27.679 DEBUG 24961 --- [nio-8081-exec-3] c.e.customer.service.CustomerService     : [CustomerService#getUser] date: Sun, 07 Jun 2020 06:06:27 GMT2020-06-07 14:06:27.679 DEBUG 24961 --- [nio-8081-exec-3] c.e.customer.service.CustomerService     : [CustomerService#getUser] keep-alive: timeout=602020-06-07 14:06:27.679 DEBUG 24961 --- [nio-8081-exec-3] c.e.customer.service.CustomerService     : [CustomerService#getUser] transfer-encoding: chunked2020-06-07 14:06:27.679 DEBUG 24961 --- [nio-8081-exec-3] c.e.customer.service.CustomerService     : [CustomerService#getUser]2020-06-07 14:06:27.679 DEBUG 24961 --- [nio-8081-exec-3] c.e.customer.service.CustomerService     : [CustomerService#getUser] {"id":1,"name":"test","phone":"119"}2020-06-07 14:06:27.679 DEBUG 24961 --- [nio-8081-exec-3] c.e.customer.service.CustomerService     : [CustomerService#getUser] <--- END HTTP (36-byte body)

服务超时、重试、降级和熔断

·超时 Feign接口调用分两层,Ribbon(负载均衡)和Hystrix(熔断器)的调用,因此Feign的超时时间就是ribbon的超时时间和Hystrix的超时时间的结合

·重试 使用Ribbon

设置Ribbon重试次数

ribbon:

#连接超时时间

ConnectTimeout: 1000

#读超时时间

ReadTimeout: 1000

##同一台实例最大重试次数,不包括首次调用

MaxAutoRetries: 0

#重试负http://载均衡其他的实例最大重试次数,不包括首次调用

MaxAutoRetriesNextServer: 1

#是否所有操作都重试,设置false时,只会对get请求进行重试;如果设置为true,便会对所有的请求进行重试,如果是put或post等写操作,如果服务器接口没做幂等性,慎用;

OkToRetryOnAllOperations: false

负载均衡配置

#服务名

user:

ribbon:

#选择随机算法

NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

Ribbon Eager加载

默认情况下Ribbon是懒加载的——首次请求Ribbon相关类才会初始化,这会导致首次请求过慢的问题,你可以配置饥饿加载,让Ribbon在应用启动时就初始化。

ribbon:

eager-load:

enabled: true

# 多个用,分隔

clients: user

降级和熔断使用hystrix

如果重试期间,调用时间超过了 Hystrix熔断的超时时间,便会立即熔断,进行FallBack

# 开启hystrix

feign.hystrix.enabled: true

# hystrix的超时时间 时间设置需要根据实际业务场景计算得出

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 10000

Fallback配置

@FeignClient(name = "user", fallback = CustomerFeignClientFallback.class)

public http://interface CustomerService {

/**

* 获取用户信息

*

* @return 用户信息

*/

@GetMapping("/user")

UserDTO getUser ();

@Component

public class CustomerFeignClientFallback implements CustomerService {

@Override

public UserDTO getUser () {

//todo 回退逻辑

return new UserDTO().setName("服务降级");

}

}

}

@FeignClient(name = "user", fallbackFactory = CustomerFeignClientFallbackFactory.class)

public interface CustomerService {

/**

* 获取用户信息

*

* @return 用户信息

*/

@GetMapping("/user")

UserDTO getUser ();

@Component

@Slf4j

public class CustomerFeignClientFallbackFactory implements FallbackFactory {

@Override

public CustomerService getUser () {

//todo 回退逻辑

return new UserDTO().setName("服务降级");

}

}

}

配置

logging:

level:

com.example.customer.service.CustomerService: debug

#全局配置,单个服务配置把default替换为需要设置的服务名

feign:

client.config.default.loggerLevel: FULL

okhttp.enabled: true

#熔断与回退

hystrix.enabled: true

#重试机制

ribbon:

#连接超时时间

ConnectTimeout: 2000

#读超时时间

ReadTimeout: 2000

##同一台实例最大重试次数,不包括首次调用

MaxAutoRetries: 0

#重试负载均衡其他的实例最大重试次数,不包括首次调用

MaxAutoRetriesNextServer: 1

#是否所有操作都重试

OkToRetryOnAllOperations: false

# Hystrix的超时时间

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 10000

有关Feign超时时间易混淆概念

Feign超时时间

feign.client.config.default.connectTimeout=10000 //Feign的连接建立超时时间,默认为10秒

feign.client.config.default.readTimeout=60000 //Feign的请求处理超时时间,默认为60

Ribbon 超时时间

ribbon.ReadTimeout=1000 //处理请求的超时时间,默认为1秒

ribbon.ConnectTimeout=1000 //连接建立的超时时长,默认1秒

Hystrix 超时时间

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000 #熔断器的超时时长默认1秒

以上各种超时配置,如果都存在,则时间小的配置生效

小提示

Feign的底层是调用ribbon来实现负载均衡的,为了不和ribbon的重试机制冲突不需要配置feign超时时间和重试功能,只需配置ribbon和hystrix超时时间即可。Ribbon超时时间必须小于hysrix超时设置,这样才能触发ribbon重http://试,ribbon重试分为两种情况,同一实例重试和负载均衡的不同实例重试,默认为1次和0次Feign的默认配置,是不启用hystrix,需要开启feign.hystrix.enabled=true,这样hystrix的相关配置才可以在Feign中生效。Hystrix的超时时间=Ribbon的重试次数(包含首次) * (ribbon.ReadTimeout + ribbon.ConnectTimeout)在Ribbon超时但Hystrix没有超时的情况下,Ribbon便会采取重试机制;而重试期间如果时间超过了Hystrix的超时配置则会立即被熔断(fallback)关系图


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:JAVA连接到SQLserver的步骤方法以及遇到的问题
下一篇:Java深入讲解SPI的使用
相关文章

 发表评论

暂时没有评论,来抢沙发吧~