一、OpenFeign介绍
声明式的REST客户端:Feign通过使用JAX-RS(Java Api eXtensions of RestFul web Services)或SpringMVC注解的修饰方式,生成接口的动态实现。Feign,假装,伪装。OpenFeign可以将(服务)提供者的Restful服务伪装为接口进行消费,消费者只需要使用“feign接口+注解”的方式即可直接调用提供者的RestFul服务。而无需在使用RestTemplate。
二、OpenFeign特点概括
1.OpenFeign只涉及Consumer,与Provider无关。因为其是用于Consumer调用Provider的。
2.OpenFeign 仅仅就是一个为客户端,其不会对请求做任何处理。
3.OpenFeign是通过注解的方式来实现RestFul请求的
三、OpenFeign与Ribbon
OpenFeign具有负载均衡的功能,其可以对指定的微服务采用负载均衡策略进行消费,访问。之前老版本的SpringCloud所继承的OpenFeign默认采用Bibbon做负载均衡。但由于Netflix公司已不再维护Ribbion,所以从SpringCloud2021.x开始集成OpenFeign中已经彻底丢弃的Ribbon,而是采用SpringCloud自行研发的SpringCloudLoaderblanced作为负载均衡。
四、OpenFeign的使用
1.导入依赖
<!-- openfeign依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.在consumer消费者工程里面写入对应提供者提供服务的接口
package com.abc.service;
import com.abc.bean.Depart;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
//添加微客服端FeignClient注解
@FeignClient(value = "depart-provider", path = "/provider/depart")//指定服务名称,老版的path路径可以用@RequestMapping注解指定,新版只能在这里面写path
public interface DepartService {
@PostMapping("/save")
boolean saveDepart(@RequestBody Depart depart);
@DeleteMapping("/delete/{id}")
boolean removeDepart(@PathVariable("id") Integer id);
@PutMapping("/update")
boolean modifyDepart(@RequestBody Depart depart);
@GetMapping("/get/{id}")
Depart getDepartById(@PathVariable("id") Integer id);
@GetMapping("/list")
List<Depart> getAllDeparts();
}
3.调用,在服务层里面定义一个接口对象,并通过伪客户端调用服务提供者提供的服务。
package com.abc.controller;
import com.abc.bean.Depart;
import com.abc.service.DepartService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.util.List;
/**
* @BelongsProject: SpringCloudAlibaba
* @BelongsPackage: com.abc.controller
* @Author: 王海鑫
* @CreateTime: 2024-01-05 16:56
* @Description: TODO
* @Version: 1.0
*/
@RestController
@RequestMapping("/consumer/depart")
public class DepartController {
@Autowired
private DepartService service;//再次添加我们刚才写的OpenFeign服务
//通过为客户端调用提供者的提供的服务
@PostMapping("/save")
public boolean saveDepart(@RequestBody Depart depart){
return service.saveDepart(depart);
}
@DeleteMapping("/delete/{id}")
public void deleteDepart(@PathVariable("id") Integer id){
service.removeDepart(id);
}
@PutMapping("/update")
public void updateDepart(@RequestBody Depart depart){
service.modifyDepart(depart);
}
@GetMapping("/get/{id}")
public Depart getDepart(@PathVariable("id") Integer id){
service.getDepartById(id);
}
@GetMapping("/list")
public List<Depart> list(){
return service.getAllDeparts();
}
}
4.在消费者启动类上面添加@EnableFeignClient注解,开启服务openfeign客户端
package com.abc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients // 开启Feign客户端
public class OpenFeignConsumer8080 {
public static void main(String[] args) {
SpringApplication.run(OpenFeignConsumer8080.class, args);
}
}
5.配置消费者和提供者的,要求两个要在同一个命名空间,这里用默认的。
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848 # nacos服务地址
username: nacos
password: nacos
6.打开浏览器,测试接口
好的,没问题,现在我们的OpenFeign就可以使用了。
五、OpenFeign的超时配置
在consumer项目的application.yml文件中配置。
spring:
openfeign:
client:
config:
default: #全局配置
# 连接超时:consumer端连接上服务端的超时时间,起决定作用的是网络状况
connect-timeout: 10000
# 读取超时:consumer端从服务端读取数据超时时间,起决定作用的是provider的业务逻辑
read-timeout: 10000
depart-provider: #局部配置
connect-timeout: 10000
read-timeout: 10000
六、对请求访问的压缩配置
compress:
request:
# 开启gzip压缩
enabled: true
# 压缩级别
compression-level: 6
# 压缩类型
mime-types: ["text/xml","application/xml","application/json","text/html"]
# 压缩最小字节数
minimum-input-size: 2048
response:
# 开启gzip压缩
enabled: true
七、选择远程调用的底层实现技术
1.理论基础
feign的远程调用底层实现的技术默认采用的是JDK的URLConnection,同时还支持HttpClient与OKHttp。
由于JDK的URLConnection不支持连接池,通信效率很低,所以生产中是不会使用默认实现的。所以在SpringCloud OpenFeign中直接将默认实现变为了HttpClient,同时也支持OKHttp。
用户可以根据自己业务选择合适的技术。
一般单例的用HttpClient,非单例用OkHttp。
八、负载均衡策略及替换
1.添加配置类
public class DepartConfig {
@Bean
public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment e, LoadBalancerClientFactory factory){
//获取负载均衡的客户端名称
String name = e.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
// 从所有provider实例中指定名称的实例列表随机选择一个实例
// 参数1: 获取指定名称的provider服务列表
// 参数2: 指定要获取的provider服务名称
return new RandomLoadBalancer(factory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);
}
}
2.在启动类上添加注解
@LoadBalancerClients(defaultConfiguration = DepartConfig.class)// 开启负载均衡,以负载均衡的方式访问远程服务
@SpringBootApplication
@EnableFeignClients // 开启Feign客户端
public class OpenFeignConsumer8080 {
public static void main(String[] args) {
SpringApplication.run(OpenFeignConsumer8080.class, args);
}
}