HTTP 원본서버

M2와 원본서버의 관계에 대해 설명한다.

원본서버란 일반적으로 HTTP 규격을 준수하는 웹서버를 의미한다. 관리자라면 원본을 보호하기 위해 이번 장의 모든 내용을 숙지할 필요가 있다. 이를 바탕으로 원본장애에도 내구성을 갖춘 유연한 서비스를 구축할 수 있다.

원본서버는 보호되어야 한다. 장애의 종류가 다양한 만큼 대처방안도 다양하다. 원본보호 정책을 적절히 구성하면 여유로운 점검시간을 가질 수 있다.

원본주소 사용정책

원본주소(IP)는 다음 요소들에 의해 사용정책 결정된다.

서비스를 운영하다보면 원본주소가 배제/복구되는 일은 빈번하다. M2은 IP테이블을 기반으로 원본주소를 사용하며 원본상태 모니터링 API를 통해 정보를 제공한다.

원본주소를 IP로 설정한 경우 매우 간단하다.

  • 설정변경 이외에 IP목록을 변화시키는 요인은 없다.

  • TTL에 의해 IP주소가 만료되지 않는다.

  • 장애/복구 모두 설정(IP주소)에 기반하여 동작한다.

See also

원본주소를 Domain으로 설정하면 Resolving해서 IP를 얻어야 한다. ( dns.log 에 기록된다.) IP 목록은 동적으로 변경될 수 있으며 모든 IP는 TTL(Time To Live)동안만 유효하다.

  • Domain은 주기적으로(1~10초) Resolving한다.

  • Resolving을 통해 사용할 IP테이블을 구성한다.

  • 모든 IP는 TTL만큼만 유효하며 TTL이 만료되면 사용하지 않는다.

  • 같은 IP가 다시 Resolving되면 TTL을 갱신한다.

  • IP테이블은 비어서는 안된다. (TTL이 만료되었더라도) 마지막 IP들은 삭제되지 않는다.

IP의 TTL이 너무 길 경우 지나치게 많은 IP를 사용하게 되어 의도치 않은 결과를 만들 수 있다. 이를 방지하기 위해 IP의 최대 TTL을 제한할 수 있다.

Note

원본주소를 Domain으로 설정하여도 장애/복구는 IP기반으로 동작한다. Domain주소 장애/복구 정책은 다음과 같다.

  • (Domain에 대해) 알고 있는 모든 IP주소가 배제(Inactive)되면 해당 Domain주소가 배제된다.

  • 신규 IP가 Resolving되더라도 Domain이 배제되어 있다면 IP주소는 처음부터 배제된다.

  • 모든 IP가 TTL 만료되더라도 배제된 Domain상태는 풀리지 않는다.

  • 배제된 Domain에 속한 IP주소가 하나라도 복구되어야 해당 Domain은 다시 활성화된다.

다소 복잡한 내용이므로 원본상태 모니터링 API를 통해 서비스 동작상태에 대해 이해도를 높이는 것이 좋다.

원본상태 모니터링

API를 통해 가상호스트의 원본상태를 모니터링한다.

# 모든 가상호스트
http://127.0.0.1:10040/monitoring/origin

# 개별 가상호스트
http://127.0.0.1:10040/monitoring/origin?vhost=www.example.com

결과는 JSON형식으로 제공된다.

{
    "origin" :
    [
        {
            "VirtualHost" : "example.com",
            "Address" :
            [
                { "1.1.1.1" : "Active" },
                { "1.1.1.2" : "Active" }
            ],
            "Address2" : [  ],
            "ActiveIP" :
            [
                { "1.1.1.1" : 0 },
                { "1.1.1.2" : 0 }
            ] ,
            "InactiveIP" : [ ]
        },
        {
            "VirtualHost" : "foobar.com",
            "Address" :
            [
                { "origin.foobar.com" : "Active" }
            ],
            "Address2" : [  ],
            "ActiveIP" :
            [
                { "5.5.5.5" : 21 },
                { "5.5.5.6" : 60 },
                { "5.5.5.7" : 37 }
            ],
            "InactiveIP" :
            [
                { "5.5.5.8" : 10 },
                { "5.5.5.9" : 184 }
            ]
        }
    ]
}
  • VirtualHost 가상호스트 이름

  • Address 원본주소 목록.

    설정주소가 사용중이라면 Active , (장애발생으로) 사용하고 있지 않다면 Inactive 로 표시된다.

  • Address2 보조 원본부소 목록.

    설정주소를 사용중이라면 Active , 사용하고 있지 않다면 Inactive 로 표시된다.

  • ActiveIP 사용 중인 IP목록과 TTL.

    원본서버를 IP로 설정하면 Address 와 동일한 IP에 TTL은 0으로 표시된다. Domain으로 설정하면 Resolving결과에 따른다. 다양한 IP와 TTL을 사용한다.

  • InactiveIP 사용하지 않는 IP목록과 TTL.

    사용하지 않더라도 복구 중이거나 HealthChecker에 의해 관리될 수 있다. 해당 주소는 TTL 동안 복구되지 않으면 삭제된다.

원본상태 초기화

API를 통해 가상호스트의 원본서버 배제/복구를 초기화한다. 또한 현재 사용 중인 세션을 재사용하지 않고 새롭게 연결을 생성한다.

# 모든 가상호스트
http://127.0.0.1:10040/command/resetorigin

# 개별 가상호스트
http://127.0.0.1:10040/command/resetorigin?vhost=www.example.com

세션 재사용

원본서버가 Keep-Alive 헤더를 지원한다면 연결된 세션은 항상 재사용된다. 하지만 세션을 재사용하여 보낸 요청에 대해 원본서버가 일방적으로 연결을 종료할 수 있다.

때문에 연결을 복구하느라 사용자 반응성이 늦어질 가능성이 있다. 특히 오랫동안 재사용하지 않은 세션의 경우 이러한 가능성은 더욱 높다. 이를 방지하기 위하여 n초 동안 재사용되지 않은 세션에 대해서 자동으로 연결을 종료하도록 설정한다.

See also

원본 선택

원본서버 주소가 멀티(2개 이상)로 구성되어 있을 때 원본서버 선택정책을 설정한다.

See also

/

RoundRobin

Session

부하(요청)

모든 서버가 부하를 균등하게 분배

반응성과 재사용성이 좋은 서버로 로드가 가중됨

연결비용

높음 (해당 서버의 순서가 되면 연결된 세션을 찾고 없으면 연결시도)

낮음 (재사용할 수 있는 세션이 없을 때만 연결)

재사용성

낮음 (서버 분배 우선)

높음 (항상 연결된 세션을 우선 사용)

세션수

많음 (각 서버마다 동시에 진행되는 HTTP 트랜잭션의 합)

적음 (동시에 진행되는 HTTP 트랜잭션 만큼 세션 존재)

효과적인 Hash 분산

함수체인 은 기존 원본 URL 뒤에 단위 가공함수를 명령어로 추가하는 형식이다.

http://example.com/origin.jpg/...{명령어}...
http://example.com/origin.jpg/dims/resize/100x100

자칫 이런 명령어들이 Hash 모드 원본분산 시 HIT율 저하의 원인이 되기도 한다. 예를 들어 다음 URL들은 모두 같은 원본파일을 변형하지만 URL이 다르다.

http://example.com/origin.jpg/dims/resize/100x100
http://example.com/origin.jpg/dims/strip/on/autorotate/on
http://example.com/origin.jpg/dims/grayscale/true

결과적으로 각기 다른 원본서버가 선택되면 불필요한 원본부하가 발생한다.

이런 경우를 방지하기 위해 URL 중 매칭되는 Suffix를 무시하도록 설정한다.

 # functions.network.http.backEnd

 "session":{
   "balanceMode": "hash",
   "hashUrlIgnoreList": [
     "/dims/",
     "?start="
  ]
}

위와 같이 hashUrlIgnoreList 를 설정해 두면 예제의 3 URL들은 모두 같은 원본서버를 선택한다.

# /dims/resize/100x100 무시
http://example.com/origin.jpg

# /dims/strip/on/autorotate/on 무시
http://example.com/origin.jpg

# /dims/grayscale/true 무시
http://example.com/origin.jpg

hashUrlIgnoreList 은 원본서버 선택에만 관여할 뿐 URL을 변형시키는 것은 아니다.

장애감지와 복구

캐싱과정 중 특정 원본서버에 장애가 발생하면 해당 서버를 사용하지 않는다. 백그라운드로 체크하여 다시 안정화됐다고 판단하면 서비스에 투입한다. 또는 헬스체커를 생성하여 주기적으로 서버 동작상태를 체크할 수 있다.

HTTP 헤더

M2가 원본서버로 보내는 HTTP 요청의 헤더를 컨트롤한다.

See also

Cache-Control 정책

원본서버가 다음과 같이 혼란스럽게 응답한 경우 M2의 동작에 대해 설명한다.

Cache-Control: private, no-transform, max-age=900

privatecache 인가 no-cache 인가에 대해서 해석의 여지가 있다. Mozilla - Cache-Control 에서는 다음과 같이 설명하고 있다.

private

   응답이 단일 사용자를 위한 것이며 공유 캐시에 의해 저장되지 않아야 한다는 것을 나타냅니다.
   사설 캐시는 응답을 저장할 수도 있습니다.

M2 캐싱엔진은 공유캐시 이기 때문에 private 이 있는 경우 noCache 로 판단한다. 사용자에게 응답하는 경우에는 원본에서 준 max-age 를 그대로 줄 수 있도록 한다.

즉, no-cache 라고 하더라도 max-age 를 보정하지 않는 것이 올바른 정책이다. 필요하면 TTL 우선순위를 조정해서 처리 하는 것이 맞다.