欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Cloud OpenFeign實現(xiàn)動態(tài)服務名調用的示例代碼

 更新時間:2025年06月06日 10:24:38   作者:要阿爾卑斯嗎  
在微服務架構中,我們經常需要根據(jù)動態(tài)傳入的服務名來遠程調用其他服務,例如,你的業(yè)務中可能有多個子服務:service-1、service-2……需要動態(tài)決定調用哪個,所以本文給大家介紹了Spring Cloud OpenFeign 實現(xiàn)動態(tài)服務名調用指南,需要的朋友可以參考下

場景背景

在微服務架構中,我們經常需要根據(jù)動態(tài)傳入的服務名來遠程調用其他服務。例如,你的業(yè)務中可能有多個子服務:service-1、service-2……需要動態(tài)決定調用哪個。

通常我們使用如下方式注入 Feign 客戶端:

 @FeignClient(name = "service")
 public interface FeignClient {
     @PostMapping("/api/push")
     void pushMessage(@RequestBody PushMessageRequest request);
 }

但這種寫法服務名是靜態(tài)寫死的,不能根據(jù)運行時的參數(shù)進行動態(tài)選擇。

錯誤用法:FeignClientFactory

很多開發(fā)者會嘗試用 Spring 內部的 FeignClientFactory

 @Resource
 private FeignClientFactory feignClientFactory;
 ?
 FeignClient FeignClient = feignClientFactory.getInstance(serviceName, FeignClient.class);

這種方式只能獲取 @FeignClient(name="xxx") 注冊的靜態(tài)實例,而不能真正實現(xiàn)動態(tài)服務調用。

  • 適用場景:獲取已經 @FeignClient 聲明過的 bean。
  • 不適用:動態(tài)服務名(如從數(shù)據(jù)庫或配置中傳入)+ 動態(tài)構建 Feign 實例。

正確方式:自定義動態(tài) Feign 客戶端工廠

要想實現(xiàn)真正的動態(tài)服務名 + 負載均衡 + 支持配置和攔截器的 Feign 客戶端,我們需要手動構造并注入 Feign 客戶端。

核心思路:

  • 使用 Spring Cloud 提供的 Feign.Builder(必須是 Spring 注入的)
  • 配合 LoadBalancerClient 實現(xiàn)服務發(fā)現(xiàn)與負載均衡
  • 手動構建 Feign 接口實例

一、配置 Feign.Builder

 @Configuration
 public class FeignBuilderConfig {
 ?
     @Bean
     @Scope("prototype")
     public Feign.Builder feignBuilder(ObjectFactory<HttpMessageConverters> messageConverters) {
         return Feign.builder()
                 .contract(new SpringMvcContract())
                 .encoder(new SpringEncoder(messageConverters))
                 .decoder(new SpringDecoder(messageConverters))
                 .retryer(new Retryer.Default(100, TimeUnit.SECONDS.toMillis(1), 3))
                 .options(new Request.Options(3000, 5000))
                 .logger(new Logger.ErrorLogger())
                 .logLevel(Logger.Level.BASIC);
     }
 }

二、自定義動態(tài)客戶端工廠

 @Component
 @Slf4j
 public class DynamicFeignClientFactory {
 ?
     private final Feign.Builder feignBuilder;
     private final LoadBalancerClient loadBalancerClient;
 ?
     public DynamicFeignClientFactory(Feign.Builder feignBuilder,
                                      LoadBalancerClient loadBalancerClient) {
         this.feignBuilder = feignBuilder;
         this.loadBalancerClient = loadBalancerClient;
     }
 ?
     public <T> T getClient(String serviceName, Class<T> clazz) {
         int maxRetry = 3;
         int retryCount = 0;
         Exception lastException = null;
 ?
         while (retryCount < maxRetry) {
             try {
                 ServiceInstance instance = loadBalancerClient.choose(serviceName);
                 if (instance == null) {
                     throw new RuntimeException("未找到可用的服務實例:" + serviceName);
                 }
 ?
                 String url = instance.getUri().toString();
                 log.info("選擇的 Feign 客戶端目標地址為:{}", url);
                 return feignBuilder.target(clazz, url);
 ?
             } catch (Exception e) {
                 lastException = e;
                 log.warn("第 {} 次嘗試獲取 Feign 客戶端失敗,服務名:{},錯誤信息:{}", retryCount + 1, serviceName, e.getMessage());
                 retryCount++;
                 try {
                     Thread.sleep(500L);
                 } catch (InterruptedException ignored) {}
             }
         }
 ?
         throw new RuntimeException("創(chuàng)建 Feign 客戶端失敗,服務名:" + serviceName, lastException);
     }
 }

三、使用方式

原始寫法(錯誤):

 @Resource
 private FeignClientFactory feignClientFactory;
 ?
 FeignClient FeignClient = feignClientFactory.getInstance(serviceName, FeignClient.class); 

正確寫法:

@Resource
private DynamicFeignClientFactory feignClientFactory;

FeignClient FeignClient = feignClientFactory.getClient(ServerName, FeignClient.class);
FeignClient.pushMessage(new PushMessageRequest(Ids, senderEventMessage));

補充說明

  • Spring 注入的 Feign.Builder 會自動繼承全局配置(超時、日志、攔截器等)。
  • 支持服務名動態(tài)路由,自動走 Spring Cloud LoadBalancer。
  • 每次調用可綁定到不同的服務實例(支持輪詢/自定義負載策略)。
  • 避免直接 new Feign.Builder(),否則會失去 Spring 集成能力。

1. DynamicFeignClientFactory 類

 @Component
 @Slf4j
 public class DynamicFeignClientFactory {
 ?
     private final Feign.Builder feignBuilder;
     private final LoadBalancerClient loadBalancerClient;
 ?
     public DynamicFeignClientFactory(Feign.Builder feignBuilder,
                                      LoadBalancerClient loadBalancerClient) {
         this.feignBuilder = feignBuilder;
         this.loadBalancerClient = loadBalancerClient;
     }
 ?
     public <T> T getClient(String serviceName, Class<T> clazz) {
         ...
     }
 }

功能說明:

這是 動態(tài)創(chuàng)建 Feign 客戶端 的核心工廠類,解決了 Spring Cloud @FeignClient 無法支持運行時動態(tài)服務名的問題。

核心邏輯:

  • 使用 Spring 提供的 LoadBalancerClient 動態(tài)選擇某個服務的實例(支持 Eureka/Nacos 等注冊中心)。
  • 使用 Spring 注入的 Feign.Builder 構建 Feign 客戶端實例,綁定目標實例地址
  • 加了簡單的重試邏輯(最多3次),提升服務不穩(wěn)定時的容錯性。

為什么不能直接用 FeignClientFactory?

  • FeignClientFactory#getInstance 是靜態(tài)注冊的,依賴啟動時的 @FeignClient(name="xxx")不能做到動態(tài)服務名運行時創(chuàng)建實例。
  • 而本類是自己構造目標地址,可通過服務名運行時切換服務。

2. FeignBuilderConfig 類

 @Configuration
 public class FeignBuilderConfig {
 ?
     @Bean
     @Scope("prototype")
     public Feign.Builder feignBuilder(ObjectFactory<HttpMessageConverters> messageConverters) {
         return Feign.builder()
                 .contract(new SpringMvcContract())
                 .encoder(new SpringEncoder(messageConverters))
                 .decoder(new SpringDecoder(messageConverters))
                 .retryer(new Retryer.Default(100, TimeUnit.SECONDS.toMillis(1), 3))
                 .options(new Request.Options(3000, 5000))
                 .logger(new Logger.ErrorLogger())
                 .logLevel(Logger.Level.BASIC);
     }
 }

功能說明:

這是自定義的 Feign 構造器配置,確保動態(tài)創(chuàng)建的 Feign 實例擁有 Spring 的 HTTP 編解碼器、契約協(xié)議、超時、重試等設置

關鍵配置解讀:

配置項作用說明
SpringMvcContract讓 Feign 支持 @RequestMapping、@GetMapping 等 Spring MVC 風格注解
SpringEncoder/Decoder使用 Spring Boot 的 HttpMessageConverter 做 JSON 編解碼(默認支持 Jackson、Gson 等)
Retryer.Default(...)設置重試機制:初始延遲100ms,最大延遲1s,最多重試3次
Request.Options(...)設置連接超時為3秒,請求響應超時為5秒
Logger.ErrorLogger + BASIC開啟日志,僅記錄錯誤請求的基本信息(節(jié)省性能)
@Scope("prototype")每次注入都創(chuàng)建一個新的 Feign.Builder(防止多實例干擾)

為什么不能直接用 Feign.builder()

如果你直接用 Feign.builder()

  • 不具備 Spring 編解碼器能力;
  • 沒有 Spring 的日志、重試、超時等配置支持;
  • 無法識別 @RequestMapping 等注解;
  • 無法使用負載均衡(因為沒注入 LoadBalancerClient);

你必須用 Spring 注入的 Feign.Builder,并設置好契約與編解碼器,才能讓它具備 @FeignClient 的能力。

總結

配置類作用是否必須
DynamicFeignClientFactory實現(xiàn)動態(tài)服務名綁定并構建 Feign 客戶端
FeignBuilderConfig注入支持 Spring 編解碼、契約協(xié)議、重試、超時等功能的構造器

這兩個配置類結合起來,實現(xiàn)了 “動態(tài)服務發(fā)現(xiàn) + 動態(tài)客戶端構建 + Spring 完整能力支持” ,是 Spring Cloud Feign 動態(tài)服務名調用的標準做法之一。

以上就是Spring Cloud OpenFeign實現(xiàn)動態(tài)服務名調用的示例代碼的詳細內容,更多關于Spring Cloud OpenFeign服務名調用的資料請關注腳本之家其它相關文章!

相關文章

  • 輕松掌握java外觀模式

    輕松掌握java外觀模式

    這篇文章主要幫助大家輕松掌握java外觀模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • JAVA實現(xiàn)二維碼生成加背景圖代碼實例

    JAVA實現(xiàn)二維碼生成加背景圖代碼實例

    這篇文章主要介紹了JAVA實現(xiàn)二維碼生成加背景圖代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • SpringMVC Mock測試實現(xiàn)原理及實現(xiàn)過程詳解

    SpringMVC Mock測試實現(xiàn)原理及實現(xiàn)過程詳解

    這篇文章主要介紹了SpringMVC Mock測試實現(xiàn)原理及實現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • 基于注解的springboot+mybatis的多數(shù)據(jù)源組件的實現(xiàn)代碼

    基于注解的springboot+mybatis的多數(shù)據(jù)源組件的實現(xiàn)代碼

    這篇文章主要介紹了基于注解的springboot+mybatis的多數(shù)據(jù)源組件的實現(xiàn),會使用到多個數(shù)據(jù)源,文中通過代碼講解的非常詳細,需要的朋友可以參考下
    2021-04-04
  • Mybatis執(zhí)行多條語句/批量更新方式

    Mybatis執(zhí)行多條語句/批量更新方式

    這篇文章主要介紹了Mybatis執(zhí)行多條語句/批量更新方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Java測試題 實現(xiàn)一個注冊功能過程解析

    Java測試題 實現(xiàn)一個注冊功能過程解析

    這篇文章主要介紹了Java測試題 實現(xiàn)一個注冊功能過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • Java常用的八種排序算法與代碼實現(xiàn)

    Java常用的八種排序算法與代碼實現(xiàn)

    這篇文章主要給給大家分享Java常用的八種排序算法與代碼實現(xiàn),下面文章將詳細介紹整個實現(xiàn)過程,感興趣的小伙伙伴可以跟著小編一起來學習,希望對你有所幫助
    2021-10-10
  • java解析sina視頻

    java解析sina視頻

    本文介紹了一個java解析sina視頻地址的例子,從這個例子中可以學習到java使用sax解析xml的方法,大家可以參考修改成其它功能
    2014-01-01
  • Spring之IOC底層原理詳解

    Spring之IOC底層原理詳解

    這篇文章主要介紹了Spring之IOC底層原理,內容詳細,文章簡單易懂,具有一定的參考價值,需要的朋友可以參考下
    2023-01-01
  • 一篇文章帶你入門java面向對象

    一篇文章帶你入門java面向對象

    這篇文章主要介紹了Java語言面向對象編程思想之類與對象實例詳解,還是十分不錯的,這里給大家分享下,需要的朋友可以參考,希望能幫到你
    2021-08-08

最新評論