feign 回退原因_spring cloud feign学习三:Feign的更多使用

Ribbon配置

全局配置

由于Spring cloud Feign的客户端负载均衡是通过spring cloud Ribbon实现的,所以我们可以直接通过配置Ribbon客户端的方式来自定义各个服务客户端调用的参数。

ribbon.ConnectTimeout=500

ribbon.ReadTimeOut=5000

指定服务配置

大多数情况下,我们对于服务调用的超时时间可能会根据实际服务的特性做一些调整,所以仅仅依靠默认的全局配置是不行的。在使用spring cloud feign的时候,针对各个服务客户端进行个性化配置的方式与使用Spring Cloud Ribbon时的配置方式时一样的,都采用了.ribbon.key=value的格式进行设置。我们使用@Feign(value="user-service")来创建一个Feign客户端的时候,同时也创建了一个名为user-service的Ribbon客户端。所以我们也可以使用@Feign中的name或者value属性只来设置对应的ribbon参数,比如:

user-service.ribbon.ConnectTimeout=500

user-service.ribbon.ReadTimeout=2000

user-service.ribbon.OkToRetryOnAllOperations=true

user-service.ribbon.MaxAutoRetriesNextServer=2

user-service.ribbon.MaxAutoRetries=1

重试机制

在spring cloud Feign中默认实现了请求的重试机制,而上面对user-service客户端的配置内容就是对于请求超时以及重试配置的详情,

@GetMapping

public String userHello() throws Exception{

ServiceInstance serviceInstance = client.getLocalServiceInstance();

//线程阻塞,测试超时

int sleeptime = new Random().nextInt(3000);

logger.info("sleeptime:"+sleeptime);

Thread.sleep(sleeptime);

logger.info("/user,host:"+serviceInstance.getHost()+",service id:"+serviceInstance.getServiceId()+",port:"+serviceInstance.getPort());

return "hello world";

}

user-service.ribbon.ConnectTimeout=500

user-service.ribbon.ReadTimeout=2000

user-service.ribbon.OkToRetryOnAllOperations=true

user-service.ribbon.MaxAutoRetriesNextServer=2

user-service.ribbon.MaxAutoRetries=1

在pay-service应用中增加了重试配置参数,其中,由于user-service.ribbon.MaxAutoRetries设置为1,所以重试策略先尝试访问首选案例一次,失败后才更换实例访问,而更换实例访问的次数通过user-service.ribbon.MaxAutoRetriesNextServer参数设置为2,所以会尝试更换两次实例进行重试。

Ribbon的超时与Hystrix的超时是两个概念。一般需要让hystrix的超时时间大于Ribbon的超时时间,否则Hystrix命令超时后,改命令直接熔断,重试机制就没有任何意义了。

Hystrix配置

spring cloud Feign中,除了引入了用于客户端负载均衡的spring cloud Ribbon之外,还引入了服务保护了容错的工具Hystrix,spring cloud feign客户端的方法都封装到Hystrix命令中进行服务保护。

全局配置

对于Hystrix的全局配置同spring cloud Ribbon的全局配置一样,直接使用它的默认配置前缀hystrix.command.default就可以进行设置,比如设置全局的超时时间:

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000

在对hystrix进行设置之前,需要确认feign.hystrix.enabled参数没有被设置为false,否则该参数设置会关闭Feign客户端的Hystrix支持。而对于我们之前测试重试机制时,对于Hystrix的超时时间控制除了可以使用上面的配置来增加熔断超时时间,也可以通过feign.hystrix.enabled=false来关闭Hystrix功能,或者使用hystrix.command.default.execution.timeout.enabled=false来关闭熔断功能。

禁用Hystrix

在spring cloud feign中,可以通过feign.hystrix.enabled=false来关闭Hystrix功能。另外,如果不想全局地关闭Hystrix支持,而只想针对某个服务客户端关闭Hystrix支持时,需要通过使用@Scope("protototype")注解为指定的客户端配置Feign.Builder实例,

@Configuration

public class DisableHystrixConfigutation {

@Bean

@Scope("prototype")

public Feign.Builder feignBuilder(){

return Feign.builder();

}

}

在pay-service服务的user-service接口中引入该配置。

@FeignClient(value = "user-service",configuration = DisableHystrixConfigutation.class)

...

指定命令配置

对于Hystrix命令的配置,在实际应用时往往也会根据实际业务情况制定出不同的配置方案。配置方法也跟传统的Hystrix命令的参数配置相似,采用hystrix.command.作为前缀。而默认情况下会采用feign客户端中的方法名作为标识,所以,针对上面的hello方法,可以如下配置:

hystrix.command.hello.isolation.thread.timeoutInmilliseconds=5000

需要注意的是,由于方法名有可能会重复,这个时候相同的方法名的hystrix配置会共用,所以在进行方法与配置的时候需要做好一定的规划,当然也可以重写Feign.Builder的实现,并在应用主类中创建它的实例来覆盖自动化配置的HystrixFegin.Builder实现。

服务降级配置

Hystrix提供的服务降级是服务容错的重要功能,由于Spring cloud feign在定义服务客户端的时候与Spring cloud Ribbon有很大的差别,HystrixCommand定义被封装起来,我们无法像之前介绍spring cloud hystrix时,通过@HystrixCommand注解的fallback参数那样来指定具体的服务降级处理方法。但是,spring cloud feign提供了另外一种简单的定义方式,

定义一个Feign客户端的服务降级类UserServiceFallback,实现UserService接口,其中每个重写方法的实现逻辑都可以用来定义相应的服务降级逻辑,具体如下:

@Component

public class UserServiceFallback implements UserService{

@Override

public String index() {

return "error";

}

@Override

public String hello() {

return "hello error";

}

@Override

public String hello1(String username) {

return "hello username is null";

}

@Override

public User hello2(String username, Integer age) {

return new User("未知",0);

}

@Override

public String hello3(User user) {

return "user error";

}

}

在服务绑定接口user-service中,通过@FeignClient注解的fallback属性来指定对应的服务降级实现类:

@FeignClient(value = "user-service",fallback = UserServiceFallback.class)

public interface UserService {

@RequestMapping("/user/index")

String index();

@RequestMapping("/user/hello")

String hello();

@RequestMapping(value = "/user/hello1",method = RequestMethod.GET)

String hello1(@RequestParam("username") String username);

@RequestMapping(value = "/user/hello2",method = RequestMethod.GET)

User hello2(@RequestHeader("username") String username, @RequestHeader("age") Integer age);

@RequestMapping(value = "/user/hello3",method = RequestMethod.POST)

String hello3(@RequestBody User user);

}

测试,停止用户的服务:

localhost:7070/pay/hello1?username=zhihao.miao

localhost:7070/pay/hello2

localhost:7070/pay/hello3

返回了我们在UserServiceFallback中定义的每个方法的降级的重写函数的实现。

fallbackFactory参数的使用

If one needs access to the cause that made the fallback trigger, one can use the fallbackFactory attribute inside @FeignClient.

如果需要访问到造成回退的具体原因,可以使用@FeignClient.注解的fallbackFactory属性。

@Component

public class HystrixClientFallbackFactory implements FallbackFactory {

private Logger logger = LoggerFactory.getLogger(getClass());

@Override

public UserService create(Throwable throwable) {

logger.info("user service exception:" + throwable.getMessage());

return new HystrixClientWithFallBackFactory(){

@Override

public User hello2(String username, Integer age) {

return super.hello2(username, age);

}

};

}

}

定义HystrixClientWithFallBackFactory实现由@Feign注解标记的接口,我这边就实现了hello2方法,只测试这个方法。

public class HystrixClientWithFallBackFactory implements UserService{

@Override

public String index() {

return null;

}

@Override

public String hello() {

return null;

}

@Override

public String hello1(String username) {

return null;

}

@Override

public User hello2(String username, Integer age) {

User user = new User();

user.setAge(0);

user.setUsername("zhihao.miao");

user.setId(-1);

return user;

}

@Override

public String hello3(User user) {

return null;

}

}

测试,断开User服务之后,进入保护模式,执行HystrixClientWithFallBackFactory中的回退操作,

控制台上输出错误日志:

其他配置

请求压缩

spring cloud feign支持对请求与相应进行GZIP压缩,以减少通信过程中的性能损耗,我们只需要通过下面的两个参数设置,就能开启请求与相应的压缩功能。

feign:

compression:

request:

enabled: true

response:

enabled: true

同时,我们还可以对请求压缩做一些更细致的设置,比如下面的配置内容指定压缩的请求数据类型,并设置了请求压缩的大小下限,只有超过了这个大小的请求才会对其进行压缩。

feign:

compression:

request:

enabled: true

mime-types: text/xml,application/xml,application/json

min-request-size: 2048

而mime-types属性和min-request-size都是默认值

日志配置

spring cloud Feign在构建被@FeignClient注解修饰的服务客户端时,会为每一个客户端都创建一个feign.Logger实例,我们可以利用改日志对象的DEBUG模式来帮助分析Feign的请求细节。可以在application.yml配置logging.level.的参数配置格式来开启指定feign客户端的debug日志,其中为feign客户端定义接口的完整路径

logging:

level:

com.zhihao.miao.pay.service.UserService: debug

但是,只添加了该配置还无法实现对debug日志的输出。这是因为feign客户端默认的Logger.Level对象定义为NONE级别,该级别不会记录任何Feign调用过程中的信息,所以我们需要调整它的级别,针对全局的日志级别,可以在应用主类中加入Logger.Level的Bean创建,

@SpringBootApplication

@EnableDiscoveryClient

@EnableFeignClients

public class PayApplication {

public static void main(String[] args) {

SpringApplication.run(PayApplication.class,args);

}

@Bean

Logger.Level feignLoggerLevel(){

return Logger.Level.FULL;

}

}

也可以实现配置类,然后在Feign客户端来指定配置类以实现是否需要调整不同的日志级别,比如说下面的实现:

@Configuration

public class FullLogConfiguration {

@Bean

Logger.Level feignLoggerLevel(){

return Logger.Level.FULL;

}

}

@FeignClient(value = "user-service",configuration = FullLogConfiguration.class)

public interface UserService {

@RequestMapping("/user/index")

String index();

@RequestMapping("/user/hello")

String hello();

@RequestMapping(value = "/user/hello1",method = RequestMethod.GET)

String hello1(@RequestParam("username") String username);

@RequestMapping(value = "/user/hello2",method = RequestMethod.GET)

User hello2(@RequestHeader("username") String username, @RequestHeader("age") Integer age);

@RequestMapping(value = "/user/hello3",method = RequestMethod.POST)

String hello3(@RequestBody User user);

}

访问localhost:7070/pay/hello1?username=zhihao.miao接口,控制台上打印如下信息:

对于Feign的Logger级别主要有下面4类,可根据实际需要进行调整使用:

none:不记录任何信息

basic:仅记录请求方法,url以及响应状态码和执行时间

headers:除了记录basic级别的信息之外,还会记录请求和响应的头信息。

FULL:记录所有请求与响应的明细,包括头信息,请求体,元数据等。

代码地址

代码地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值