Spring Cloud 시스템 이 라벨 루트 를 실현 하 는 방법 예시

만약 에 Spring Cloud 체 계 를 사용 하고 있다 면 실제 사용 과정 에서 다음 과 같은 문제 에 부 딪 히 고 있 습 니 다.본 글 의 내용 을 읽 고 후속 적 으로 이런 문 제 를 해결 하 는 참고 로 할 수 있 습 니 다.글 의 내용 은 틀림 이 없 으 므 로 곰 곰 이 생각 한 후에 실천 하 시기 바 랍 니 다.
질문:
1.로 컬 은 개발 또는 테스트 환경의 클 러 스 터 연결 을 연결 합 니 다.정상 적 인 테스트 요청 은 로 컬 에 요청 하여 자신의 debug 에 의 해 막 힐 수 있 습 니 다.
2.환경 유 지 를 테스트 할 때 여러 항목 을 동시에 테스트 하고 똑 같은 클 러 스 터 를 유지 하 며 필요 한 지,더 좋 은 방안 이 있 는 지 테스트 합 니 다.
일반적으로 저 희 는 Spring Cloud 온 가족 통 을 사용 할 때 zuul 을 게 이 트 웨 이 로 선택 하고 Ribbon 은 부하 이퀄 라이저 로 하 며 Feign 은 원 격 서비스 호출 모델 로 합 니 다.Spring Cloud 를 사용 한 학생 들 은 이 구성 요소 들 의 역할 에 대해 잘 알 고 있 을 것 이다.이 구성 요소 들 을 조합 한 마이크로 서비스 클 러 스 터 를 통 해 태그 경로 의 기능 을 실현 합 니 다.
실 현 된 효 과 는 그림 에서 보 듯 이 머리 에 라벨 을 달 아 달 라 는 요청 은 게 이 트 웨 이와 각 응용 을 거 칠 때 라벨 을 통 해 트 래 픽 을 어느 것 으로 해 야 하 는 지 판단 하고 모든 응용 프로그램 자체 의 라벨 은 eureka 의 matedate 를 통 해 이 루어 집 니 다.

다음 그림 에서 동적 수정 탭 제어 응용 프로그램 이 받 을 수 있 는 요청 을 구상 할 수 있 습 니 다.mq 부분의 기능 은 잠시 설명 하지 않 습 니 다.
 
답:
ZoneAvoidance Rule 의 계승 클래스 를 실현 하고 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 을 RequestZone Label Context 에 넣 어야 합 니 다.우 리 는 하나의 요청 에서 만약 에 io 스 레 드 가 끝까지 실행 된다 면 threadlocal 을 이용 하여 스 레 드 변 수 를 저장 해 야 한 다 는 것 을 알 고 있 습 니 다.그러나 하나의 요청 에서 정 해 지지 않 은 하위 스 레 드 가 완성 되면 데이터 온라인 스 레 드 간 의 전달 이 문제 가 됩 니 다.여 기 는 Inheritable ThreadLocal 을 사용 하여 해결 합 니 다.RequestZone Label Context 에서 볼 수 있 습 니 다.

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);
    }
  }
}
이로써 최초의 생각 은 기본적으로 실현 되 었 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기