1. Java项目中如何实现接口调用?
- HttpClient:相较于传统JDK自带的URLConnection,提升了易用性和灵活性,使客户端发送Http请求变得更容易;
- Okhttp:一个处理网络请求的开源项目,是安卓端最火的轻量级框架;
- HttpURLConnection:Java的标准类,继承自URLConnection,可用于向指定网站发送GET、POST请求,使用复杂;
- RestTemplate:Spring提供的用于访问Rest服务的客户端,提供了多种访问Http服务的方法,大大提高开发效率。
2. 什么是Feign?
Feign是Netflix开发的声明式、模板化的 **Http客户端** ,可以帮助我们更加便捷、优雅的调用Http Api。
SpringCloud OpenFeign对Feign进行了增强,使其支持SpringMVC注解,另外还整合了Ribbon和Nacos,从而使得Feign的使用更加方便。
优势:
Feign可以做到使用Http请求远程服务时就像调用本地方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这是个Http请求。它像Dubbo一样consumer直接调用接口方法调用provider而不需要通过常规的HttpClient构造请求再解析返回数据。它解决了让开发者调用远程接口就跟调用本地方法一样,无需关注与远程的交互细节,更无需关注分布式环境开发。
3. SpringCloud Alibaba快速整合OpenFeign
快速整合步骤:order服务调用stock服务
- 引入依赖:
<!--openfeign远程调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 编写调用接口:
@FeignClient(value = "stock-service", path = "/stock")
public interface StockFeignClient {
@PostMapping("/query")
String query(@RequestBody Object obj);
}
- 启动类上添加@EnableFeignClients注解:
@SpringBootApplication
@EnableFeignClients
public class OrderApp {
public static void main(String[] args) {
SpringApplication.run(OrderApp.class, args);
}
}
- 发起调用:
@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private StockFeignClient stockFeignClient;
@PostMapping("/query2")
public String query2(@RequestBody Object obj) {
log.debug("订单请求req2:{}", JSON.toJSON(obj));
return stockFeignClient.query(obj);
}
}
4. SpringCloud Feign的自定义配置及使用
Feign提供了很多的拓展机制,让用户可以更加灵活的使用。
4.1 日志配置
有时候我们遇到Bug,比如接口调用失败、参数没收到等问题,或者想看看调用性能,就需要配置Feign的日志了,以此让Feign把请求信息输出来。
全局配置方式:
@Configuration
public class FeignConfig {
// 此种配置将对所有调用的服务生效
@Bean
public Logger.Level logLevel() {
return Logger.Level.FULL;
}
}
Feign日志有4种级别,分别是:
- NONE【性能最佳,适用于生产】:不记录任何日志(默认值);
- BASIC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间;
- HEADERS:记录BASIC级别的基础上,记录请求和响应的header;
- FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。
局部配置方式:
# 日志级别
logging.level.com.balloon=debug
#feign日志级别-指定服务
feign.client.config.stock-service.logger-level=FULL
对应的配置类:org.springframework.cloud.openfeign.FeignClientProperties.FeignClientConfiguration
4.2 超时时间配置
通过Options可以配置连接超时时间和读取超时时间,Options的第一个参数是连接的超时时间(ms),默认值是10*1000ms,第二个是请求处理的超时时间(ms),默认值是60*1000ms。
全局配置方式:
@Bean
public Request.Options options() {
return new Request.Options(5000, 1000);
}
局部配置方式:
#feign超时配置-指定服务
feign.client.config.stock-service.connect-timeout=5000
feign.client.config.stock-service.read-timeout=1000
补充说明:Feign的底层用的是Ribbon,但超时时间以Feign配置为准!
4.3 客户端组件配置
Feign中默认使用JDK原生的URLConnection发送HTTP请求,我们可以集成别的组件来替换掉URLConnection,比如Apache HttpClient、OkHttp。 Feign发起调用真正执行逻辑:feign.Client#execute:
配置Apache HttpClient:
- 引入依赖:
<!--Apache HttpClient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.7</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>10.1.0</version>
</dependency>
- 修改配置,启用Feign的Apache HttpClient:
#feign使用Apache HttpClient(可以忽略,默认开启)
feign.httpclient.enabled=true
关于配置可参考源码:org.springframework.cloud.openfeign.FeignAutoConfiguration
测试:调用会进入feign.httpclient.ApacheHttpClient#execute
拓展学习:
- openFeign夺命连环9问,这谁受得了?(Feign也是一个狠角色,
Feign旨在使得Java Http客户端变得更容易;Feign集成了Ribbon、RestTemplate实现了负载均衡的执行Http调用;Feign = Ribbon(客户端负载均衡)+ RestTemplate(http调用)) - hystrix ,feign,ribbon的超时时间配置,以及原理分析(openFeign默认连接时间/超时时间为20s/60s,ribbon为1s/1s;取值逻辑:
都不配取ribbon默认的1s/1s,配了优先取openFeign) - 强强联合:OpenFeign 整合 Sentinel(
openFeign+sentinel实现服务降级) - Spring Cloud OpenFeign远程调用性能优化(
优化:超时时间+线程池管理http连接对象+传输数据压缩+负责均衡策略+日志级别)- 修改openFeign的超时时间,让openFeign能够正确的处理业务;
- 通过配置专用的通信组件Apache HttpClient 或 OKHttp ,让 OpenFeign 可以通过线程池更好地对 HTTP 连接对象进行重用和管理,以提高其性能;
- 开启数据压缩功能,可以提高宽带利用率和加速数据传输速度;
- 使用合适的负载均衡策略来替换默认的轮询负载均衡策略,已获得更好的执行效率;
- 检查生产环境中 openFeign 的日志级别,选择合适的日志输出级别,防止无效的日志输出。
- 微服务中远程调用Dubbo与Feign对比 (dubbo与feign都依赖注册中心、负载均衡;
dubbo性能高、支持多协议、默认的Dubbo协议:利用Netty,TCP传输,单一、异步、长连接,适合数据量小、高并发 和服务提供者远远少于消费者的场景) - Dubbo 、 OpenFegin 远程服务调用的使用区别
- 个人观点:dubbo使用体验更好:1)超时、重试配置一目了然 2)可直接引用服务提供方接口定义
- 今天就先到这里吧??? 生命不息 学习不止!!!
- 重学springboot系列番外篇之RestTemplate(
RestTemplate是一个用于发送HTTP请求的工具类,使用JDK自带的httpURLConnection作为底层http客户端实现)
迷之操作:
在实际生产中,发现openFeign的使用和上面学的demo有很大出入???
解答:openFeigin有两种使用方式:1.指定访问URL 2.不指定访问URL(配置的name值用于服务发现) 参见:# 那天晚上和@FeignClient注解的深度交流