0.Feign的介绍
开发微服务,免不了需要服务间调用。Spring Cloud框架提供了RestTemplate和FeignClient两个方式完成服务间调用,之前一直是使用restTemplate+Ribbon负载均衡进行服务调用。使用Feign之后,可以简化web服务的调用,可以在接口上加入注解,即可使用服务
什么是OpenFeign?
OpenFeign就是SpringCloud对Feign的基础上添加了对Spring MVC的注解支持
1.依赖导入
<!--OpenFeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
2.OpenFeign的使用
①首先需要在主启动类上加入@EnableFeignClients
注解开启feign客户端
@SpringBootApplication
@EnableFeignClients
public class CloudConsumerFeignOrder9011Application {
public static void main(String[] args) {
SpringApplication.run(CloudConsumerFeignOrder9011Application.class, args);
}
}
②新建一个接口,里面包含需要调用的方法,并需要加入@FeignClient
注解并配合上SpringMVC的注解使用
下面是提供者的接口:
@GetMapping("/payment/get/{id}")
public CommonResult<Payment> getPayment(@PathVariable Long id){
Payment payment = paymentService.getPaymentById(id);
log.info("---------查询到结果:{}-----------,serverPort:{}",payment,serverPort);
if (payment!=null){
return new CommonResult<>(200,"success,serverPort:"+serverPort,payment);
}else {
return new CommonResult<>(400,"failed,serverPort:"+serverPort);
}
}
下面是我们消费者新创建的接口
@FeignClient
注解需要指定要远程调用的服务ID,然后在需要的方法上面需要加入跟提供者的接口一样的地址,这个地方的@PathVariable
注解必须写明id,不能省略
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface FeignService {
@GetMapping("/payment/get/{id}")
public CommonResult<Payment> getPayment(@PathVariable("id") Long id);
}
③写一个控制器进行测试
@RestController
@Slf4j
@RequestMapping("/consumer/payment")
public class OrderController {
/** 注入feign接口 */
@Autowired
FeignService feignService;
@GetMapping("/get/{id}")
public CommonResult<Payment> getPayment(@PathVariable Long id){
return feignService.getPayment(id);
}
}
开启项目后,进行测试
第一次:
第二次:
可以看到,虽然没有注明@LoadBalanced,但是feign默认自带的有负载均衡
3.OpenFeign的超时控制
什么是超时控制?
OpenFeign默认会等待获取服务1秒钟,如果超过这个时间,则会直接报错,这个时间可以在配合文件中设置。
进行测试
①在提供者服务添加一个会超时的方法
这里会休眠3秒
/** 测试超时控制 */
@GetMapping("/feign/timeout")
public String feignTimeout(){
try {
Thread.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return serverPort;
}
②编写feign的接口,并创建一个控制器方法进行测试
feign的接口类:
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface FeignService {
@GetMapping("/payment/get/{id}")
public CommonResult<Payment> getPayment(@PathVariable("id") Long id);
@GetMapping("/payment/feign/timeout")
public String feignTimeout();
}
控制器方法:
@GetMapping("/timeout")
public String feignTimeout(){
return feignService.feignTimeout();
}
③开启项目测试
可以看到,超时直接报错
④修改默认的超时控制时间
在消费者的yml配置文件中添加超时时间配置
#设置feign客户端的超时时间,OpenFeign默认支持ribbon
ribbon:
#指的是建立连接后,获取到对应的服务,超时条件的时间
ReadTimeout: 5000
#指两端建立连接,超时条件的时间
ConnectTimeout: 5000
修改完成后,重新启动,再次进行测试,查看是否继续报错。
等了3秒钟后,返回了结果,说明配置生效,并没有达到超时所需的时间。
4.OpenFeign的日志打印功能
Feign提供了日志打印功能,可以通过配置来调整日志级别,从而了解Feign中HTTP请求的细节,说白了就是对Feign接口的调用情况进行监控和输出
以下是4种级别
- NONE 默认的,不显示任何日志
- BASIC 仅记录请求方法、URL、响应状态码和执行时间
- HEADERS 包括BASIC中的信息,并额外显示请求头和响应头的信息
- FULL 包括HEADERS中的信息,并额外显示请求和响应的正文和元数据
如何配置Feign的日志级别?
①新建一个配置类,然后写一个返回level类型的方法,返回需要的日志级别,并注册到容器中。注意,这个level类是feign包下的logger下的level
@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLevel(){
return Logger.Level.BASIC;
}
}
②在项目的yml配置文件中,开启日志
logging:
level:
#设置feign日志以什么级别监视什么服务,这个服务是feign接口的全路径名
com.hht.cloud.service.FeignService: debug
③重新启动项目,进行测试
随便调用一个接口后,控制台打印出了相关日志