服务调用——OpenFeign
1、概述
1. OpenFeign是什么?
Feign是一个声明式的WebService客户端,使用Feign能让编写WebService客户端更加简单。
它的使用方法是在客户端定义一个服务接口然后在上面添加注解。Feign也支持可拔插式的编码器和解码器。
SpringCloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters。
Feign也是运行在消费者端的,使用 Ribbon 进行负载均衡,所以 OpenFeign 直接集成了 Ribbon。
2. Feign能做什么?
Feign旨在使编写Java Http客户端变得更容易。之前我们使用Eureka + Ribbon + RestTemplate时,利用RestTemplate对Http请求的封装处理,形成了一套模板化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign在此基础上做了进一步封装,由它来帮助定义和实现依赖服务接口的定义。在Feign的实现下,只需要创建一个接口并使用注解的方式来配置它,即可完成对服务提供方的接口绑定,简化了使用SpringCloud Ribbon时,自动封装服务调用客户端的开发量。
Feign集成了Ribbon:利用Ribbon维护服务提供方的服务列表信息,并且通过如轮询的算法实现了客户端的负载均衡。而与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以声明式的方式,优雅而简单的实现了服务调用。
3. Feign和OpenFeign的区别
| Feign | OpenFeign | |
|---|---|---|
| 特点 | Feign是SpringCloud组件中的一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端的负载均衡,去调用服务注册中心的服务。Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务。 | OpenFeign是SpringCloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping 等。OpenFeign的 @FeignClient 可以解析SpringMVC的 @RequestMapping 注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。 |
| 启动器 | spring-cloud-starter-feign | spring-cloud-starter-openfeign |
Feign已经停止维护,所以我们只需要关注OpenFeign的使用即可,我们现在学习的就是利用OpenFeign实现我们之前用的Ribbon+RestTemplate实现的功能。
2、 OpenFeign使用步骤
1. 服务消费者端的POM文件添加依赖
<!--openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
在POM中我们引入了OpenFeign的依赖以及Eureka客户端的依赖。
3. 写配置文件YAML
server:
port: 80
eureka:
client:
register-with-eureka: false # 客户端就不注册入服务注册中心了
fetch-registry: true #从EurekaServer中检索服务提供者
service-url:
defaultZone: http://eureka7002.com:7002/eureka/
由于80为服务消费方,只是调用服务提供方的服务,所以可以不讲自己注册到服务注册中心。
4. 主启动类:
package org.jun;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author junfeng.lin
* @date 2021/2/18 2:00
*/
@SpringBootApplication
@EnableFeignClients //激活feign功能
public class OpenFeignClient {
public static void main(String[] args) {
SpringApplication.run(OpenFeignClient.class,args);
}
}
注意主启动类上需要添加 @EnableFeignClients 注解,这个注解声明80服务可以使用Feign来实现服务接口的调用。
5. 服务消费端业务类:
在服务消费方中编写如下的接口即可对服务提供方的服务进行调用:
package org.jun.Feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @author junfeng.lin
* @date 2021/2/18 2:05
*/
@Component
@FeignClient("EUREKA-ORDER")
public interface MyFeign {
@GetMapping("/getPort")
public String getPort();
}
@FeignClient 注解中的value值为要调用的服务名称,也就是8001/8002服务提供方注册到Eureka注册中心的服务名,这个注解就是告诉该接口调用哪个服务,而OpenFeign默认会使用轮询的负载均衡算法来调用具体的服务实例,在这个接口中我们需要使用服务提供方服务的哪个具体方法,将该方法作为接口方法写入接口中即可。
然后编写80服务消费方的Controller:
package org.jun.Controller;
import org.jun.Feign.MyFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author junfeng.lin
* @date 2021/2/18 2:01
*/
@RestController
public class MyController {
@Autowired
private MyFeign myFeign;
/**
* 服务提供方8001和8002中的服务
* 根据id查询订单
* @return
*/
@GetMapping("/getPort")
public String getPort() {
String port = myFeign.getPort();
return port;
}
@GetMapping("testTimeOut")
public String testTimeOut() {
return myFeign.testTimeOut();
}
}
6.测试效果
我们先启动Eureka的集群注册中心7002,然后启动服务提供方8001/8002,再启动服务消费方80,访问http://localhost/getPort,我们可以发现OpenFeign使用轮训的负载均衡算法实现了服务提供方服务接口的调用:


7. 总结:

简言之就是,客户端的服务接口使用用 @FeignClient 注解根据服务名称去调用服务提供方的具体服务。
3、OpenFeign的超时控制
1、OpenFeign默认等待服务提供方1秒钟,超过则报错

2、修改yaml文件配置信息
server:
port: 80
spring:
application:
name: openfeignConsume
# eureka客户端的实例名称(服务消费者)
eureka:
instance:
hostname: localhost
client:
# 客户端就不注册入服务注册中心了
register-with-eureka: false
# 从EurekaServer中检索服务提供者
fetch-registry: true
service-url:
# 设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://eureka7002.com:7002/eureka
# 设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
# 指的是建立连接所用的时间,适用于网络状态正常的情况下,两端连接所用的时间(单位为ms)
ReadTimeout: 5000
# 指的是建立连接后从服务器读取到可用资源所用的时间(单位为ms)
ConnectTimeout: 5000
3、测试效果

4、openFeign的日志功能
1、编写配置类
package org.jun.Config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author junfeng.lin
* @date 2021/2/18 15:28
*/
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
2、修改yaml文件配置信息
logging:
level:
# 以什么日志级别监控哪个接口
org.jun.Feign.MyFeign: debug
3、测试效果
访问了http://localhost/testTimeOut后,在控制台中出现如下日志信息

5、Openfeign中传输文件
1、使用Post请求
2、在feign中设置参数
@RequestMapping(value = "/db/importUserGroup",produces = MediaType.APPLICATION_JSON_VALUE,
consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<?> importUserGroup(@RequestPart("file") MultipartFile file);
1131

被折叠的 条评论
为什么被折叠?



