OpenFeign服务接口调用
一、概述
- Feign 是一个声明式的 REST 客户端,它用了
基于接口的注解方式
,很方便实现客户端像调用本地接口方法一样,进行远程调用。 - Feign 最初由 Netflix 公司提供,但不支持SpringMVC注解,后由 SpringCloud 对其封装,支持了SpringMVC注解,让使用者更易于接受。
- https://cloud.spring.io/spring-cloud-static/Hoxton.SR1/reference/htmlsingle/#spring-cloud-openfeign
二、快速开发
1、在消费端引入 open-feign 依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、编写Feign调用接口。复制粘贴被调方的conreoller方法,加上类路径
GoodsFeignClient:
package com.liming.consumer.feign;
import com.liming.consumer.domain.Goods;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient("EUREKA-PROVIDER")
public interface GoodsFeign {
@GetMapping("/goods/findById/{id}")
public Goods findById(@PathVariable("id") Integer id);
}
3、在启动类 添加 @EnableFeignClients
注解,开启Feign功能
4、测试调用
OrderController:
package com.liming.consumer.controller;
import com.liming.consumer.domain.Goods;
import com.liming.consumer.feign.GoodsFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
GoodsFeign goodsFeign;
@GetMapping("/add/{id}")
public Goods add(@PathVariable("id") Integer id){
//String url="http://localhost:8000/goods/findById/"+id;
//Goods goods = restTemplate.getForObject(url, Goods.class);
// //1服务发现
// List<ServiceInstance> instances = discoveryClient.getInstances("EUREKA-PROVIDER");
// if(instances==null||instances.size()<=0){
// return null;
// }
// //2通过某个策略拿到一个实例 算法
// ServiceInstance serviceInstance = instances.get(0);
// String host = serviceInstance.getHost();
// int port = serviceInstance.getPort();
// System.out.println(host);
// System.out.println(port);
//
// String url="http://"+host+":"+port+"/goods/findById/"+id;
// Goods goods = restTemplate.getForObject(url, Goods.class);
//ribbon
// String url="http://EUREKA-PROVIDER/goods/findById/"+id;
// Goods goods = restTemplate.getForObject(url, Goods.class);
//feign调用
Goods goods = goodsFeign.findById(id);
return goods;
}
}
三、其他设置
3.1 超时设置
- Feign 底层依赖于 Ribbon 实现负载均衡和远程调用
- Ribbon默认1秒超时
- 超时配置: yml中
# 设置Ribbon的超时时间
ribbon:
ConnectTimeout: 1000 # 连接超时时间 默认1s
ReadTimeout: 3000 # 逻辑处理的超时时间 默认1s
测试:
1.连接超时,provider都停掉
2.逻辑处理的超时时间
provider
@GetMapping("/findById/{id}")
public Goods findById(@PathVariable("id") Integer id){
Goods goods = goodsService.findById(id);
goods.setTitle(goods.getTitle()+"|端口号:"+port);
//模拟业务逻辑比较繁忙
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return goods;
}
3.2 日志记录
1.Feign 只能记录 debug 级别的日志信息
# 设置当前的日志级别 debug,feign只支持记录debug级别的日志
logging:
level:
com.ydlclass: debug
2.定义Feign日志级别Bean
FeignLogConfig
package com.liming.consumer.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignLogConfig {
/*
NONE,不记录
BASIC,记录基本的请求行,响应状态码数据
HEADERS,记录基本的请求行,响应状态码数据,记录响应头信息
FULL;记录完成的请求 响应数据
*/
@Bean
public Logger.Level level(){
return Logger.Level.FULL;
}
}
3.启用该Bean:
GoodsFeignClient
@FeignClient(value = "FEIGN-PROVIDER",configuration = FeignLogConfig.class)