[NET-008][중급] 프록시와 로드밸런서 흐름 이해하기 > IT 기술 공유

본문 바로가기
사이트 내 전체검색

IT 기술 공유

[NET-008][중급] 프록시와 로드밸런서 흐름 이해하기

페이지 정보

profile_image
작성자 기술팀장
댓글 0건 조회 139회 작성일 26-09-03 11:36

본문

[이번 수업]
프록시는 요청과 응답의 중개자입니다. 세 종류를 방향과 책임으로 구분하고, 로컬 입구가 두 서버에 요청을 번갈아 보내는 흐름을 확인합니다.

[선수지식]
NET-007의 HTTP 요청·응답, URL, 상태 코드와 포트를 알아야 합니다.

[학습목표]
1. 정방향 프록시와 리버스 프록시의 위치를 설명할 수 있습니다.
2. 로드밸런서의 라운드 로빈 방식을 이해할 수 있습니다.
3. 전달 헤더와 백엔드 주소를 안전하게 다룰 수 있습니다.

[핵심개념]
정방향 프록시는 클라이언트를 대신해 외부로 요청합니다. 리버스 프록시는 원본 서버처럼 보이는 입구로서 요청을 내부 백엔드에 전달합니다. HTTP 표준에서는 이를 게이트웨이라고도 부릅니다.

로드밸런서는 여러 백엔드 중 보낼 곳을 고릅니다. 라운드 로빈은 목록을 순환하고, 최소 연결 방식은 연결이 적은 서버를 고릅니다. 운영에서는 헬스 체크, 연결 제한, 시간 초과가 필요합니다. 상태를 바꾸는 요청을 재시도하면 중복 실행될 수 있습니다.

흐름은 `클라이언트 → 리버스 프록시·로드밸런서 → 백엔드 A 또는 B`입니다.

[따라하기]
아래를 local_proxy.py로 저장하세요. 로컬 주소와 자동 선택 포트만 쓰는 학습용 예제입니다.

```python
from http.server import BaseHTTPRequestHandler, HTTPServer
from threading import Thread
from urllib.request import urlopen

def app(name):
    class Handler(BaseHTTPRequestHandler):
        def do_GET(self):
            body = f"{name} served {self.path}".encode()
            self.send_response(200); self.end_headers(); self.wfile.write(body)
        def log_message(self, *args): pass
    return Handler

backends = [HTTPServer(("127.0.0.1", 0), app(n)) for n in ("app-a", "app-b")]
targets = [f"http://127.0.0.1:{s.server_port}" for s in backends]

class Proxy(BaseHTTPRequestHandler):
    index = 0
    def do_GET(self):
        target = targets[Proxy.index % 2]; Proxy.index += 1
        body = urlopen(target + self.path).read()
        self.send_response(200); self.end_headers(); self.wfile.write(body)
    def log_message(self, *args): pass

front = HTTPServer(("127.0.0.1", 0), Proxy)
for server in [*backends, front]:
    Thread(target=server.serve_forever, daemon=True).start()
for _ in range(4):
    print(urlopen(f"http://127.0.0.1:{front.server_port}/hello").read().decode())
for server in [front, *backends]:
    server.shutdown(); server.server_close()
```

Windows는 `py local_proxy.py`, macOS와 Linux는 `python3 local_proxy.py`로 실행합니다. 결과입니다.

```text
app-a served /hello
app-b served /hello
app-a served /hello
app-b served /hello
```

이는 입구 하나가 라운드 로빈으로 두 백엔드를 고른 결과입니다. Python의 http.server는 기본 보안 검사만 제공하므로 운영용이 아닙니다.

[흔한 실수]
첫째, 프록시와 백엔드의 시간 초과를 따로 설계하지 않습니다. 둘째, 처리 시간이 다른데 라운드 로빈이면 부하가 같다고 생각합니다. 셋째, 한 서버 메모리에만 로그인 세션을 저장해 다른 서버로 갈 때 로그인이 풀립니다.

[보안 주의]
본인 소유 로컬 환경에서만 실행하세요. 사용자가 목적지 주소를 정하면 내부 주소로 요청하는 SSRF 위험이 있으므로 백엔드는 허용 목록으로 고정합니다. 외부의 `Forwarded`나 `X-Forwarded-For`를 신뢰하지 말고, 신뢰하는 앞단에서 제거하거나 검증해 다시 설정하세요. IP 수집과 보관을 제한하고 백엔드 구간에도 인증·암호화·접근 통제를 적용합니다.

[직접 해볼 과제]
백엔드를 app-c까지 늘리고 `% 2`를 서버 수에 맞게 고쳐 6번 요청하세요. 세 서버가 두 번씩 출력되는지 확인하고 느린 서버가 있을 때 라운드 로빈의 한계를 설명하세요.

[확인문제]
1. 정방향 프록시와 리버스 프록시는 각각 누구를 대신하나요?
2. 라운드 로빈은 다음 백엔드를 어떻게 고르나요?
3. 외부에서 받은 전달 헤더를 그대로 신뢰하면 안 되는 이유는 무엇인가요?

[다음 학습]
다음 CLOUD-008에서는 서버리스와 관리형 서비스를 고르는 기준을 배웁니다.

[공식 참고 자료]
HTTP 중개자와 게이트웨이 표준: https://www.rfc-editor.org/rfc/rfc9110.html
Forwarded 헤더 표준과 보안 고려사항: https://www.rfc-editor.org/rfc/rfc7239.html
HTTP 로드밸런싱 공식 설명서: https://nginx.org/en/docs/http/load_balancing.html
Python 학습용 HTTP 서버 주의사항: https://docs.python.org/3/library/http.server.html

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

접속자집계

오늘
2,060
어제
5,103
최대
16,772
전체
773,114
Copyright © 소유하신 도메인. All rights reserved.