菜单
本页目录

OpenFeign服务接口调用

OpenFeign概述

1. LoadBalancer和OpenFeign的区别

LoadBalancer 和 OpenFeign 都是用于微服务架构中的不同工具,但它们的作用和使用场景不同。

  • LoadBalancer:主要用于在多个服务实例之间分配请求,以实现负载均衡。它负责将请求分发到不同的服务实例,从而提高服务的可用性和性能。

  • OpenFeign:是一个声明式的 HTTP 客户端,主要用于服务之间的通信。OpenFeign 允许你通过简单的注解方式定义服务接口,而不需要自己编写复杂的 HTTP 客户端代码。OpenFeign 可以与 LoadBalancer(客户端负载均衡器)结合使用,提供客户端侧的负载均衡功能。

为什么需要学习 OpenFeign? 即使你已经有了 LoadBalancer,用 OpenFeign 仍然有以下几个好处:

  • 简化服务调用:你不需要手动处理 HTTP 请求和响应,OpenFeign 会帮你自动处理这些细节。
  • 增强可读性和维护性:通过声明式的接口,代码更加直观,容易理解和维护。
  • 灵活性和扩展性:OpenFeign 可以轻松集成其他功能,比如日志记录、请求拦截等。

2. LoadBalancer和OpenFeign应该使用哪一个

如果你的微服务架构中需要频繁进行服务间通信,且希望代码更简洁和可维护,那么建议你日常使用 OpenFeign。LoadBalancer 可以与 OpenFeign 结合使用,帮助你实现客户端的负载均衡。

但如果你只关注于服务实例之间的负载均衡,而不涉及服务之间的复杂调用,LoadBalancer 可能已经足够。实际上,在大多数场景下,OpenFeign 和 LoadBalancer 是互补的,经常会一起使用

3. 什么是 OpenFeign?

OpenFeign 是一个声明式的 HTTP 客户端,主要用于简化微服务之间的调用。它允许你通过注解的方式定义服务接口,而不需要手动编写 HTTP 请求代码。

4. OpenFeign 能干什么?

OpenFeign 是一个功能强大的工具,能够在微服务架构中简化和增强服务间的通信。它的主要功能包括:

  • 可插拔的注解支持:OpenFeign 支持使用注解来定义服务接口,包括 Feign 注解和 JAX-RS 注解。这种方式使得定义 HTTP 请求变得更加直观和简洁,同时也支持通过插件扩展注解的功能。

  • 支持可插拔的 HTTP 编码器和解码器:OpenFeign 允许你自定义和扩展 HTTP 请求和响应的编码器和解码器。这意味着你可以根据需要使用不同的数据格式(如 JSON、XML)或自定义的格式来传递数据。

  • 支持 Sentinel 和它的 Fallback:OpenFeign 可以与 Alibaba 的 Sentinel 集成,用于实现服务的熔断、限流和降级功能。当某个服务出现问题时,Sentinel 能够自动调用定义好的 Fallback 方法,从而保证系统的稳定性。

  • 支持 Spring Cloud LoadBalancer 的负载均衡:OpenFeign 可以与 Spring Cloud LoadBalancer 结合使用,实现客户端的负载均衡。通过这种方式,OpenFeign 可以在多个服务实例之间自动分配请求,从而提高系统的可用性和响应速度。

  • 支持 HTTP 请求和响应的压缩:OpenFeign 还支持对 HTTP 请求和响应进行压缩处理,减少网络传输的数据量,提高传输效率。这对于大型数据传输场景特别有用。

OpenFeign基本用法

在启动类中加入@EnableFeignClients注解

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@EnableDiscoveryClient //该注解用于向使用consul为注册中心时注册服务
@EnableFeignClients(basePackages = "com.cluod.stores.api")//该注解用于构建OpenFeign
//(basePackages = "com.cluod.stores.api")是指定OpenFeign服务端包在哪里
public class SpringApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringApplication.class, args);
    }
}

编写服务者代码ProviderController

import com.cluod.commons.resp.ResultData;//编写的返回封装类
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Tag(name = "服务端", description = "模仿服务提供者")
public class ProviderController {

    @GetMapping("provider/store/get/{num}")
    public ResultData<String> getStore(@PathVariable("num") Integer num) {
        return ResultData.success("provider store get " + num);
    }

}

编写StoreClient服务接口

  1. 注意接口中的api应该与ProviderController中的方法参数完全一样
     import com.cluod.commons.resp.ResultData;
     import org.springframework.cloud.openfeign.FeignClient;
     import org.springframework.web.bind.annotation.GetMapping;
     import org.springframework.web.bind.annotation.PathVariable;
    
     // 服务提供者的在consul(服务注册中心)中的名称
     @FeignClient(value = "cloud-payment-service")
     public interface StoreClient {
    
         @GetMapping("provider/store/get/{num}")
         public ResultData getStore(@PathVariable("num") Integer num);
    
     }
    

编写ConsumerController消费者

import com.cluod.stores.api.StoreClient;
import com.cluod.commons.resp.ResultData;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Tag(name = "消费端", description = "模仿消费者")
public class ConsumerController {
   
   @Resource
   private StoreClient storeClient;

   @GetMapping("consumer/store/get/{num}")
   private ResultData<String> getStore(@PathVariable("num") Integer num) {
       return storeClient.getStore(num);
   }
}

服务调用流程

  1. 用户在调用ConsumerController的getStore()方法的时候,OpenFeign服务调用接口storeClient会根据@FeignClient()内的服务名称或者ip去调用对应服务上的API,以实现微服务实例之间的调用。 dff70e6908143c75f25e8f335fbd1cb.png