Springcloud 서비스 다 중 버 전 제어 구현 예시 코드

수요
애플 릿 의 새로운 버 전이 출시 되 었 을 때 심 사 를 해 야 합 니 다.만약 에 인터페이스의 새로운 버 전이 되 돌아 오 는 내용 에 변화 가 생기 면 백 엔 드 가 직접 출시 되면 오래된 버 전이 잘못 보고 되 고 온라인 심사 에 들 어가 지 않 으 면 통과 할 수 없습니다.
이전 에는 새로운 인 터 페 이 스 를 써 서 호 환 되 었 으 나 호 환 코드 나 불필요 한 코드 가 많아 개발 도 쉽게 생각 하지 못 하고 낡은 인 터 페 이 스 를 직접 수정 하여 버 전 관리 가 절실 한 수요 가 되 었 다.
사고의 방향
모든 요청 은 게 이 트 웨 이 로 자 연 스 럽 게 게 게 이 트 웨 이 층 에서 버 전 통 제 를 실현 할 것 이 라 고 생각 할 수 있 습 니 다.먼저 생각 나 는 것 은 ZuulFilter 필터 에서 이 루어 집 니 다.전단 의 모든 요청 은 요청 헤더 에 version 의 header 를 추가 한 다음 일치 합 니 다.그러나 이 는 프론트 버 전 만 가 져 올 수 있 고 백 엔 드 인 스 턴 스 를 선택 하 는 것 과 일치 하지 않 습 니 다.
자 료 를 조회 한 결과 부하 가 균형 을 이 룰 때 버 전 통 제 를 실현 해 야 한 다 는 것 을 발견 했다.마찬가지 로 전단 의 모든 요청 이 요청 헤더 에 version 의 header 를 추가 하고 백 엔 드 인 스 턴 스 는 버 전의 tag 를 설정 합 니 다.
이루어지다
먼저 설명해 야 할 것 은 제 가 선택 한 제어 센터 는 consul 이 고 게 이 트 웨 이 는 zuul 입 니 다.
부하 균형 정책 은 IRule 인터페이스 로 추상 화 되 었 습 니 다.프로젝트 의 기본 적 인 상황 에서 사용 되 는 IRule 의 하위 클래스 Zone Avoidance Rule extends Predicate Based Rule 입 니 다.우 리 는 Predicate Based Rule 의 하위 클래스 를 실현 하여 Zone Avoidance Rule 을 교체 해 야 합 니 다.
Predicate Based Rule 은 필터 링 을 실현 하 는 방법 이 필요 합 니 다.우 리 는 이 방법 에서 버 전 제 어 를 실현 합 니 다.필터 링 후 기본 부하 균형 정책 입 니 다.기본 값 은 폴 링 입 니 다.

  /**
   * Method that provides an instance of {@link AbstractServerPredicate} to be used by this class.
   * 
   */
  public abstract AbstractServerPredicate getPredicate();
VersionPredicate
우 리 는 Predicate BasedRule 의 getPredicate()방법 을 볼 수 있 습 니 다.이 인 스 턴 스 는 버 전 제어 의 업무 논 리 를 구체 적 으로 정의 합 니 다.코드 는 다음 과 같 습 니 다:

private static class VersionPredicate extends AbstractServerPredicate {

    private static final String VERSION_KEY = "version";

    @Override
    public boolean apply(@NullableDecl PredicateKey predicateKey) {
      if (predicateKey == null) {
        return true;
      }
      RequestContext ctx = RequestContext.getCurrentContext();
      HttpServletRequest request = ctx.getRequest();
      String version = request.getHeader(VERSION_KEY);
      if (version == null) {
        return true;
      }
      ConsulServer consulServer = (ConsulServer) predicateKey.getServer();
      if (!consulServer.getMetadata().containsKey(VERSION_KEY)) {
        return true;
      }
      return consulServer.getMetadata().get(VERSION_KEY).equals(version);
    }
  }
우선 부하 균형 과정 을 알 아 보 자.하나의 요청 이 게 이 트 웨 이에 도착 하면 해당 하 는 서비스 이름 을 분석 한 다음 에 이 서비스의 모든 사용 가능 한 인 스 턴 스 를 얻 을 수 있 습 니 다.그 다음 에 저희 의 여과 방법 으로 이 요청 이 사용 할 수 있 는 모든 서비스 인 스 턴 스 를 걸 러 내 고 마지막 으로 폴 링 부하 균형 을 이 룰 것 입 니 다.
PredicateKey 클래스 는 인 스 턴 스 서버 와 loadBalancerKey 를 사용 하여 패키지 한 클래스 입 니 다.버 전 관리 업무 논 리 는 다음 과 같 습 니 다.
  • predicateKey 가 null 인지 아 닌 지 판단 합 니 다.그렇다면 트 루 로 바로 돌아 갑 니 다.트 루 는 이 인 스 턴 스 를 사용 할 수 있 습 니 다
  • RequestContext 를 통 해 현재 요청 인 스 턴 스 HttpServletRequest 를 가 져 오고 요청 인 스 턴 스 를 통 해 요청 헤더 의 버 전 번 호 를 가 져 옵 니 다
  • 전단 요청 이 버 전 번 호 를 가 져 왔 는 지 판단 하고 가 져 오지 않 으 면 버 전 관리 없 이 트 루 로 돌아 갑 니 다
  • 서비스 인 스 턴 스 를 가 져 오고 ConsultServer 류 로 전환 합 니 다.여 기 는 제 가 사용 하 는 등록 센터 가 consul 이기 때문에 다른 것 을 선택 하여 해당 하 는 실현 류
  • 로 전환 할 수 있 습 니 다.
  • 서비스 인 스 턴 스 가 버 전 번 호 를 설정 하 였 는 지 판단 합 니 다(예:spring.cloud.consul.discovery.tags="version=1.0.0").저 희 는 consul 의 tags 로 이 루어 진 버 전 제어 이 고 서로 다른 tag 를 설정 하여 여러 기능 을 실현 할 수 있 습 니 다
  • .
  • 같은 서비스 인 스 턴 스 가 버 전 번 호 를 설정 하지 않 으 면 트 루 로 바로 돌아 갑 니 다
  • 마지막 으로 버 전 매 칭 을 하고 성공 적 인 서비스 인 스 턴 스
  • 를 되 돌려 줍 니 다.
    주의 점
    최종 실현 은 다음 과 같다.
    
    /**
     * @author Yuicon
     */
    @Slf4j
    public class VersionRule extends PredicateBasedRule {
    
      private final CompositePredicate predicate;
    
      public VersionRule() {
        super();
        this.predicate = createCompositePredicate(new VersionPredicate(),
            new AvailabilityPredicate(this, null));
      }
    
      @Override
      public AbstractServerPredicate getPredicate() {
        return this.predicate;
      }
    
      private CompositePredicate createCompositePredicate(VersionPredicate versionPredicate,
                                AvailabilityPredicate availabilityPredicate) {
        return CompositePredicate.withPredicates(versionPredicate, availabilityPredicate)
            .build();
      }
    
      private static class VersionPredicate extends AbstractServerPredicate {
    
        private static final String VERSION_KEY = "version";
    
        @Override
        public boolean apply(@NullableDecl PredicateKey predicateKey) {
          if (predicateKey == null) {
            return true;
          }
          RequestContext ctx = RequestContext.getCurrentContext();
          HttpServletRequest request = ctx.getRequest();
          String version = request.getHeader(VERSION_KEY);
          if (version == null) {
            return true;
          }
          ConsulServer consulServer = (ConsulServer) predicateKey.getServer();
          if (!consulServer.getMetadata().containsKey(VERSION_KEY)) {
            return true;
          }
          log.info("id is {}, header is {}, metadata is {}, result is {}",
              consulServer.getMetaInfo().getInstanceId(),
              version, consulServer.getMetadata().get(VERSION_KEY),
              consulServer.getMetadata().get(VERSION_KEY).equals(version));
          return consulServer.getMetadata().get(VERSION_KEY).equals(version);
        }
      }
    }
    원래 저 는@Component 주 해 를 더 해서 로 컬 에서 직접 테스트 를 통 과 했 습 니 다.그러나 생산 서버 로 업 데 이 트 된 후에 대부분의 요청 이 찾 을 수 없 는 서비스 인 스 턴 스 의 오류 가 발생 하여 저 는 안개 가 낀 상태 에서 빨리 원래 버 전 으로 돌아 갔습니다.
    많은 자 료 를 조회 한 후에 야 글 한 편 을 찾 았 는데,기 존의 부하 균형 전략 류 를 교체 하 는 Config 류 가 필요 하 다 는 것 을 발견 하 였 다.코드 는 다음 과 같 습 니 다:
    
    @RibbonClients(defaultConfiguration = RibbonGatewayConfig.class)
    @Configuration
    public class RibbonGatewayConfig {
    
      @Bean
      public IRule versionRule() {
        return new VersionRule();
      }
    }
    여기까지 버 전 관리 가 성공 한 셈 이다.
    엔 딩
    실제 사용 과정 에서 여전히 많은 문제 가 발견 되 었 다.예 를 들 어 전단 버 전 번 호 는 전체 국면 에서 유일한 것 이다.그 중의 한 서비스 가 버 전 번 호 를 업그레이드 하면 모든 서 비 스 를 이 버 전 번호 로 업그레이드 해 야 한다.코드 가 변경 되 지 않 더 라 도.비교적 좋 은 해결 방안 은 전단 이 서로 다른 서비스 에 따라 서로 다른 버 전 번 호 를 전달 하지만 전단 피드백 이 어렵다.
    또 하나의 타협 방안 은 설정 센터 를 이용 하여 구체 적 인 서비스 가 버 전 통 제 를 열 었 는 지 여 부 를 설정 하 는 것 이다.현재 의 수 요 는 버 전 관리 가 필요 하기 때문에 애플 릿 이 심사 한 후에 오래된 서비스 인 스 턴 스 를 닫 을 수 있 기 때문이다.여러분,더 좋 은 방안 이 있다 면 토론 을 환영 합 니 다.
    Springcloud 가 서비스 다 중 버 전 통 제 를 실현 하 는 예제 코드 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.Springcloud 다 중 버 전 관리 내용 에 대해 서 는 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부탁드립니다!

    좋은 웹페이지 즐겨찾기