API Gateway Service의 개념과 Spring Netflix Ribbon, Zuul

최준호·2021년 7월 6일
0

2021 msa

목록 보기
3/10

API Gateway Service

  • API Gateway Service란

    1. 사용자가 설정한 라우팅 설정에 따라서 각 EndPoint로 client 대신 요청하고 응답을 받은 것을 다시 client로 돌려준다.

      • EndPoint란 소프트웨어나 제품에 최종 목적지인 client를 가리키며 PC, 노트북, 핸드폰, 태블릿 등의 디바이스들을 말함.
    2. 외부의 요청을 단일화하여 사용할 수 있도록 해준다.

    3. 클라이언트와 서버 사이의 프록시 역할로 시스템의 내부 구조를 숨기고 반환하는 데이터는 적절한 구조로 변경하여 반환할 수 있다.

  • API Gateway Service를 사용하는 이유

    1. 인증 및 권한 부여
    2. 서비스 검색 통합
      • 마이크로 서비스 검색
    3. 응답 캐싱
    4. 정책, 회로 차단기 및 QoS 다시 시도
      • 마이크로 서비스에 문제가 생겼을 때 해당 마이크로 서비스를 차단하는 기능
    5. 속도 제한
    6. 부하 분산
      • Load Balancer
    7. 로깅, 추적, 상관 관계
      • 어떤 EndPoint에서 어떤 Microservice가 호출되었고 정상적으로 실행되었는지 추적 기능
    8. 헤더, 쿼리 문자열 및 청구 변환
      • client의 요청 헤더와 쿼리를 변경 가능
    9. IP 차단

Netflix Ribbon

  • 넷플릭스에서 Spring 재단에 기부한 프로젝트로 msa에서 서비스들을 서로 호출하기 위해서는 RestTemplate와 Feign Client와 같은 기능이 필요한데 간단하게 설명하면

    1. RestTemplate

      new RestTemplate().getForObject("localhost:8080", Test.class, 200);
    2. Feign Client

      ```java
      @FeignClient("test")
      public interface TestClient{
          @RequestMapping("/test")
          List<Test>getTest();
      }
      ```

      와 같이 url로 호출하거나 msa에 등록된 이름으로 호출할 수 있는 기능들이다. 그래서 Ribbon이란 서비스는 이런 서비스들을 이름으로 호출하며 Health check를 통해 Load Balancer 기능을 제공한다. 하지만 해당 서비스는 비동기 방식이 적용되어 지지 않은 서비스이므로 최근에는 많이 사용되지 않는다. 또한 해당 서비스는 Client에서 gateway로 요청하는 로직이 아닌 Client자체에서 서비스 이름을 부르도록 하는 로직이다.

      현재는 Spring Cloud Loadbalancer로 대체해서 사용 가능하고 해당 서비스를 스프링부트 버전(2.4)을 맞춰서 사용 가능하다.

Netflix Zuul

위의 Ribbon이 client side에서 msa를 호출하는 gateway라면 zuul는 server에서 실제 gateway처럼 client의 요청을 받아내는 역할을 수행하는 서비스이다. 물론 이 서비스 또한 현재 Spring Cloud Gateway로 대체하여 사용하는 것을 권장한다.(Spring boot 2.3까지 지원) 하지만 Zuul로 구현되어진 프로젝트도 많기 때문에 Zuul의 동작원리를 이해하고 Spring Cloud Gateway를 차례로 이해해보자.

  1. 서비스 프로젝트 생성

    first service, second service 생성

    위 설정을 동일하게 두개의 서비스를 생성한다.

    그런 다음 프로젝트의 각각 service first, second를 구분할 수 있도록 rescontroller를 생성하여 반환하는 문구를 다르게 한다.

    yml 파일로 변경 후 다음과 같이 설정해주자. eureka에 등록하지 않는 이유는 우선 등록하지 않고 진행후 추후에 eureka에 등록하여 또 진행할 것이기 때문이다. 포트번호는 1번 서버는 8081, 2번은 8082로 세팅해줬다.

  2. Zuul 서비스 프로젝트 생성

    프로젝트 생성 후

    다음과 같이 @EnableZuulProxy 어노테이션을 추가해준다.

    서버의 세팅 또한 해주는데 여기서 서비스에 대한 path와 url을 설정해준다.

    다음과 같이 통일된 host에서 client의 요청하는 url에 따라 호출되는 서비스를 다르게 가져올 수 있는 것을 확인할 수 있다.

  3. Zuul 서비스 filter 적용
    프로젝트에 filter로 적용시킬 class를 생선한 뒤

    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import com.netflix.zuul.exception.ZuulException;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    import javax.servlet.http.HttpServletRequest;
    
    @Component
    @Slf4j
    public class ZuulLoggingFilter extends ZuulFilter {
        @Override
        public String filterType() {
            return "pre";   //사전 필터이기 때문에 pre로 명명
        }
    
        @Override
        public int filterOrder() {
            return 1;   //여러개 필터의 순서
        }
    
        @Override
        public boolean shouldFilter() {
            return true;   //필터로 사용될지 정함 false: 사용안함, true: 사용
        }
    
        @Override
        public Object run() throws ZuulException {  //filter의 동작 로직
            log.info("************* printing logs : ");
    
            RequestContext ctx = RequestContext.getCurrentContext();    //zuul에서 제공하는 ServletReqeust 객체를 가져오기 위한 메서드
            HttpServletRequest request = ctx.getRequest();
            log.info("************* "+ request.getRequestURI());    //사용자가 요청한 url정보
            return null;
        }
    }

    해당 코드를 넣고 테스트를 진행하면 된다. ZuulFilter 추상 클래스를 상속받아 상속 메서드들을 오버라이트한 코드인데 각 코드에 대해서 간단한 설명을 주석으로 적어놨다. 그리고 실제 서버를 재 실행하여 로그를 확인하면

    다음과 같이 로그에 사용자가 어떤 url을 사용했는지를 기록할 수 있는 것을 확인할 수 있다. 이렇게 Zuul를 사용하는 방법에 대해 알아봤다.

출처 : https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%84%9C%EB%B9%84%EC%8A%A4

profile
코딩을 깔끔하게 하고 싶어하는 초보 개발자 (편하게 글을 쓰기위해 반말체를 사용하고 있습니다! 양해 부탁드려요!) 현재 KakaoVX 근무중입니다!

0개의 댓글