가장 웹 서비스 앞에 서 있는 것
환영
이름을 입력하면 example.com 브라우저에 표시됩니다. 실제로 응용 프로그램을 실행하는 기계에 도달하지 않습니다. 실제로 요청을 전달하는 기계에 도달합니다. 전달하는 기계는 역 프록시라는 이름이 있습니다.
이 강의에서는 역 프록시가 하는 일, 거의 모든 공용 웹 서비스가 왜 역 프록시 뒤에 숨겨지는지를, 그리고 엣지 레이어가 동시에 같은 시간에 세 가지 작업을 수행하는지 설명합니다.
끝낫다, 당신은 이해할 수 있습니다:
- 클라이언트, 프록시 및 원본의 차이
- 원본 앞에 프록시가 보호, 확장 및 조각 없이 조각을 교체할 수 있게 해주는 이유
- 역 프록스가 한 번에 처리하는 세 가지 작업: 원본 숨기기, TLS 종료 및 복제본 사이의 부하 분배
- 브라우저에서 프록시를 거쳐 upstream으로 이동하는 요청의 각_hop
끝낫다, 당신은 프록시 배치, 엣지의 책임 나누기 및 상태가 없는 프록시 레이어가 비싼 대신 단일 원본이 아닌 이유에 대해 자신감 있게 추론할 수 있습니다.
전방 프록시 vs 역 프록시
두 가지 프록시 방향
두 가지 종류의 프록시는 두 가지 파티 사이에 서 있고 교통량을 전달합니다. 그들은 어느 파티를 대표하는지로 차이가 있습니다.
전방 프록시: 클라이언트 그룹 앞에 서 있습니다. 클라이언트는 프록시에 대해 알고 있습니다. 외부 서버는 프록시 주소가 아닌 클라이언트 주소를 보게 됩니다. 기업의 출구 프록시, 콘텐츠 필터 및 SOCKS 프록스가 이 패턴에 부합합니다.
역 프록시: 서버 그룹 앞에 서 있습니다. 외부 세계(클라이언트)는 프록시 주소에 연결합니다. 클라이언트는 실제 서버가 뒤에 숨겨져 있는지 모릅니다. 거의 모든 공용 웹 서비스가 사용합니다.
왜 방향이 중요한가? 작업, 실패 모드 및 보안 경계는 다릅니다. 전방 프록시는 사용자가 연락하는 whom을 걱정합니다. 역 프록시는 서버에 연락하는 whom을 걱정합니다.
클라이언트는 두 가지 모두에서 교통량을 전달합니다: client -> forward_proxy -> 인터넷 -> reverse_proxy -> origin.
A client sending traffic through both kinds at once travels: client -> forward_proxy -> internet -> reverse_proxy -> origin.
왜 에지에서 così 많이 살고 있나요?
에지 레이어는 어떻게 생계를 유지하는가
리버스 프록스는 동시에 세 가지 작업을 수행합니다. 그 중 하나만 해당 레이어가 존재을 정당화할 수 있습니다. 모든 세 가지 작업이 같은 주소에서 수행되고 있기 때문에, 대부분의 실제 웹 아키텍처가 전면에서 같은 모양새를 보이는 이유입니다.
작업 1: 원본 숨기기. 프록스는 공공 IP를 통해 응답합니다. 백엔드는 인터넷이 도달할 수 없는 사설 IP에 위치합니다. 원본에 대한 공격자가 프록스를 먼저 손상시킬 필요가 있습니다.
작업 2: TLS 종료. 프록스가 example.com의 인증서를 보유하고 있으며, incoming HTTPS 요청을 해독합니다. 백엔드는 프록스와 신뢰할 수 있는 네트워크 세그먼트를 건너뛰어 간단한 내부 TLS 또는 HTTP를 사용하여 프록스에 대한 통신을 수행합니다. 인증서 회전, 갱신 및 시프트 정책은 단일 위치에서 유지됩니다.
작업 3: 부하 분배. 프록스가 각 요청에 대해 백엔드를 처리하는 백엔드를 선택합니다. 하나의 프록스 뒤의 백엔드는 풀을 형성하며 프록스가 헤더에 대한 해시를 사용하여 요청 당 하나를 선택합니다. 용량을 추가하려면 풀에 백엔드를 추가하는 것입니다. 모든 클라이언트에게 새 주소를 말하는 것이 아닙니다.
각 작업은 작은 프로그램입니다. 함께 작동하면 Python 앱 자체보다 'Caddy가 Python 앱 앞에 위치한 계층'이 더 많은 설계 중량을 지닙니다.
모두 세 가지를 위한 설계
당신의 팀은 단일 Python 프로세스에서 작동하는 작은 API를 실행 중이며, 8000번 포트에서 단일 VM에서 실행되고 있습니다. 교통량이 증가했기 때문에 하나의 VM이 따라잡을 수 없고, VM이 공용 IP를 가지고 있으며 자체 TLS 인증서를 실행한다고 보안 검토에서 문제점으로 표시되었습니다.
프론트에 리버스 프록시를 추가로 사용하기로 결정했습니다. 레이아웃을 그려보세요: DNS가 어디로 지적되고, 인증서가 어디에 위치하고, 부하가 백엔드로 어떻게 도달하는지, 그리고 원래 VM이 변경되거나 유지되는 것이 어떤 것이 있는지?
컴포넌트를 교체하면서 누가 알아채지 못할까
중계가 자유를 구매합니다
오래된 컴퓨터 과학 격언: 분산 시스템에서 가장 유용한 중계 중 하나인 역방화벽.
구매하는 것:
- 교환 가능한 백엔드. 애플리케이션을 Python에서 Go로 이동합니까? 하나의 데이터 센터에서 다른 데이터 센터로 마이그레이션합니까? 무결점으로 새로운 버전을 출시합니까? 각 경우가 역안정적인 공용 주소 뒤에서 발생합니다. 사용자에게 변경이 없습니다.
- 독립적인 확장성. TLS 계층에서 프로토콜을 처리하는 프락시 계층은 CPU 및 대역폭으로 확장되며, 백엔드 계층은 애플리케이션 작업으로 확장됩니다. 각 부분이 다른 기계에서 실행되기 때문에 서로 다른 축으로 성장합니다.
- 오류 격리. 백엔드에서 나쁜 배포가 발생하면 공용 주소가 다운되지 않습니다. 프락시가 계속 작동하며 수정을 푸시하거나 롤백합니다. 백엔드 회복할 때까지 세계가 다시 연결됩니다.
- 프록시에서 중첩되는 횡단 관심사. 요청 로깅, 헤더 수정, 캐싱, 응답 압축 등 모든 것이 프락시에서 발생합니다. 백엔드 코드는 애플리케이션에만 집중합니다.
프록시가 없는 경우 각 문제가 애플리케이션 프로세스 내에서 발생해야 합니다. 프록시에서는 이러한 문제가 하나의 계층에서 발생하며 하나 팀이 소유합니다.
비용: 또 다른 계층을 운영해야 합니다. 숙련된 팀은 비용을 인정합니다. 왜냐하면 프록시 계층 자체가 상태가 없고 수평으로 확장되기 때문입니다. 하나의 프락시를 다른 프락시로 대체하려면 조정할 필요가 없습니다.
프록시를 통해 청록/녹색 배포
팀은 API 버전 1을 역방화벽 뒤에 세 개의 백엔드 VM(청색 풀이)에 실행하고 있습니다. 버전 2를 배포하고 30초 이내에 롤백할 수 있는 기능이 있어 문제가 발생하면 어떤 경우에도 가능합니다.
버전 2를 실행하는 세 개의 새로운 백엔드 VM(녹색 풀이)를 런치하고, 아직 그들에게 트래픽을 라우팅하지 않았지만, 청색 풀이와 함께 부담없이 함께 실행됩니다.
브라우저부터 백엔드까지, 그리고 되돌아 오다
단일 요청을 끝까지 따라가기
HTTPS GET https://api.example.com/users/42를 통해 리버스 프록스가 백엔드 풀 앞에 위치한 것을 따라 trace해보세요.
호프 1: DNS 해결. 브라우저는 api.example.com을 위한 리졸버에게 질문합니다. 리졸버는 프록시의 공인 IP를 반환합니다(예: 203.0.113.10). 브라우저는 203.0.113.10:443에 TCP 연결을 엽니다.
호프 2: TLS 핸드셰이크. 프록스가 api.example.com의 자격 증명을 제시합니다. 브라우저는 자격 증명을 검증하고 양쪽 모두 세션 키에 동의하며 암호화된 채널이 열립니다.
호프 3: TLS 내부 HTTP 요청. 브라우저는 GET /users/42 HTTP/1.1\nHost: api.example.com\n...을 보내고 프록스는 요청 바이트를 해독합니다.
호프 4: 백엔드 선택. 프록스는 api.example.com을 위한 업스트림 풀을 참조하고 하나의 백엔드를 선택합니다(예: 10.0.0.21:8000) 로드 밸런싱 전략에 따라.
호프 5: 업스트림 요청. 프록스는 백엔드 10.0.0.21:8000에게 평범한 HTTP 연결을 개설하거나 재사용하고 요청을 전달합니다. 프록스는 헤더를 수정할 수 있습니다: X-Forwarded-For: <client-ip> 추가, Host: 정확히 설정, 연결 단계 헤더처럼 Connection을 제거.
호프 6: 백엔드 처리. 백엔드 애플리케이션은 요청을 읽고 데이터베이스를 쿼리하고 JSON 응답을 빌드합니다.
호프 7: 업스트림 응답. 백엔드는 프록스에게 평범한 HTTP로 응답을 보냅니다.
호프 8: 에지 응답. 프록스는 응답을 재작성하거나 압축하고 TLS 세션을 통해 다시 암호화하고 브라우저에게 보내줍니다.
호프 9: 연결 수명. TLS 세션은 다음 요청에 재사용되는 것이 일반적(HTTP/2는 여러 요청을 하나의 연결에서 실행합니다). 프록스와 백엔드 연결은 일반적으로 재사용을 위해 풀됩니다.
모든 공개 웹 서비스는 이 모양의 변형을 따릅니다. 홉을 이해하면 지연이 발생하는 곳, 로깅이 들어갈 곳, 그리고 실패가 숨길 수 있는 곳을 추리할 수 있습니다.
시간은 어디에 가셨나요?
사용자가 API가 느리다고 불평합니다. 요청을 처리하는데 850ms가 걸렸음을 발견합니다. 서버 로그에 따라서 요청을 처리하는데 40ms만 소비했습니다. 프록시 로그에 따르면 프록시가 작업에 50ms를 소비했습니다(TLS handshake + 라우팅 + 응답 쓰기).
새 서비스에 대한 최소 경계 설계
합성
전방 및 역방향 프록스의 차이를 이해했으며, 역방향 프록스가 한 번에 세 가지 작업을 처리하는 이유와, 원인을 숨길 때마다 이익이 되는 이유를 배웠습니다. 또한 에지로 요청이 호프 바이 호프로 흐르는 방법을 배웠습니다.
이제 그것을 적용하세요.
새 서비스 notes.example.com을 출시하기 위한 작은 팀이 있습니다. 사용자는 개인 노트를 읽고 쓰게 됩니다. 팀은 출시에 두 개의 백엔드 VM을 실행하고一年간 십 개로 확장할 것으로 예상합니다. 사용자에게 HTTPS를, 새로운 버전의 점진적인 출시를 원하고 백엔드 IP의 공개를 피하고자 합니다.
이 과정에서 다음으로 이동하는 곳
이 과정에서 다음으로 이동하는 곳
이 수업은 에지 계층의 모양을 설정했습니다. 이 과정에서 4개의 수업이 그것을 기반으로 합니다:
- 무상태 수평 확장: 왜 프록시 계층(& 그 뒤에 있는 것들) 싼 비용으로 여러 번 반복되고, 급성 증기에 대한 계산 수식은 무엇인가?
- Ingress / Egress 분리: 왜 Incoming & Outgoing 트래픽을 모두 처리하는 단일 프록시 박스가 놀라운 방식으로 실패하게 되며, 계층을 나누는 방법은 무엇인가?
- 실패 모드 & 폭파 반경: 단일 구성 변경이 왜 파장으로 퍼져 결국 outage가 발생하게 되며, 재발을 예방하기 위한 비난 없는 작업 항목을 어떻게 작성해야 하는가?
- 관측성 & 용량: 에지에서 측정해야 하는 것이 무엇인지, 사용자가 먼저 알게 되기 전에 문제가 있다는 것을 알아챌 수 있는가?
각각의 교훈은 독립적으로 서술되어 있다. 함께 보면 웹 스케일 부족을 이해하는 일련의 정신 모델을 제공한다.
동반 교훈: geometry_of_proxies_and_origins는 이 교훈의 내용을 지향 그래프로 전환하고, 요청 경로에 대한 그래프 이론은 무엇을 말해주는지 탐구한다.
잘 했다. 앞으로 가자.