作用
在网络请求时,可能会出现异常请求,如果还想再异常情况下使系统可用,那么就需要容错处理,比如:网络请求超时时给用户提示“稍后重试”或使用本地快照数据等等。Spring Cloud Feign就是通过Fallback实现的
feign服务改造
在上文基础上进行改造
user-api改造
@FeignClient
feign调用入口
package com.yyzh.user.api.feign;
import com.yyzh.user.api.feign.base.FeignConfigurationAdapter;
import com.yyzh.user.api.feign.fallback.RemoteUserServiceFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "user-server",// 注册到eureka服务上的名字
url = "${feign.server.name.user.url:}",// 可以指定地址调用服务
configuration = FeignConfigurationAdapter.class,
fallbackFactory = RemoteUserServiceFallbackFactory.class)
@RequestMapping(path = "/v1/user")// 目标服务中拼接接口
public interface RemoteUserService {
@GetMapping(value = "/hello")
String hello(@RequestParam("str") String str);
}
feign通用配置
package com.yyzh.user.api.feign.base;
import feign.Feign;
import feign.Logger;
import feign.Retryer;
import feign.querymap.BeanQueryMapEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/**
* feign的 通用配置
* @author zihui
* @date 2021-01-25 11:20:29
**/
@Configuration
public class FeignConfigurationAdapter {
@Bean
Logger.Level feignLoggerLevel() {
//设置日志等级
return Logger.Level.FULL;
}
/**
* 替换解析queryMap的类,实现父类中变量的映射
* @return Feign.Builder
*/
@Bean
@Primary
public Feign.Builder feignBuilder() {
return Feign.builder().queryMapEncoder(new BeanQueryMapEncoder()).retryer(Retryer.NEVER_RETRY);
}
}
FallbackFactory工厂
package com.yyzh.user.api.feign.fallback;
import com.yyzh.user.api.feign.RemoteUserService;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class RemoteUserServiceFallbackFactory implements FallbackFactory<RemoteUserService> {
@Override
public RemoteUserService create(Throwable throwable) {
log.warn("RemoteUserService服务fallback:case:{}", throwable.getMessage());
return new RemoteUserServiceFallback(throwable);
}
}
Fallback实现类
package com.yyzh.user.api.feign.fallback;
import com.yyzh.user.api.feign.RemoteUserService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class RemoteUserServiceFallback implements RemoteUserService{
private Throwable cause;
public RemoteUserServiceFallback(Throwable throwable) {
this.cause = throwable;
}
@Override
public String hello(String input) {
log.warn("RemoteUserService调用hello失败:{},cause:{}", input, cause);
return null;
}
}
最后别忘了api打包
客户端验证
feing客户端升级配置FeighConfig.java
加入@ComponentScan扫描fallback路径
package com.springboot.demo.config;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @author zihui
* @version 1.0
* @title: FeighConfigurer
* @description: TODO
* @date 2021-01-21 15:36:25
*/
@Configuration
@EnableFeignClients(basePackages = {
"com.yyzh.user.api.feign"
})
@ComponentScan(basePackages = {
"com.yyzh.user.api.feign.fallback"
} )
public class FeighConfig {
}
application.yml配置中开启该功能
# feign 配置
feign:
hystrix:
enabled: true #开启hystrix
验证
重启消费端服务,调用feign接口,此时因为feign提供服务端未开启服务,导致的熔断返回如下两个日志打印,此时Spring Cloud Feign HTTP请求异常Fallback容错机制(基于Hystrix实现)已接入项目