前面消费者对于微服务的消费是通过 RestTemplate 完成的,这种方式的弊端是很明显的:消费者对提供者的调用无法与业务接口完全吻合。 例如,原本Service 接口中的方法是有返回值的,但经过 RestTemplate 相关API调用后没有了其返回值,最终执行是否成功用户并不清楚。 再例如 RestTemplate 的对数据的删除与修改操作方法都没有返回值。 代码编写不方便,不直观。提供者原本是按照业务接口提供服务的,而经过 RestTemplate一转手,变为了 URL,使得程序员在编写消费者对提供者的调用代码时,变得不直接、不明了。没有直接通过业务接口调用方便、清晰。
OpenFeign 具有负载均衡功能,其可以对指定的微服务采用负载均衡方式进行消费、访问。之前老版本 Springcloud 所集成的 OpenFeign 默认采用了 Ribbon 负载均衡器。但由于Netflix 已不再维护 Ribbon,所以从 Springcloud2021.x开始集成的 OpenFeign 中已彻底丢弃Ribbon,而是采用 SpringCloud 自行研发的 SpringCloud Loadbalancer 作为负载均衡器
<!--openfegin依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
/**
* ProjectName: springcloudalibaba
* ClassName: DepartService
* Package: com.cheese.service
* Description: openFegin 伪客户端接口
* Datetime: 2024-07-23 1:12
* Author: LJZ
*/
@FeignClient(value = "depart-provider", path = "/provider/depart") //微服务名称,uri
public interface DepartService {
/**
* 接口名,注解路径,所有方法名与provider-server 中的接口一致
* @param depart
* @return
*/
//新增
@PostMapping("/save")
Boolean addDepart(@RequestBody DepartEntity depart);
//修改
@PutMapping("/update")
Boolean updateDepart(@RequestBody DepartEntity depart);
//删除
@DeleteMapping("/del/{id}")
Boolean deleteDepartById(@PathVariable Integer id);
//查询
@GetMapping("/get/{id}")
DepartEntity getDepartById(@PathVariable Integer id);
//列表
@GetMapping("/list")
List<DepartEntity> getAllDepart();
}
//SpringCloud2021.x前后版本的openfegin使用差异
//旧版本
@FeignClient(value = "depart-provider", path = "/provider/depart") //微服务名称,uri
或是
@FeignClient(value = "depart-provider") //微服务名称,uri
@RequestMapping("/provider/depart")
//两种方式均可
//-----------------------------------------
//新版本只能使用第一种方式进行注解配置
@Resource
private DepartService departService;
//新增
@PostMapping("/")
public Boolean addDepart(@RequestBody DepartEntity depart) {
return departService.addDepart(depart);
}
//修改
@PutMapping("/")
public Boolean modifyDepart(@RequestBody DepartEntity depart) {
return departService.updateDepart(depart);
}
//删除
@DeleteMapping("/{id}")
public Boolean deleteDepart(@PathVariable Integer id) {
return departService.deleteDepartById(id);
}
//查询
@GetMapping("/{id}")
public DepartEntity getDepart(@PathVariable Integer id) {
return departService.getDepartById(id);
}
//列表
@GetMapping("/list")
public List<DepartEntity> getDepartList() {
return departService.getAllDepart();
}
@EnableFeignClients //开启OpenFeginClient
spring:
cloud:
# OpenFegin 超时配置
openfeign:
client:
config:
default: #全局设置
#consumer与provider建立连接的超时时间<==取决于网络因素
connect-timeout: 1
#建立连接后的读取时间,consumer发出请求到provider的响应这段时间的阈值<==取决于provider的业务逻辑
read-timeout: 1
depart-provider: #指定微服务设置,优先于全局设置,feginName即,@FeginClient注解value的值
connect-timeout: 1
read-timeout: 2
spring:
cloud:
#对请求响应的压缩设置
compression:
request:
#开启压缩配置
enabled: true
#指定类型
mime-types: ["text/xml", "application/xml", "application/json","video/mp4"]
#最小请求大小,默认值2048
min-request-size: 1024
response:
enabled: true
spring-cloud-starter-loadbalancer
依赖,如果不引入依赖也能够使用默认的 feginclient,但是就不会有负载均衡的功能<!--nacos2.2.0.1往后版本的客户端负载均衡依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
DepartConfig.java
,用于配置负载均衡策略/**
* ProjectName: springcloudalibaba
* ClassName: DepartConfig
* Package: com.cheese.config
* Description: 用于修改负载均衡策略
* Datetime: 2024-07-30 1:21
* Author: LJZ
*/
public class DepartConfig {
@Bean
public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory factory) {
//获取负载均衡客户端名称,即提供者服务名称
String serverName = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
//获取提供者微服务名称可用的实例列表
ObjectProvider<ServiceInstanceListSupplier> lazyProvider = factory.getLazyProvider(serverName, ServiceInstanceListSupplier.class);
//从集合lazyProvider中获取指定serverName的实例,随机做负载均衡
return new RandomLoadBalancer(lazyProvider, serverName);
}
}
@Configuration
注解,在启动类中需添加@LoadBalancerClients(defaultConfiguration = DepartConfig.class)
spring-cloud-loadbalancer 存在以下弊端
dubbo
,此外还有 gRPC
等