91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

使用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

翼城县| 大新县| 根河市| 辛集市| 大兴区| 都江堰市| 福清市| 栾城县| 梁山县| 乌恰县| 临沂市| 山阳县| 万荣县| 苏尼特右旗| 綦江县| 昆明市| 南投县| 马公市| 房产| 馆陶县| 任丘市| 湾仔区| 元阳县| 兴海县| 兴安县| 南京市| 宜兰市| 岳阳县| 磐石市| 合川市| 龙江县| 贵阳市| 呼伦贝尔市| 万盛区| 崇信县| 从化市| 陇西县| 静海县| 依安县| 枣庄市| 潮安县|