认识 Feign
Feign
-
声明式 REST Web 服务客户端
-
地址 https://github.com/OpenFeign/feign
Spring Cloud OpenFeign
- 依赖 spring-cloud-starter-openfeign
Feign 的简单使用
开启 Feign 支持
- 在配置类加上@EnableFeignClients
定义 Feign 接口
- 在对应接口上加入 @FeignClient ,添加这个注解的接口最后会被实例化为bean,我们可以直接调用这个bean上的方法 来实现远程的调用
简单配置
-
默认配置在 FeignClientsConfiguration 当中
-
通过 Encoder (编码器)/ Decoder (解码器)/ Logger (日志)/ Contract (服务协议)/ Client …
通过配置定制 Feign(web.xml)
feign:
client:
config:
feignName: 如果是deflate 默认所以的feign客户端都使用这个配置
connectTimeout:5000
readTimeout:5000
loggerLevel:full
errorDecoder:com.example.SimpleErrorDecoder
retryer:com.examole.SimpleRetryer
requestInterceptors:
- com.example.FooRequestInterceptor
- com.example.BarRequestInterceptor
decode404:false
encoder:com.example.SimpleEncoder
decoder:com.example.SimpleDecoder
contract:com.example.SimpleContract
Feign 的一些其他配置
-
feign.okhttp.enabled=true
开启 okhttp 支持 要加入对应的包 -
feign.httpclient.enabled=true
开启 httpclient 支持 要加入对应的包 -
feign.compression.response.enabled=true
开启响应压缩 -
feign.compression.request.enabled=true
开启请求压缩 -
feign.compression.request.mime-types= text/xml,application/xml,application/json
对 xml 和 json 进行压缩 -
feign.compression.request.min-request-size=2048
最小的请求的压缩尺寸为2048
以上4个为压缩配置
例子
由 eureka-server eureka-waiter-service 和 feign-customer-service 三部分组成
feign-customer-service 目录
需要修改的代码
CoffeeService
@FeignClient(name = "waiter-service-test", contextId = "coffee", path = "/coffee")
// name 是我们要去找的服务
// path 公共的path部分
// 因为 CoffeeService和CoffeeOrderService的name相同 为了区分 增加contextId 防止产生冲突
// 不要在接口上加@RequestMapping
public interface CoffeeService {
@GetMapping(path = "/", params = "!name")
List<Coffee> getAll();
@GetMapping("/{id}")
Coffee getById(@PathVariable Long id);
@GetMapping(path = "/", params = "name")
Coffee getByName(@RequestParam String name);
}
CoffeeOrderService
@FeignClient(name = "waiter-service-test", contextId = "coffeeOrder")
public interface CoffeeOrderService {
@GetMapping("/order/{id}")
CoffeeOrder getOrder(@PathVariable("id") Long id);
@PostMapping(path = "/order/", consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
CoffeeOrder create(@RequestBody NewOrderRequest newOrder);
}
CustomerRunner
@Component
@Slf4j
public class CustomerRunner implements ApplicationRunner {
@Autowired
private CoffeeService coffeeService;
@Autowired
private CoffeeOrderService coffeeOrderService;
//这两个实例 springcloud 会给我们去做 调用相应的方法 就可以完成 不用再使用 resttemple 调用
@Override
public void run(ApplicationArguments args) throws Exception {
readMenu();
Long id = orderCoffee();
queryOrder(id);
}
private void readMenu() {
List<Coffee> coffees = coffeeService.getAll();
coffees.forEach(c -> log.info("Coffee: {}", c));
}
private Long orderCoffee() {
NewOrderRequest orderRequest = NewOrderRequest.builder()
.customer("Li Lei")
.items(Arrays.asList("capuccino"))
.build();
CoffeeOrder order = coffeeOrderService.create(orderRequest);
log.info("Order ID: {}", order.getId());
return order.getId();
}
private void queryOrder(Long id) {
CoffeeOrder order = coffeeOrderService.getOrder(id);
log.info("Order: {}", order);
}
}
CustomerServiceApplication
@SpringBootApplication
@Slf4j
@EnableDiscoveryClient
@EnableFeignClients //开启 Feign 支持
public class CustomerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(CustomerServiceApplication.class, args);
}
@Bean
public CloseableHttpClient httpClient() {
return HttpClients.custom()
.setConnectionTimeToLive(30, TimeUnit.SECONDS)
.evictIdleConnections(30, TimeUnit.SECONDS)
.setMaxConnTotal(200)
.setMaxConnPerRoute(20)
.disableAutomaticRetries() //禁用自动重试
.setKeepAliveStrategy(new CustomConnectionKeepAliveStrategy()) //使用自己的 KeepAlive
.build();
}
}
结果分析
执行 3 个程序
成功注册之后
在feign-customer-service的控制台 我们可以看到 成功访问了eureka-waiter-service的数据 并调用了它的方法