一、Ribboon配置
在Spring cloud Feign中客户端负载均衡是通过Spring cloud Ribbon实现的,所以我们可以直接通过配置Ribbon客户端的方式来自定义各个服务客户端调用的参数。那么我们怎么在Spring cloud Feign中配置Ribbon呢?
全局配置
全局配置方法简单,直接用ribbon.<key>=<value>的方式设置ribbon的默认参数。如下:
#ribbon请求连接的超时时间
ribbon.ConnectTimeout=250
#请求处理的超时时间
ribbon.ReadTimeout=1000
#对所有操作请求都进行重试
ribbon.OkToRetryOnAllOperations=true
#对当前实例的重试次数
ribbon.MaxAutoRetries=1
#对下个实例的重试次数
ribbon.MaxAutoRetriesNextServer=1
指定服务配置
为了有针对性的配置,针对各个服务客户端进行个性化配置方式与使用Spring cloud Ribbon时的配置方式一样的,都采用<client>.ribbon.<key>=<value>的格式进行设置。如下:
hello-service.ribbon.ConnectTimeout=500
hello-service.ribbon.ReadTimeout=1000
二、重试机制
#对所有操作请求都进行重试 ribbon.OkToRetryOnAllOperations=false #对当前实例的重试次数 ribbon.MaxAutoRetries=1 #对下个实例的重试次数 ribbon.MaxAutoRetriesNextServer=1
结果:
未超时(正常)时,compute服务被调用一次。
超时时,compute服务被调用3次。
三、Hystrix配置
在Spring cloud Feign中,除了引入Spring cloud Ribbon之外,还引入了服务保护与容错的工具Hystrix。默认情况下, Spring cloud Feign会为将所有Feign客户端的方法都封装到Hystrix命令中进行服务保护。
那么在Spring cloud Feign如何配置Hystrix的属性以及如何实现服务降级?
全局配置
全局配置通ribbon一样,直接使用它的默认配置前缀hystrix.command.default就可以进行设置,
在设置之前,需要确认feign.hystrix.enabled参数是否设置为false,如果为false则关闭Feign客户端的Hystrix支持。
或者使用hystrix.command.default.execution.timeout.enabled=false来关闭熔断功能。
比如设置全局的超时时间:
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds
详细参数列表见《服务容错保护断路器Hystrix之二:Hystrix工作流程解析》中的《2.8、关于配置》
指定服务配置
如果想局部关闭Hystrix,需要通过使用@Scope("prototype")注解为指定的客户端配置Feign.Builder实例,详细步骤如下:
package com.dxz.feign; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import feign.Feign; @Configuration public class DisableHystrixConfiguration { @Bean @Scope("prototype") public Feign.Builder feignBuilder() { return Feign.builder(); } }
package com.dxz.feign.remote; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import com.dxz.feign.DisableHystrixConfiguration; //@FeignClient("compute-service") @FeignClient(name="compute-service",configuration=DisableHystrixConfiguration.class) public interface HelloService { @RequestMapping(value="/add", method = RequestMethod.GET) String hello(@RequestParam("a") Integer a, @RequestParam("b") Integer b, @RequestParam("sn") Integer sn); }
结果:
下面的超时,不会熔断调用fallback方法,而是等待。
四、服务降级配置
新增一个服务降级处理类:
package com.dxz.feign.remote; import org.springframework.stereotype.Service; @Service public class HelloServiceFallback implements HelloService { @Override public String hello(Integer a, Integer b, Integer sn) { System.out.println("HelloServiceFallback"); return "fallback"; } }
在服务绑定接口HelloService中,通过@FeignClient注解的fallback属性来指定服务降级处理类:
package com.dxz.feign.remote; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import com.dxz.feign.DisableHystrixConfiguration; @FeignClient(name="compute-service", fallback=HelloServiceFallback.class) //@FeignClient(name="compute-service",configuration=DisableHystrixConfiguration.class) public interface HelloService { @RequestMapping(value="/add", method = RequestMethod.GET) String hello(@RequestParam("a") Integer a, @RequestParam("b") Integer b, @RequestParam("sn") Integer sn); }
测试:
其他配置
请求压缩
Spring cloud Feign支持请求与响应的GZIP压缩,以减少通讯过程中的性能损耗。只需要通过下面两个参数设置,就能开启请求与响应的压缩功能:
feign.compression.request.enabled=true
feign.compression.response.enabled=true
日志配置
Spring cloud Feign在构建被@FeignClient修饰的服务客户端时,会为每一个客户端创建一个feign.Logger实例,我们可以利用该日志对象的DEBUG模式来帮助分析Feign的请求细节。
开启方式:
logging.level.<FeignClient>=<LEVEL value>
logging.level.com.dxz.feign.remote.HelloService=DEBUG
但是,只添加了如上配置,还无法实现对DEBUG日志的输出,这是由于Feign客户端默认的Logger.LEVEL对象定义为NONE级别。该级别不吉利任何Feign调用过程中的信息,所以需要调整级别,针对全局日志调整,直接在启动类里调整如下,
package com.dxz.feign; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.feign.EnableFeignClients; import org.springframework.context.annotation.Bean; import feign.Logger; @SpringBootApplication @EnableFeignClients @EnableDiscoveryClient public class ConsumerApplication { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
如果是局部调整,可以为日志级别增加配置类,如下:
package com.dxz.feign; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import feign.Logger; @Configuration public class FullLogConfiguation { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
package com.dxz.feign.remote; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import com.dxz.feign.DisableHystrixConfiguration; import com.dxz.feign.FullLogConfiguation; //@FeignClient(name="compute-service", fallback=HelloServiceFallback.class) //@FeignClient(name="compute-service",configuration=DisableHystrixConfiguration.class) @FeignClient(name="compute-service", fallback=HelloServiceFallback.class, configuration=FullLogConfiguation.class) public interface HelloService { @RequestMapping(value="/add", method = RequestMethod.GET) String hello(@RequestParam("a") Integer a, @RequestParam("b") Integer b, @RequestParam("sn") Integer sn); }
测试结果: