-
HTTP완벽가이드 스터디 7, 8장IT 2021. 5. 2. 19:49
7장
웹 캐시는 자주 쓰이는 문서의 사본을 자동으로 보관하는 HTTP 장치다. 웹 요청이 캐시에 도착했을 때, 사본이 존재한다면 서버에 갈 필요없이 즉시 반환한다.
네트워크 요금으로 인한 비용을 줄여준다.
네트워크 병목을 줄여준다.
원 서버에 대한 요청을 줄인다, 즉 부하를 줄여서 전체 속도를 빠르게 해준다.
거리로 인한 지연을 줄여준다.
이 장에서는 캐시가 어떻게 성능을 개선, 비용을 절감하는지, 그리고 그것을 어떻게 측정하는지, 캐시가 있을 가장 적절한 위치는 어디인지에 대해 말할 것이다.
또한 HTTP가 어떻게 캐시된 사본을 신선하게 유지하는지, 캐시와 서버와의 상호작용은 어떻게 이뤄지는지를 이야기한다.
7.1 불필요한 데이터 전송
복수의 클라이언트가 똑같은 문서를 위해 서버에 접근할 때, 서버는 각각 한 번씩 클라이언트에게 전송을 한다. 이 똑같은 문서란 곧 똑같은 바이트들이다.
똑같은 바이트다 똑같이 서버를 통해 이동하게 된다면, 이 불필요한 데이터 전송은 값비싼 네트워크 대역폭을 잡아먹고, 전송을 느리게 만들며, 서버에 부담을 준다.
캐시를 이용하면 첫번째 서버 응답이 캐시에 보관이 되고, 뒤 이은 요청들에 대한 응답으로 보관된 사본을 사용하게 된다. 이는 중복된 트래픽을 줄인다.
7.2 대역폭 병목
캐시는 네트워크 병목을 줄인다. 많은 네트워크가 원격 서버보다는 로컬 네트워크 클라이언트에게 더 넓은 대역폭을 제공한다.
클라이언트가 서버에 접근할 때의 속도는, 그 경로에 있는 가장 느린 네트워크의 속도와 같다.
만약 클라이언트가 빠른 LAN에 있는 캐시로부터 사본을 가져온다면, 캐싱은 성능을 대폭 개선할 수 있을 것이다. (특히 큰 문서들에 대해서)
7.3 갑작스런 요청 쇄도 (Flash Crowds)
캐싱은 갑작스런 요청 쇄도에 대처하기 위해 특히 중요하다. 특별한 사건이 있는 경우 서버는 평소보다 수십 배 많은 요청을 받기도 한다.
7.4 거리로 인한 지연
네트워크가 빛의 속도로 오간다고 하더라도, 미국과 일본 사이에서는 600밀리초 정도의 지연이 발생할 수 있다. 이 때, 웹 사이트가 복잡해지면 이것은 수 초로 증가한다.
7.5 적중과 부적중
캐시에 요청이 들어왔을 때, 만약 그에 대응되는 사본이 있다면 그것을 이용해 요청이 처리될 수도 있다. 이것을 캐시 적중(cache hit)이라고 부른다.
만약 대응하는 사본이 없다면 그냥 원 서버로 전달되기만 할 뿐이다. 이것을 캐시 부적중(cache miss)이라고 부른다.
캐시 적중이 높으면 좋겠지만, 웹 상의 모든 문서를 보관할 정도의 충분한 캐시를 살 능력이 있는 사람은 거의 없고, 있다고 해도 정보 중에는 항상 최신 상태여야 하는 것도 있다.
7.5.1 재검사 (Revalidation)
원 서버의 콘텐츠는 변경이 될 수 있어서, 캐시는 반드시 그들의 사본이 최신 상태인지 점검해야 한다. 이런 신선도 검사를 재검사 (Revalidation) 이라고 한다.
효과적인 검사를 위해 HTTP는 서버로부터 전체 객체를 가져오지 않아도 콘텐츠가 여전히 신선한지 빠르게 검사할 수 있는 특별한 요청을 재정의했다.
모든 문서를 재검사하지 않고, 클라이언트가 요청한 문서가, 특별히 오래되어서 다시 검사가 필요해보이는 경우에만 한정하여 재검사를 한다.
캐시는 캐시된 사본의 재검사가 필요할 때, 원 서버에 작은 재검사 요청을 보낸다. 콘텐츠가 변경되지 않았다면 서버는 아주 작은 304 Not Modified 응답을 보낸다.
그 사본이 유효하다는 것을 알게 된 캐시는 즉각 사본이 신선하다고 임시로 다시 표시한 뒤 클라이언트에게 제공한다. 이를 재검사 적중 혹은 느린 적중이라고 부른다.
순수 캐시 적중보다는 느린데, 원 서버와 검사를 할 필요가 있기 때문이다.
HTTP는 캐시된 객체를 재확인하기 위해 몇 가지 도구를 제공하는데, 그 중에서 가장 많이 씌는 것은 If-Modified-Since 헤더다. 서버에 보내는 GET 요청에 이를 추가하면 된다.
이것은 캐시된 시간 이후 변경된 경우에만 사본을 보내달라는 의미가 된다. 아래는 이 헤더를 보낸 이후 발생하는 세 가지 경우이다.
재검사 적중
만약 서버 객체가 변경되지 않았다면 서버는 클라이언트에게 작은 HTTP 304 Not Modified 응답을 보낸다.
재검사 부적중
만약 서버 객체가 캐시된 사본과 다르다면, 서버는 콘텐츠 전체와 함께 평범한 HTTP 200 OK 응답을 클라이언트에게 보낸다.
객체 삭제
만약 서버 객체가 삭제되었다면, 서버는 404 Not Found 응답을 돌려보내며, 캐시는 즉각 사본을 삭제한다.
7.5.2 적중률
캐시가 요청을 처리하는 비율을 캐시 적중률이라고 한다. (혹은 캐시 적중비, 문서 적중률, 문서 적중비 라고도 한다.)
캐시 관리자는 캐시 적중률이 100%에 근접하게 되는 것을 좋아할 것이다. 실제 적중률은 캐시가 얼마나 큰지, 캐시 사용자들의 관심사가 얼마나 비슷한지, 또는,
캐시된 데이터가 얼마나 자주 바뀌거나 개인화되는지, 캐시가 어떻게 설정되어 있는지에 달려 있다.
적중률은 예측하기 어려운 것으로 악명이 높지만, 보통은 40%면 웹 캐시로서 괜찮은 편이다. 다행인 것은, 보통 크기의 캐시라도 충분히 효과적이라는 점이다.
7.5.3 바이트 적중률
문서들이 모두 같은 크기인 것은 아니기 때문에 적중률이 모든 것을 말해주지 못한다. 그렇기 때문에 별도로 바이트 단위 적중률 측정값을 계산하기도 한다.
(특히 트래픽의 모든 바이트에 요금을 매기려는 사람들이 그렇다.)
바이트 단위 적중률은 캐시를 통해 제공된 모든 바이트의 비율을 표현한다. 이 측정 값은 트래픽이 절감된 정도를 포착해낸다.
바이트 단위 적중률이 100%라면 어떤 트래픽도 인터넷으로 나가지 않았음을 의미한다.
문서 적중률은 트랜잭션이 얼마나 외부로 나갔는지를 보여주고, 바이트 단위 적중률은 얼마나 많은 바이트가 인터넷으로 나가지 않았는지를 보여준다.
각각이 트랜잭션과, 대역폭 절약을 최적화하는 데에 중요한 지표로 활용된다.
7.5.4 적중과 부적중의 구별
불행히도 HTTP는 클라이언트에게 응답이 캐시 적중이었는지 원 서버 접근이었는지 말해줄 수 있는 방법을 제공하지 않는다.
두 경우 모두 응답 코드는 응답이 본문을 가지고 있음을 의미하는 200 OK가 될 것이다. 다만 어떤 상용 프락시 캐시는 캐시에서의 일을 설명하고자 Via 헤더를 이용하기도 한다.
다른 방법으로는 Date 헤더를 이용하는 것이다. 응답의 Date 헤더 값을 현재 시각과 비교하여, 응답의 생성 일이 더 오래되었다면 캐시된 것임을 알 수 있다.
다른 방법으로 Age 헤더를 이용하는 방법이 있다.
7.6 캐시 토폴로지
캐시는 한 명의 사용자에게만 할당될 수도 있고, 반대로 수천 명의 사용자들 간에 공유될 수도 있다. 한 명에게만 할당된 경우를 개인 전용 캐시 (private cache)라고 부른다.
개인 전용 캐시는 개인만을 위한 캐시이므로 한 명의 사용자가 자주 찾는 페이지를 담는다. 공유된 캐시는 공용 캐시 (public cache) 라고 부른다.
7.6.1 개인 전용 캐시
개인 전용 캐시는 많은 저장 공간을 필요로 하지 않으므로 작고 저렴할 수 있다. 웹 브라우저는 개인 전용 캐시를 내장하고 있다.
대부분의 웹 브라우저는 자주 쓰이는 문서를 개인용 컴퓨터의 디스크와 메모리에 캐시해 놓고 사용자가 캐시 사이즈와 설정을 수정할 수 있도록 허용한다.
이전에는 chrome의 경우 about:cache 를 검색하여 캐시 목록을 볼 수 있었지만, 지금은 사라졌다. 단 캐시가 사라진 것은 아니라서 아래 경로에서 찾아 볼 수는 있다.
C:\Users\[username]\AppData\Local\Google\Chrome\User Data\Profile 1\Cache
조사해본 결과, 캐시 조회가 사라진 것은 캐시를 볼 수 있는 다양한 tool이 나온 탓이라고 되어 있지만, 실질적인 이유는 아닌 것 같다. (많은 개발자들이 이를 아쉬워 하고 있다.)
몇몇 개발자들은, 이것이 보안 쪽에서 야기된 문제로 인해 사라진 것이라고 추측하고 있다.
7.6.2 공용 프락시 캐시
공용 캐시는 캐시 프락시 서버, 혹은 더 흔히 프락시 캐시라고 부르는 특별한 종류의 공유된 프락시 서버다.
프락시 캐시는 로컬 캐시에서 문서를 제공하거나 혹은 사용자 입장에서 서버에 접근한다. 공용 캐시에는 여러 사용자가 접근하기에, 불필요한 트래픽을 줄일 더 많은 기회가 있다.
예를 들어, 각각의 개인 전용 캐시들이 자신의 사본이 최신의 정보인지 파악하지 위해 원 서버에 확인을 요청한다고 해보자. 작은 요청이라 할지라도 이 역시 많은 트래픽이 된다.
이 때 공용 프락시 캐시는, 서버에 이 사본이 최신인지에 대한 물음을 1번만 하면 되기 때문에 트래픽을 절감해준다.
수동 프락시를 지정하거나 프락시 자동설정 파일을 설정함으로써 브라우저가 프락시 캐시를 사용하도록 설정할 수 있다. 또는 인터셉트 프락시를 사용하여 강제할 수도 있다.
7.6.3 프락시 캐시 계층들
캐시 하나가 모든 것을 처리하는 것이 부담이 된다면, 프락시 캐시들로 계층을 만들어, 적은 클라이언트에게만 쓰이는 사본들 위에 캐시 프락시 하나를 두고,
많은 클라이언트들에게 쓰이는 사본을 그 프락시 서버들 위에 또 하나의 프락시 서버들을 두어 피라미드 구조처럼 만드는 것을 생각해볼 수 있다.
7.6.4 캐시망, 콘텐츠 라우팅, 피어링
몇몇 네트워크 아키텍처는 단순한 캐시 계층 대신 복잡한 캐시망을 만든다. 프락시 캐시는 복잡한 방법으로 서로 대화하여 어떤 부모와 캐시할지, 바로 서버로 갈지 결정한다.
아래는 캐시망 안에서 콘텐츠 라우팅을 위해 설계된 캐시들이 할 수 있는 일이다.
URI에 근거, 부모 캐시와 원 서버 중 하나를 동적으로 선택한다.
URI에 근거, 특정 부모 캐시를 동적으로 선택한다.
부모 캐시에게 가기 전, 캐시된 사본을 로컬에서 찾는다.
다른 캐시들이 그들의 콘텐츠에 접근할 수 있도록 부분적인 허용을 하되, 인터넷 트랜짓 (다른 네트워크로 건너가는 행위) 은 허용하지 않는다.
서로 다른 조직들이 상호 이득을 위해 그들의 캐시를 연결하여 서로 찾아볼 수 있게 하는 것을 피어링이라고 한다.
선택적인 피어링을 지원하는 캐시는 형제 캐시라고 부르는데,
HTTP는 형제 캐시를 지원하지 않기 때문에 사람들은 인터넷 캐시 프로토콜(ICP)나 하이퍼텍스트 캐시 프로토콜(HTCP) 같은 프로토콜을 이용해 HTTP를 확장하였다.
7.7 캐시 처리 단계
HTTP GET 메시지를 하나 보내면 캐시 처리는 일곱 가지 절차에 따라 이루어진다.
요청 받기 : 캐시는 요청 메시지를 읽는다.
파싱 : 캐시는 메시지를 파싱하여 URL과 헤더들을 추출한다.
검색 : 캐시는 로컬 복사본이 있는지 검사하고, 사본이 없다면 사본을 받아온다.
신선도 검사 : 캐시된 사본을 찾았다면 최신의 것이 맞는지 검사한다. 아니라면 서버로부터 변경사항을 확인한다.
응답 생성 : 응답을 생성한다.
발송 : 클라이언트에게 응답을 돌려준다.
로깅 : 선택적으로 로그 파일에 트랜잭션을 서술한 로그를 남긴다.
7.7.1 단계 1 : 요청 받기
캐시는 네트워크 커넥션에서의 활동을 감지, 데이터를 읽는다. 고성능 캐시는 동시에 여러 커넥션으로부터 데이터를 읽고 메시지 전체가 도착하기 전에 트랜잭션을 처리한다.
7.7.2 단계 2 : 파싱
캐시는 요청 메시지를 여러 부분으로 파싱하여 헤더 부분을 조작하기 쉬운 자료구조에 담는다. 상대 URL 참고.
7.7.3 단계 3 : 검색
캐시는 URL을 알아내고 로컬 사본이 있는지 알아낸다. 복사본은 메모리, 디스크, 심지어 다른 컴퓨터에 있을 수도 있다. 전문적인 수준의 캐시는 고도의 알고리즘을 사용한다.
만약 문서를 로컬에서 가져올 수 없으면 부모 프락시나 원 서버로부터 가져오고, 또는 실패를 반환한다.
캐시된 객체는 서버 응답 본문과 원 서버 응답 헤더를 포함하고 있으므로 캐시 적중 동안에 올바른 서버 헤더가 반환될 수 있다.
또한 캐시된 객체가 얼마나 오랫동안 캐시에 머무르고 있었는지, 얼마나 자주 사용됐는지에 관한 메타 데이터를 포함시키기도 한다.
7.7.4 단계 4 : 신선도 검사
HTTP는 캐시가 일정 기간 동안 서버 문서의 사본을 보유할 수 있도록 해준다. 이 때 일정기간을 정하는 것은 신선도 계산에서 이루어진다. 해당 내용은 후술한다.
7.7.5 단계 5 : 응답 생성
캐시가 원 서버에서 온 것처럼 보일 수 있게 캐시는 캐시된 응답 헤더를 토대로 새 응답 헤더를 생성한다. 이 때 헤더는 수정되고 늘어나기도 한다.
캐시는 클라이언트가 요구한 것에 맞게 서버 응답을 수정할 필요가 있다. 예컨대 클라이언트가 HTTP/1.1을 원한다면, 서버가 1.0을 보냈더라도 캐시 차원에서 수정해주어야 한다.
7.7.6 단계 6 : 전송
응답을 돌려준다. 프락시 캐시 역시 클라이언트와 커넥션을 유지해야 한다. 고성능 캐시는 로컬 저장장치와 네트워크 I/O 버퍼 사이에서 콘텐츠 복사를 피해 효율을 높인다.
7.7.7 단계 7 : 로깅
캐시는 로그 파일과 캐시 사용에 대한 통계를 유지하곤 한다. 따라서 통계를 지닌 캐시라면, 전송 이후 로그를 반영해 통계를 수정해야 한다.
7.8 사본을 신선하게 유지하기
오래된 데이터를 제공하는 캐시는 불필요하다. 예컨대 금융 자료는 매 초마다 변경이 되기 때문에 항상 최신의 정보를 가져와야 한다.
7.8.1 문서 만료
HTTP는 Cache-Control과 Expires라는 특별한 헤더들을 이용해서 원 서버가 각 문서에 유효 기간을 붙일 수 있게 해준다. 이는 유통기간과 비슷한 개념이다.
캐시는 이를 토대로 서버와 접촉 없이 사본을 제공할 수 있다. 만료된 데이터가 있다면 캐시는 서버에 변경 사항을 확인하고 사본과 새로운 유효기간을 가져와야 한다.
7.8.2 유효기간과 나이
Expires는 절대 시간이다. 그래서 컴퓨터의 절대 시간이 바르게 맞춰져 있을 것을 요구한다. 그렇기에 새로 생겨난 것이 Cache-Control이다. 이는 상대시간을 초(seconds)로 받는다.
7.8.3 서버 재검사
캐시된 문서가 만료되었다면 서버에 확인 요청을 보낸다. 이를 서버 재검사라고 한다. 검사 이후 캐시는 아래의 결과를 돌려줘야 한다.
충분히 신선한, 캐시된 사본 (서버로부터 새로 받아온 경우)
원 서버와 재검사 되었기 때문에 충분히 신선하다고 확신할 수 있는 캐시된 사본 (변경사항이 없음을 확인한 경우)
에러 메시지 (서버가 다운된 경우)
서버가 죽은 경우, 캐시에는 데이터가 남아 있더라도 에러를 보내는 것이 옳다.
경고 메시지가 부착된 캐시된 사본 (부정확한 경우)
7.8.4 조건부 메서드와의 재검사
HTTP 조건부 메서드는 재검사를 효율적으로 만들어준다. HTTP는 캐시가 서버에게 '조건부 GET' 이라는 요청을 보낼 수 있도록 한다.
이는 캐시가 가지고 있는 사본이 서버의 것과 다른 경우에만 데이터를 보내달라는 요청이다.
HTTP에서는 5가지의 조건부 요청 헤더를 정의하고 있는데, 그 중 둘은 캐시 재검사를 위한 If-Modified-Since와 If-None-Match다.
7.8.5 If-Modified-Since : 날짜 재검사
IMS 요청이라고도 한다. IMS 요청은 특정 날짜 이후로 변경된 경우에만 요청한 본문을 보내달라고 한다. 변경이 없는 경우, 변경이 필요한 헤더들만 수정하여 보내준다.
7.8.6 If-None-Match : 엔터티 태그 재검사
IMS에는 몇 가지 문제가 있다.
변경점이 없어도, 백 그라운드 프로세스에 의해서 변경 시각이 계속 바뀌는 데이터가 있을 경우
어떤 문서의 변경이 철자나 주석 등의 사소한 변경이라, 전체 문서를 가져오는 것이 리소스 낭비로 이어질 경우
최근 변경 일시를 정확하게 파악할 수 없는 경우
1초보다 작은 간격으로 갱신되는 문서는, 1초마다 확인하는 것으로도 충분하지 않을 수 있다.
이런 경우에는 문서에 일종의 버전이나 넘버링을 붙여서, 해당 번호가 아닌 경우에만 돌려달라고 요청할 수 있다.
7.8.7 약한 검사기와 강한 검사기
서버는 때때로 조금의 변경 정도는 그 정도면 같은 것 이라고 말할 수 있게 약한 검사기를 지원한다. 강한 검사기는 콘텐츠가 바뀔 때마다 바뀐다.
하지만 약한 검사기는 콘텐츠의 변경을 허용하며, 콘텐츠의 중요한 정보가 바뀔 때에만 함께 변경된다.
7.8.8 언제 엔터티 태그를 사용하고 언제 Last-Modified 일시를 사용하는가?
둘 다 사용해야 한다. 둘 다 동시에 사용하는 것이 가장 좋다.
7.9 캐시 제어
아래는, 서버가 캐시에게 줄 수 있는 얼마나 오랫동안 유지할 것인지에 대한 기준을 우선 순위에 따라 나열한 것이다.
Cache-Control : no-store
Cache-Control : no-cache
Cache-Control : must-revalidate
Cache-Control : max-age
Expires 날자 헤더
아무런 정보도 주지 않고 캐시 스스로가 판단하게 한다.
7.9.1 no-cache와 no-store 응답 헤더
no-store와 no-cache 헤더는 캐시가 검증되지 않는 캐시 객체로 응답하는 것을 막는다.
no-store의 경우에는 캐시가 사본을 저장하는 것 자체를 막고, no-cache의 경우에는 무조건 서버와 재검사를 하게 하는 것이다.
7.9.2 Max-Age 응답 헤더
최대 시간을 설정한다. 서버는 최대 시간 (maximum aging)을 0으로 설정함으로써, 캐시가 매 접근마다 문서를 캐시하거나 리프레시하지 않도록 요청할 수 있다.
7.9.3 Expires 응답 헤더
앞서 설명한 헤더. 더는 사용을 권하지 않는다. 컴퓨터마다의 시간이 다를 수 있어 정확하지 않기 때문이다.
7.9.4 Must-Revalidate 응답 헤더
캐시가 신선하지 않은 데이터를 임의로 제공하는 것을 원천적으로 금지한다.
7.9.5 휴리스틱 만료
만약 어떤 헤더도 포함되지 않았다면 캐시는 경험적인 방법 (Heuristic) 으로 최대 나이를 계산할 것이다. 어떤 알고리즘이든지 사용될 수 있다.
다만 결과 값이 24시간보다 큰 경우에는 Heuristic Expiration 경고 헤더가 응답 헤더에 추가되어야 한다.
8장
통합점: 게이트웨이 , 터널, 릴레이8.1 게이트웨이
게이트웨이는 리소스와 애플리케이션을 연결하는 역할을 한다.
애플리케이션은 게이트웨이에게 요청을 처리해달라고 할 수 있고, 게이트웨이는 그에 응답할 수 있다. 동적인 콘텐츠를 생성하거나 데이터베이스에 질의를 보낼 수 있다.
또한 HTTP 트래픽을 다른 프로토콜로 자동 변환하여, HTTP 클라이언트가 다른 프로토콜을 알 필요 없이 서버에 접속할 수 있게 하기도 한다.
8.1.1 클라이언트 측 게이트웨이와 서버 측 게이트웨이
웹 게이트웨이는 한쪽에서는 HTTP로 통신하고, 다른 한쪽에서는 HTTP가 아닌 다른 프로토콜로 통신한다.
또한 게이트웨이는 클라이언트와 서버 프로토콜을 다음과 같이 빗금(/)으로 구분해 기술한다.
<클라이언트 프로토콜>/<서버 프로토콜>
8.2 프로토콜 게이트웨이
브라우저에서 명시적으로 게이트웨이를 설정하여 자연스럽게 트래픽이 게이트웨이를 거쳐 가게 하거나, 게이트웨이를 대리 서버(리버스 프락시)로 설정할 수 있다.
8.2.1 HTTP/*: 서버 측 웹 게이트웨이
서버 측 웹 게이트웨이는 클라이언트로부터 HTTP 요청이 원 서버 영역으로 들어오는 시점에 클라이언트 측의 HTTP 요청을 외래 프로토콜로 전환한다.
예를 들어 HTTP/FTP 게이트웨이는 HTTP 요청을 FTP 요청으로 변환한다.
8.2.2 HTTP/HTTPS: 서버 측 보안 게이트웨이
기업 내부의 모든 웹 요청을 암호화함으로써 개인 정보 보호와 보안을 제공할 수 있다.
클라이언트는 일반 HTTP를 사용하지만, 게이트웨이는 자동으로 사용자의 모든 세션을 암호화한다.
8.2.3 HTTPS/HTTP: 클라이언트 측 보안 가속 게이트웨이
HTTPS/HTTP 게이트웨이는 웹 서버 앞단에 위치하여 보이지 않는 인터셉트 게이트웨이나 리버스 프락시 역할을 한다.
8.3 리소스 게이트웨이
게이트웨이의 가장 일반적인 형태인 애플리케이션 서버는 목적지 서버와 게이트웨이를 한 개의 서버로 결합한다. 애플리케이션 서버는 HTTP를 통해서 클라이언트와 통신하고 서버 측에 있는 애플리케이션 프로그램에 연결하는 서버 측 게이트웨이다.
애플리케이션 게이트웨이에서 유명했던 최초의 API는 공용 게이트웨이 인터페이스(Common Gateway Interface, CGI)였다.
CGI는 특정 URL에 대한 hTTP 요청에 따라 프로그램을 실행하고, 프로그램의 출력을 수집하고, HTTP 응답으로 회신하는데 웹 서버가 사용하는 표준화 된 인터페이스 집합이다.
8.3.1 공용 게이트웨이 인터페이스
CGI는 최초의 서버 확장이자 지금까지도 널리 쓰이는 서버 확장이다. 웹에서 동적인 HTML, 신용카드 처리, 데이터베이스 질의 등을 제공하는 데 사용한다.
8.3.2 서버 확장 API
CGI는 구동중인 HTTP 서버에 외부 인터프리터가 쉽게 접속할 수 있게 해주지만, 서버 자체의 동작을 바꾸고 싶거나 서버의 처리 능력을 최고치로 올리기 위해서는 서버 확장 API가 필요하다.
이런 확장 API는 프로그래머가 자신의 코드를 서버에 연결하거나 서버의 컴포넌트를 자신이 만든 것으로 교체해버릴 수 있다.
8.4 애플리케이션 인터페이스와 웹 서비스
애플리케이션을 연결하면서 생기는 까다로운 이슈 중 하나는, 데이터를 교환하려는 두 애프리케이션 사이에서 프로토콜 인터페이스를 맞추는 일이다.
웹 서비스는 SOAP를 통해 XML을 사용하여 정보를 교환한다.
SOAP(Simple Object Access Protocol): HTTP 메시지에 XML 데이터를 담는 방식에 관한 표준
XML(eXtensible Markup Language): 데이터 객체를 담는 데이터를 생성하고 해석하는 방식 제공
8.5 터널
웹 터널은 HTTP 프로토콜을 지원하지 않는 애플리케이션에 HTTP 애플리케이션을 사용해 접근하는 방법을 제공한다.
웹 터널을 사용하는 가장 일반적인 이유는 HTTP 커텍션 안에 HTTP가 아닌 트래픽을 얹기 위해서다. 따라서 이것을 사용하면 웹 트래픽만을 허락하는 방화벽이 있더라도 HTTP가 아닌 트래픽을 전송할 수 있다.
8.5.1 CONNECT로 HTTP 커널 커넥션 맺기
CONNECT 메서드는 터널 게이트웨이가 임의의 목적 서버와 포트에 TCP 커넥션을 맺고 클라이언트와 서버 간에 오는 데이터를 무조건 전달하기를 요청한다.
8.5.2 데이터 터널링, 시간, 커넥션 관리
클라이언트는 성능을 높이기 위해 CONNECT 요청을 보낸 후, 응답을 받기 전에 터널 데이터를 전송할 수 있다. 이는 서버에 데이터를 더 빨리 보내는 방법이지만, 게이트웨이가 요청에 이어서 데이터를 적절하게 처리할 수 있어야 함을 전제로 한다.
터널의 끝단 어느 부분이든 커넥션이 끊어지면, 끊어진 곳으로부터 온 데이터는 반대편으로 전달된다. 그 다음 커넥션이 끊어졌던 터널의 끝단 반대편의 커넥션도 프락시에 의해서 끊어질 것이다. 컨넥션이 끊긴 한쪽에 아직 전송하지 않은 데이터는 버려진다.
8.5.3 SSL 터널링
SSL 트래픽이 기존 프락시 방화벽을 통과할 수 있도록 HTTP에 터널링 기능이 추가되었다. 이 터널링 기능은 HTTP 메시지에 암호화된 날 데이터를 담고 일반 HTTP 채널을 통해 데이터를 전송한다.
8.5.4 SSL 터널링 vs HTTP/HTTPS 게이트웨이
HTTP/HTTPS의 단점
클라이언트-게이트웨이 사이에는 보안이 적용되지 않은 일반 HTTP 커넥션이 맺어져 있다.
프락시가 인증을 담당하고 있기 때문에 클라이언트는 원격 서버에 SSL 클라이언트 인증을 할수 없다.
게이트웨이는 SSL을 완벽히 지원해야 한다.
SSL 터널링을 사용하면 프락시에 SSL을 구현할 필요가 없다. SSL 세션은 클라이언트가 생성한 요청과 보안이 적용된 웹 서버간에 생성된다. 프락시 서버는 트랙잭션의 보안에는 관여하지 않고 암호화된 데이터를 그대로 터널링 한다.
8.6 릴레이
HTTP 릴레이는 HTTP 명세를 완전히 준수하지는 않는 간단한 HTTP 프락시다. 릴레이는 커넥션을 맺기 위한 HTTP 통신을 한 다음 바이트를 맹목적으로 전달한다.
HTTP는 복잡하기에 모든 헤더와 메서드 로직을 수행하지 않고 맹목적으로 트래픽을 전달하는 간단한 프락시를 구현하는 방식이 유용할 때가 있다. 데이터를 맹목적으로 전달하도록 구현하기는 쉽기 때문에 단순 필터링이나 진단 혹은 콘텐츠 변환을 하는데 사용되기도 한다.
하지만 이는 잠재적으로 심각한 상호 운용 문제를 가지고 있기 때문에 주의해서 배포해야 한다.
'IT' 카테고리의 다른 글
HTTP완벽가이드 스터디 13, 14장 (0) 2021.05.23 HTTP완벽가이드 스터디 11, 12장 (0) 2021.05.16 HTTP완벽가이드 스터디 5, 6장 (0) 2021.04.24 HTTP완벽가이드 스터디 3, 4장 (0) 2021.04.17 HTTP완벽가이드 스터디 1, 2장 (0) 2021.04.11