1.引入依赖
Maven坐标
<!--feign 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>${feign.version}</version>
</dependency>
2. 定义FeignClient
/**
* @description: 基础服务
*
* FeignClient注解:
* name/value属性: 这两个的作用是一样的,指定的是调用服务的微服务名称(独立使用时,只需唯一) 可以使用环境变量或者jvm属性定义url字段
* url: 定义远程服务的domain
* fallbackFactory: 定义熔断器(可以在熔断器中定义熔断处理,返回兜底的结果)
*
* @date: 2020/11/24 14:49
* @author: fdh
*/
//@FeignClient(name = "baseSapi", url = "${qs.sapi.base.url.prefix}", fallbackFactory = RemoteBaseFallBackFactory.class)
@FeignClient(name = "baseSapi", url = "http://localhost:9001", fallbackFactory = RemoteBaseFallBackFactory.class)
public interface RemoteBaseService {
/**
* 获取考季知识点
*
* 接口地址: http:// xxxxx
*
* @param seasonId
* @return
*/
@RequestMapping(value = "/s1/v1/seasonKnowledgePoint/kpListBySeasonId", method = RequestMethod.GET)
SapiResult<List<KnowledgePointVo>> getKpListBySeasonId(@RequestParam("seasonId") Long seasonId);
}
3.定义熔断器
/**
* @description: 远程基础熔断工厂
* @date: 2020/11/25 13:48
* @author: fdh
*/
@Component
public class RemoteBaseFallBackFactory implements FallbackFactory<RemoteBaseService> {
@Override
public RemoteBaseService create(Throwable throwable) {
RemoteBaseFallBackServiceImpl remoteBaseFallBackService = new RemoteBaseFallBackServiceImpl();
remoteBaseFallBackService.setThrowable(throwable);
return remoteBaseFallBackService;
}
}
4.定义FeignClient熔断实现
/**
* @description: RemoteBaseService熔断处理
* @date: 2020/11/25 13:49
* @author: fdh
*/
public class RemoteBaseFallBackServiceImpl implements RemoteBaseService {
private static final Logger log = LoggerFactory.getLogger(RemoteBaseFallBackServiceImpl.class);
@Setter
private Throwable throwable;
private void printLog(String modules, Throwable throwable){
if( modules == null ){
modules = StringUtils.EMPTY;
}
log.info("{}异常:", modules, throwable);
}
@Override
public SapiResult<List<KnowledgePointVo>> getKpListBySeasonId(Long seasonId) {
printLog("知识点接口", throwable);
return SapiResultUtil.success(Collections.emptyList());
}
}
5. 扫描FeignClient
/**
* @description: 启动类
* @date: 2020/11/25 13:52
* @author: fdh
*/
@SpringBootApplication
@EnableFeignClients(basePackages = "com.xxx.feign")
public class DaApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(DaApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(DaApplication.class, args);
}
}
以上就可以实现Feign独立使用,不依赖注册中心,进行独立远程调用
补充:
1. 生产环境上往往需要记录FeignClient远程调用日志,我们可以定义日志输出级别
/**
* @description: Feign日志
* @date: 2020/11/5 16:35
* @author: fdh
*/
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
推荐日志级别:
| 级别 | 打印内容 |
| NONE(默认值) | 不记录任何日志 |
| BASIC(更适合生产环境) | 仅记录请求方法、URL、响应状态代码以及执行时间 |
| HEADERS | 记录BASIC级别的基础上,记录请求和响应的 header |
| FULL(更适合开发环境) | 记录请求和响应的 header、body和元数据 |
2. 启用熔断并设置熔断超时时间(默认1秒)
feign.hystrix.enabled=true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 30000
统一处理,需要增加FeignClient远程调用携带加密参数
@Component
public class FeignRequestInterceptor implements RequestInterceptor {
private org.slf4j.Logger log = LoggerFactory.getLogger(FeignRequestInterceptor.class);
@Override
public void apply(RequestTemplate requestTemplate) {
try {
// xxxx 算法
//String sign = DigestUtils.md5DigestAsHex(params.getBytes("utf-8"));
requestTemplate.query("sign", "xxxxxx");
} catch (UnsupportedEncodingException e) {
log.error("签名失败:", e);
}
}
}
