1、项目中接口的调用方式
1.1 HttpClient
- HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 Http 协议的客户端编程工具包,并且它支持 HTTP 协议最新版本和建议。HttpClient 相比传统 JDK 自带的 URLConnection,提升了易用性和灵活性,使客户端发送 HTTP 请求变得容易,提高了开发的效率。
1.2 OkHttp
- 一个处理网络请求的开源项目,是安卓端最火的轻量级框架,由 Square 公司贡献,用于替代 HttpUrlConnection 和 Apache HttpClient。OkHttp 拥有简洁的 API、高效的性能,并支持多种协议(HTTP/2 和 SPDY)。
1.3 HttpURLConnection
- HttpURLConnection 是 Java 的标准类,它继承自 URLConnection,可用于向指定网站发送 GET 请求、POST 请求。HttpURLConnection 使用比较复杂,不像 HttpClient 那样容易使用。
1.4 RestTemplate
- RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程 HTTP 服务的方法,能够大大提高客户端的编写效率。
1.5 WebClient
- WebClient 是 Spring WebFlux 模块提供的一个非阻塞的基于响应式编程的进行 Http 请求的客户端工具。
- WebFlux 对标 SpringMvc,WebClient 相当于 RestTemplate,同时也是 Spring 官方的 Http 请求工具。
- 与RestTemplate相比,WebClient的优势:
- 非阻塞响应式IO,单位时间内有限资源下支持更高的并发量。
- 支持使用Java8 Lambda表达式函数。
- 支持同步、异步、Stream流式传输。
以上是最常见的几种调用接口的方式,下面介绍比上面更简单方便的方式---- Feign
2、什么是Feign
- Feign是Netflix开发的声明式、模板化的HTTP客户端,其灵感来自Retrofit、JAXRS-2.0以及WebSocket。Feign可帮助我们更加便捷、优雅地调用HTTP API。
- Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。
2.1 Feign的优势
- Feign可以做到使用 HTTP 请求远程服务时就像调用本地方法一样的体验,开发者完全感知不到这是远程方法,更感知不到这是个 HTTP 请求。
- 它像 Dubbo 一样,consumer 直接调用接口方法调用 provider,而不需要通过常规的 Http Client 构造请求再解析返回数据。它解决了让开发者调用远程接口就跟调用本地方法一样,无需关注与远程的交互细节,更无需关注分布式环境开发。
3、快速整合OpenFeign
3.1 导入依赖
<!--OpenFeign 远程调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
3.2 编写调用接口
@FeignClient
:指定远程调用的服务和方法/** * name:指定调用的Rest接口的服务名 * path:指定调用的Rest接口的请求路径,即:StockController指定的@RequestMapping中的路径 * configuration:指定配置类 */ @FeignClient(name = "StockService",path = "/stock/stockapi",configuration = FeignConfig.class) public interface StockFeignService { //声明需要调用的Rest接口对应的方法 @RequestMapping("/handle") String getStock(); }
3.3 在启动类中开启远程调用的功能
@EnableFeignClients
:开启远程调用@SpringBootApplication @EnableFeignClients //这里设置要为哪个服务提供方选用指定的负载均衡的规则 @RibbonClients(value = { @RibbonClient(name = "StockService", configuration = RibbonConfig.class) }) public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } }
3.4 发起调用
- 像调用本地方法一样调用远程服务
@RestController @RequestMapping("/orderapi") public class OrderController { @Autowired private StockFeignService stockFeignService; @RequestMapping("/add") public String addOrder(){ System.out.println("OpenFeign方式调用:下单成功"); String stock = stockFeignService.getStock(); return "下单成功:"+ stock; } }
4、Feign的自定义配置和使用
- Feign 提供了很多的扩展机制,让用户可以更加灵活的使用。
4.1 日志配置
- 有时候我们遇到 Bug,比如接口调用失败、参数没收到等问题,或者想看看调用性能,就需要配置 Feign 的日志了,以此让 Feign 把请求信息输出来。
- Feign的日志级别:
NONE
【性能最佳,适用于生产】:不记录任何日志(默认值)。BASIC
【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间。HEADERS
:记录BASIC级别的基础上,记录请求和响应的header。FULL
【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。
4.1.1 通过配置类的方式进行配置
- 编写配置类:
/** * 全局配置:如果使用了@Configuration注解,将会对所有的服务提供方都执行该配置 * 局部配置: * 1、如果想针对某一个服务进行配置,就不要加@Configuration注解 * 2、通过配置文件进行配置 */ @Configuration public class FeignConfig { /** * 设置feign的日志级别 * @return */ @Bean public Logger.Level feignLoggerLevel(){ return Logger.Level.BASIC; } }
- 让调用的服务使用指定的Feign配置
- 修改yml配置文件中(默认是info)的日志级别,因为feign的日志级别是debug。
# SpringBoot默认的日志级别是info,feign的日志级别是debug logging: level: root: info com.example.order.feign: debug # 设置feign服务所在包下的日志级别
4.1.2 在配置文件中进行配置
- 对应属性配置类: org.springframework.cloud.openfeign.FeignClientProperties.FeignClientConfiguration
# Feign日志局部配置 feign: client: config: StockService: # 对应的服务名称 loggerLevel: FULL # 设置日志级别
4.2 超时配置
- 配置类
@Configuration
public class FeignConfig {
/**
* 设置feign请求超时时间
* @return
*/
@Bean
public Request.Options options(){
return new Request.Options(5000, 5000);
}
- 配置文件
feign:
client:
config:
StockService: # 对应的服务名称
loggerLevel: FULL # 设置日志级别
connect-timeout: 5000 # 设置连接超时时间 默认2000(2秒)
read-timeout: 3000 # 设置读取超时时间 默认5秒
4.3 自定义拦截器
- 自定义拦截器实现认证逻辑(只有请求拦截,没有响应拦截)
public class FeignInterceptor implements RequestInterceptor {
Logger logger = LoggerFactory.getLogger(FeignInterceptor.class);
@Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.header("token","123456789");
requestTemplate.query("id","111");
logger.info("feign拦截器");
}
}
- 在配置类中进行配置
@Configuration
public class FeignConfig {
/**
* 自定义拦截器
* @return
*/
@Bean
public FeignInterceptor feignInterceptor(){
return new FeignInterceptor();
}
- 在配置文件中进行配置
feign:
client:
config:
StockService: # 对应的服务名称
requestInterceptors[0]: #拦截器配置
com.example.order.interceptor.FeignInterceptor