中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用Spring Cloud體系怎么實現標簽路由

發布時間:2021-05-07 16:38:19 來源:億速云 閱讀:183 作者:Leah 欄目:編程語言

使用Spring Cloud體系怎么實現標簽路由?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

問題:

1,本地連上開發或測試環境的集群連調,正常測試請求可能會請求到本地,被自己的debug阻塞。

2,測試環境維護時,多項目并發提測,維護多個相同的集群進行測試是否必要,是否有更好的方案。

一般,我們在使用Spring Cloud全家桶的時候,會選擇zuul作為網關,Ribbon作為負載均衡器,Feign作為遠程服務調用模版。使用過Spring Cloud的同學對這些組件的作用必然非常熟悉。這里就拿這些組件組合成的微服務集群來實現標簽路由的功能。

實現的效果如圖所示,在頭上帶上標簽的請求會在經過網關和各個應用時進行標簽判斷流量應該打到哪一個去,而每一個應用自己本身的標簽是通過eureka上的matedate實現的。

使用Spring Cloud體系怎么實現標簽路由

如下圖可以構想動態修改標簽控制應用所能承接的請求,這里暫時不描述mq部分的功能:

使用Spring Cloud體系怎么實現標簽路由 

答案:

實現一個ZoneAvoidanceRule的繼承類,重寫getPredicate方法:

@Override
public AbstractServerPredicate getPredicate() {
  OfflineEnvMetadataAwarePredicate offlineEnvMetadataAwarePredicate = new OfflineEnvMetadataAwarePredicate();
  offlineEnvMetadataAwarePredicate.setEnv(env);
  return offlineEnvMetadataAwarePredicate;
}

Predicate的實現屏蔽了開發測試環境中非這個環境網段啟動的應用,并且比對請求的標簽和本地的標簽,來控制路由給哪一個服務器

@Override
public AbstractServerPredicate getPredicate() {
  OfflineEnvMetadataAwarePredicate offlineEnvMetadataAwarePredicate = new OfflineEnvMetadataAwarePredicate();
  offlineEnvMetadataAwarePredicate.setEnv(env);
  return offlineEnvMetadataAwarePredicate;
}

那么我們注意到請求頭上的標簽要在初始時就拿到,所以需要一個ServletRequestListener,將拿到的zone放入RequestZoneLabelContext。我們知道在一個請求中如果是一個io線程執行到底,我們只需要利用threadlocal來存儲線程變量,可是如果一個請求中會產生不定的子線程完成,數據在線程間的傳遞就成為問題,這里使用了InheritableThreadLocal來決解,在RequestZoneLabelContext中可以看到。

public class RequestZoneLabelContextListener implements ServletRequestListener {


  private static final String ZONE_LABEL_NAME = "zone";


  @Override
  public void requestDestroyed(ServletRequestEvent sre) {
    RequestZoneLabelContext.remove();
  }


  @Override
  public void requestInitialized(ServletRequestEvent requestEvent) {
    HttpServletRequest request = (HttpServletRequest)requestEvent.getServletRequest();
    String lbZone = request.getHeader(ZONE_LABEL_NAME);
    if(StringUtils.isNotBlank(lbZone)){
      RequestZoneLabelContext.setZone(lbZone);
    }
  }
}
/**
 * 從request header上傳遞label到feign請求
 */
public class RequestZoneLabelContext {


  private static InheritableThreadLocal<String> zoneLabelThreadLocal = new InheritableThreadLocal<>();


  public static void setZone(String zone){
    zoneLabelThreadLocal.set(zone);
  }


  public static String getRequestZone(){
    return zoneLabelThreadLocal.get();
  }


  public static void remove(){
    zoneLabelThreadLocal.remove();
  }
}

那么在應用之間調用的feign中我們是需要繼續把這個zone通過header傳遞下去的,所以又擴展了RequestInterceptor:

public class FeignZoneHeaderInterceptor implements RequestInterceptor {


  @Override
  public void apply(RequestTemplate template) {
    String requestZone = RequestZoneLabelContext.getRequestZone();
    if(StringUtils.isNotBlank(requestZone)){
      template.header("zone", requestZone);
    }
  }
}

看完上述內容,你們掌握使用Spring Cloud體系怎么實現標簽路由的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

沁源县| 深泽县| 昭通市| 三江| 思茅市| 四川省| 平湖市| 广平县| 色达县| 沁水县| 双流县| 乐亭县| 邹城市| 怀来县| 嘉鱼县| 梁平县| 顺平县| 望奎县| 平阴县| 合水县| 安国市| 山阴县| 邯郸县| 汉中市| 班玛县| 白朗县| 云阳县| 若尔盖县| 剑阁县| 襄城县| 洪泽县| 巴林右旗| 正宁县| 万年县| 顺义区| 拜城县| 阳新县| 淳化县| 当阳市| 丽江市| 云和县|