一、远程调用是什么?
是指在微服务架构中,不同的微服务之间通过网络进行通信和调用。可以帮助实现微服务之间的协作和交互,使得系统更加灵活和可扩展。
二、什么是Feign?
Feign是Netflix公司提供服务调用组件,单独使用Feign比较麻烦。SpringCloud对Feign做了集成封装,提供了声明式服务调用组件Open-Feign。
Open-Feign支持SpringMVC注解。是Spring Cloud提供的一个声明式的伪Http客户端,它使得调用远程服务就像调用本地服务一样简单,只需要创建一个接口并添加一个注解即可。
Feign默认集成了Ribbon,所以使用Feign默认就具备负载均衡的效果。
三、Feign入门
1. 使用步骤
Feign要在调用者一方配置
- 导入openfeign的起步依赖
- 创建Feign的Client接口
- 编写feign接口是一定要提前明确
- 期望feign帮我们发送什么请求
- 期望feign帮我们把响应结果转化成什么对象
- 在引导类上添加@EnableFeignClients("Client接口所在的包名")
- 使用Client进行远程调用
2. 示例
添加依赖
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
创建Feign客户端
创建一个UserClient接口,用于配置Feign调用user-service的功能
要求:
- 在接口上添加注解
@FeignClient("要调用的服务名")
- 接口里要有方法
- 每个方法对应一个请求接口
- 在方法上添加注解,设置方法的路径
java
@FeignClient("user-service")
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
在引导类上添加@EnableFeignClients
java
@EnableDiscoveryClient
@SpringBootApplication
@MapperScan("com.sdf.order.mapper")
@EnableFeignClients("com.sdf.order.client")//启用Feign支持
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
使用UserClient调用用户服务
java
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private UserClient userClient;
public Order findById(Long id){
Order order = orderMapper.selectById(id);
//使用UserClient调用用户服务
User user = userClient.findById(order.getUserId());
order.setUser(user);
return order;
}
}
四、Feign原理
Feign帮我们生成的接口代理对象(注入进来的代理对象),在代理对象里边Feign帮我们做了两件事:
-
构造HTTP请求并发出去
请求方式:创建Client接口方法上的请求方式
请求路径:http://目标服务名/资源路径
-
获取HTTP响应并转换返回给调用者
得到HTTP响应,根据Client接口方法的返回值类型,将响应结果转换成返回值类型,在返回给调用
图示:
五、Feign配置Ribbon
Feign已经集成了Ribbon,用法参考负载均衡
不做任何配置:也有负载均衡效果。默认的负载均衡策略是:轮询
如果要修改负载均衡策略:
- 方式1:修改消费者的配置文件,设置负载均衡策略
- 方式2:使用@Bean把负载均衡策略对象放到IoC容器里
如果要实现饥饿加载:修改配置文件,开启饥饿加载,并设置哪些服务需要饥饿加载
六、Feign配置日志
1. 使用步骤
修改配置文件,设置整体文件的日志级别
创建Feign配置类,注册Logger.Level用于设置Feign的日志级别
支持四种日志级别
- NONE:不输出任何日志,是默认值
- BASIC:仅输出请求的方式、URL以及响应状态码、执行时间
- HEADERS:在BASIC基础上,额外输出请求头和响应头信息
- FULL:输出所有请求和响应的明细,包括头信息、请求体、元数据
2. 示例
设置整体的日志级别
yaml
logging:
level:
com.sdf: debug
配置Feign的日志文件级别
方式一:@Bean方式(不推荐)
单独为Feign配置一个日志类,设置日志级别
java
@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLog(){
return Logger.Level.FULL;
}
}
方式二、配置文件方式(推荐)
修改配置文件application.yaml,添加如下配置:
yaml
feign:
client:
config:
default:
loggerLevel: FULL
七、Feign使用优化
Feign底层发起http请求,依赖于其它的框架。其底层客户端实现包括:
-
URLConnection:默认实现,不支持连接池,性能低(每次请求都需要建立连接,得到响应在断开连接)
-
Apache HttpClient :支持连接池
-
OKHttp:支持连接池
因此提高Feign的性能主要手段就是使用连接池代替默认的URLConnection。
1. 使用步骤
使用Apache HttpClient 的步骤:
- 添加httpclient的依赖坐标
- 配置httpclient连接池
2. 示例
添加httpclient的依赖坐标
xml
<!--httpClient的依赖 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
配置httpclient连接池
yml
feign:
httpclient:
enabled: true # 开启feign对HttpClient的支持,默认是true
max-connections: 200 # 最大的连接数,默认200
max-connections-per-route: 50 # 每个路径的最大连接数,默认50
测试效果
在FeignClientFactoryBean中的loadBalance方法中打断点:
Debug方式重启服务,可以看到这里的client,底层就是Apache HttpClient: