万世威 2020-10-16
OpenFeign 是一个声明式的 web 服务客户端, 让编写 web 服务更加简单, 写一个接口并添加一个注解即可, 具有可插拔注解特性 并同时支持 Feign 注解 和 JAX-RS 注解, Feign 支持可插拔式的编码器和解码器.
Spring Cloud 对 Feign 进行了封装, 支持 springmvc 标准注解 和 HttpMessageConverters. Feign 可以与 Ribbon 和 Eureka 组合使用, 以支持 负载均衡
1、单独使用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
@FeignClient(url = "http://127.0.0.1:9002/dist", name = "test")
public interface FeignService {
@GetMapping("/service/{id}")
String getStore(@PathVariable("id") int id);
@PostMapping(value = "/file", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
String testFileUpload(@RequestBody MultipartFile file);
}
2、搭配 Nacos 使用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
spring:
application:
name: quick-openfeign
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
@FeignClient(value = "quick-provider")
public interface FeignService {
@GetMapping("/dist/service")
String getStore();
}
这 2 种配置方式,在有 context-path 参数下,需要写明 context-path,可在 @FeignClient 中加入,path 参数值指定
1、使用 OkHttpClient
或 ApacheHttpClien
, 同时需要引入相应的包
feign.okhttp.enabled=true
feign.httpclient.enabled=true
2、配置优先级
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 5000
loggerLevel: basic
3、创建多个具有相同 name
和 url
的 feign client
, 使用 contextId
属性配置,避免 bean 名称冲突
@FeignClient(contextId = "fooClient", name = "stores", configuration = FooConfiguration.class)
public interface FooClient {}
@FeignClient(contextId = "barClient", name = "stores", configuration = BarConfiguration.class)
public interface BarClient {}
@FeignClient(value = "quick-provider", fallback = HystrixClientFallback.class)
public interface FeignService {
@GetMapping("/dist/service/{id}")
String getStore(@PathVariable("id") int id);
}
@Component
public class HystrixClientFallback implements FeignService {
@Override
public String getStore(int id) { return "hystrix"; }
}
/* 通过 Feign 调用提供者时,提供者方法报错, 执行 HystrixClientFallback 类同名方法 */
@FeignClient(value = "quick-provider", fallbackFactory = HystrixClientFallback.class)
public interface FeignService {
@GetMapping("/dist/service/{id}")
String getStore(@PathVariable("id") int id);
}
@Component
public class HystrixClientFallback implements FallbackFactory<FeignService> {
@Override
public FeignService create(Throwable t) {
return new FeignService() {
@Override
public String getStore(int id) {
return t.getMessage();
}
};
}
}
public interface ProviderService {
@GetMapping("/dist/service/{id}")
String getStore(@PathVariable("id") int id);
}
@FeignClient(value = "quick-provider", fallbackFactory = HystrixClientFallback.class)
public interface FeignService extends ProviderService {}
feign:
compression:
response:
enabled: true
request:
enabled: true
mime-types: text/xml,application/xml,application/json
min-request-size: 2048
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignBuilderConfiguration {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
# application.yaml 中添加以下配置
logging:
level:
com.dist.feign: debug # feign 接口所在类包名[可加类名]
public interface FeignService {
@GetMapping("/dist/service/{id}")
String getStore(@PathVariable("id") int id);
}
@Configuration
@Import(FeignClientsConfiguration.class)
public class FeignConfig {
@Bean
public FeignService feignService(Decoder decoder, Encoder encoder, Client client, Contract contract) {
return Feign.builder().client(client)
.encoder(encoder)
.decoder(decoder)
.contract(contract)
.target(FeignService.class, "http://quick-provider");
}
}