OpenFeign服务接口调用
OpenFeign概念
1、概念
OpenFeign为微服务架构下服务之间的调用提供了解决方案,OpenFeign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用OpenFeign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问HTTP请求。让编写web服务客户端变得非常容易,只需创建一个接口并在接口上添加注解即可。
2、 OpenFeign的作用
OpenFeign旨在使编写 Java Http 客户端变得更容易。前面使用Ribbon+RestTemplate时,利用RestTemplate对Http请求的封装处理,形成了一套模板化的调用方法。
但是在实际的开发中,由于对服务依赖的调用不止一处,往往一个接口会被多出调用,所以通常会正对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。
所以,OpenFeign在此基础上做了进一步封装,由它来帮助我们定义和实现依赖服务接口的定义。在OpenFeign的实现下,我们只需要创建一个接口并使用注解的方式来配置它(以前是Dao接口上标注 @Mapper 注解,现在是一个微服务接口上标注一个OpenFeign接口即可)
。即完成对服务提供方的接口绑定,简化了使用SpringCloud Ribbon时,自动封装服务调用客户端的开发量。
OpenFeign集成了Ribbon
:利用Ribbon维护了微服务列表信息,并且通过轮询实现了客户端负载均衡,而与Ribbon不同的是,通过OpenFeign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现服务调用。
3、Feign 与 OpenFeign的区别
Feign | OpenFeign |
---|---|
Feign是Spring Cloud组件中一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign的使用方式是:使用Feign的注解定义接口,调用接口,就可以调用服务注册中心的服务。 | OpenFeign是Spring Cloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中 |
OpenFeign的配置使用
1、引入pom依赖
<!--openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、写yml配置文件
server:
port: 80
spring:
application:
name: cloud-openfeign-order-service
eureka:
client:
#是否将自己注册到注册中心, 默认true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,单机无所谓,集群必须设置为true配合ribbon使用负载均衡
fetch-registry: true
service-url:
# defaultZone: http://localhost:7001/eureka #单机版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #集群版
instance:
instance-id: openfeign-order80
#访问路径可以显示IP地址
prefer-ip-address: true
#eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认为30秒)
lease-renewal-interval-in-seconds: 1
#eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认为90秒),超时将删除服务
lease-expiration-duration-in-seconds: 2
#设置feign客户端超时时间(OpenFeign 默认支持ribbon)
ribbon:
#指的是建立连接所用时间,适用于网络状况正常情况下,两端连接所用时间
ReadTimeout: 5000
#指的是连接建立后,从服务器获取到可用资源所用时间
ConnectTimeout: 5000
#feign 日志以什么级别监控那个接口
logging:
level:
com.atguigu.springcloud.service: debug
3、主启动类
@SpringBootApplication
@EnableFeignClients
public class OpenFeignOrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OpenFeignOrderMain80.class, args);
}
}
4、业务类
(1)service 远程调用接口
/*
接口:面向接口编程。把需要调用的远程接口封装到接口中(映射地址为远程接口的地址)
*/
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {
/* OpenFeign下接口即完成如下操作:
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPayment(@PathVariable("id") Long id) {
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
URI uri = loadBalancer.instances().getUri();
return restTemplate.getForObject(uri + "/payment/get/" + id, CommonResult.class);
}
*/
@GetMapping(value = "/payment/get/{id}")
CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
}
(2)controller
@RestController
@Slf4j
public class OrderFeignController {
@Resource
private PaymentFeignService paymentFeignService;
@GetMapping(value = "/consumer/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
return paymentFeignService.getPaymentById(id);
}
}
OpenFeign超时控制
1、yml 文件配置超时控制
#设置feign客户端超时时间(OpenFeign 默认支持ribbon)
ribbon:
#指的是建立连接所用时间,适用于网络状况正常情况下,两端连接所用时间
ReadTimeout: 5000
#指的是连接建立后,从服务器获取到可用资源所用时间
ConnectTimeout: 5000
2、测试
(1)服务提供者
//openfeign超时控制测试
@GetMapping(value = "payment/openfeign/timeout")
public CommonResult timeout() {
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new CommonResult(200, "success", "openfeign超时控制测试");
}
(2)服务消费者
A、客户端controller
@RestController
@Slf4j
public class OrderFeignController {
@Resource
private PaymentFeignService paymentFeignService;
@GetMapping(value = "/consumer/payment/timeout")
public CommonResult<Payment> timeout() {
return paymentFeignService.timeout();
}
}
B、客户端service远程调用接口
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {
@GetMapping(value = "/payment/openfeign/timeout")
CommonResult<Payment> timeout();
}
测试结果:
OpenFeign日志打印功能
1、配置类
@Configuration
public class OpenFeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
2、yml配置
# openfeign 日志以什么级别监控那个接口
logging:
level:
com.atguigu.springcloud.service: debug
调用结果: