본문 바로가기
반응형
Programming/Javascript

자바스크립트(Javascript) 디자인패턴 - 프록시패턴 (proxy pattern)

by JAMINS 2020. 6. 3.

디자인패턴 중 하나인 프록시 패턴은 하나의 객체가 다른 객체에 대한 인터페이스로 동작하도록 한다. 이러한 패턴은 의외로 많이 볼 수 있는 패턴이다. 서버 구성을 할 때 프록시 서버를 두어 패킷양을 조절하거나 중간 레이어를 두어 완충 역할을 할 수도 있다.

프록시 패턴은 이전에 설명했던 퍼사드 패턴 과 비교했을 때 다음과 같은 차이가 있다.

  • 퍼사드 : 메서드 호출 몇 개를 결합 시켜 편의 제공
  • 프록시 : 클라이언트 객체와 실제 대상 객체 사이에 존재, 접근 통제

이는 즉 성능 개선에 도움을 준다. 왜냐면 실제 대상 객체를 보호하여 되도록 일을 적게 시키기 때문이다. 구체적으로 lazy한 초기화 이다. 초기화의 경우 비용이 발생하는데, 최초 초기화 요청을 대신 받지만 실제 객체가 정말로 사용되기 전까지는 요청 전달하지 않는다. 이는 애플리케이션의 응답성을 향상 시킨다.

동영상 재생 애플리케이션을 예로 들어보자.

예시

동영상 재생 애플리케이션

동영상 목록들을 프록시가 없다면 매번 가져와야 한다. 프록시가 있으므로 횟수를 줄일 수 있다.

  • Videos <--> HTTP : 3번 요청 시 3번의 id 요청 / 3번의 응답이 발생
  • Videos <--> Proxy <--> HTTP : 프록시에 id요청을 모아놓은 후 보내고, 한번에 응답을 받는다. 프록시는 응답을 각각 나눠준다.

이러한 방식으로 라운드 트립을 줄일 수 있다.

  1. HTTP로 직접 호출하지 않고 프록시로 요청.
  2. 50ms 안에 다른 호출이 들어오면 하나로 병합
  3. 하나로 받은 Id들을 대기열(큐)에 모아놓고 HTTP 요청 후 비운다.(flush)
  4. 응답 후 콜백

proxy의 코드를 간략하게 살펴보자.

var proxy = {
    ids: [],
    delay: 50,
    timeout: null,
    callback: null,
    context: null,

    makeRequest: function(id, callback, context) {
        this.ids.push(id);

        this.callback = callback;
        ...

        // timeout 설정
        if (!this.timeout) {
            this.timeout = setTimeout(function() {
                proxy.flush();
            }, this.delay);
        }
    },

    flush: function() {
        http.makeRequest(this.ids, "proxy.handler");

        // timeout, queue비움
        this.timeout = null,
        this.ids = [];
    },

    handler: function() {
        ..
    }

}

프록시 사용해서 요청 결과 캐시

프록시 내에 캐시 프로퍼티를 정의하여 요청 결과를 캐싱할 수 있다.

Videos <--> Proxy <--> HTTP

  1. Proxy로 보낸 후 HTTP로 보낸다.
  2. 요청을 받아 프록시 캐시에 저장하고 리턴한다.
  3. 요청을 받을 때 프록시 캐시에 이미 결과가 있나 확인한다.
  4. 있으면 캐시에서 바로 내려주고, 없으면 1번 작업 반복

만약 HTTP쪽 원본이 바뀌면, 캐시와 어떻게 동기화할지는 캐시 정책에 따라 달라질 수 있다.

참고

  • 자바스크립트 디자인패턴 책

댓글