프록시 서버 구현
2025. 5. 14. 11:31ㆍ개발
프록시 서버 구현 - 캐시와 병렬 처리로 효율 UP!
이번 글에서는 C언어로 구현한 프록시 서버(proxy server)에 대해 정리해볼게요. 특히 캐시를 어떻게 저장하는지와 동시 접속 요청을 어떻게 처리하는지를 중심으로 볼 거예요.
1. 구조 개요
- 클라이언트로부터 HTTP 요청을 받아 서버에 전달하고 응답을 다시 클라이언트에 전달하는 중계 역할을 해요.
- 자주 오는 요청은 캐시에 저장해서 더 빠르게 응답할 수 있어요.
- 여러 클라이언트가 동시에 요청해도 각 요청을 스레드로 처리해서 병렬로 응답할 수 있어요.
2. 캐시 구조: 연결리스트 기반의 LRU 정책
캐시는 웹 객체(web_object_t)를 저장하는 이중 연결리스트(doubly linked list) 형태로 구현되어 있어요.
typedef struct web_object_t {
char path[MAXLINE]; // 요청 경로 (URI)
int content_length; // 컨텐츠 길이
char *response_ptr; // 실제 응답 데이터
struct web_object_t *prev, *next; // 이전, 다음 노드
} web_object_t;
LRU(Least Recently Used) 방식으로 작동해요:
- 새로운 객체는 항상 맨 앞(root)에 삽입
- 사용된 캐시는 다시 맨 앞으로 이동 (read_cache)
- 전체 캐시 크기를 초과하면 맨 끝(lastp)부터 제거
관련 주요 함수들:
find_cache(path)– 요청한 path가 있는 캐시 객체를 찾아 반환send_cache(obj, fd)– 캐시된 응답을 클라이언트로 전송read_cache(obj)– 사용된 캐시를 리스트 맨 앞으로 이동write_cache(obj)– 새로운 응답을 캐시에 저장 (용량 초과 시 제거)
3. 요청 동시 처리: 스레드 기반 병렬 구조
이 서버는 클라이언트 요청을 하나씩 순차적으로 처리하지 않고, 요청마다 새로운 스레드를 생성해서 동시에 병렬로 처리해요.
while (1) {
connfdp = Malloc(sizeof(int));
*connfdp = Accept(...);
Pthread_create(&tid, NULL, thread, connfdp);
}
thread 함수는 각 요청을 처리하고, 끝나면 자동으로 리소스를 정리해줘요:
Pthread_detach()– 스레드 종료 시 자동으로 자원 반환handle_client(connfd)– 요청 처리 함수 (GET/HEAD)
요즘 웹 환경처럼 수많은 요청이 동시에 들어오는 상황에서 매우 효율적인 구조죠!
4. 마무리 요약
- 캐시는 메모리 절약과 빠른 응답을 위해 필수!
- LRU 정책으로 오래된 응답부터 삭제
- 스레드로 동시 요청 처리 → 고성능 서버 구현 가능
웹 프록시 서버 git 주소 : https://github.com/applepc24/tiny_web-proxy/blob/main/proxy.c
'개발' 카테고리의 다른 글
| pintos 프로젝트 시작하기 (0) | 2025.05.25 |
|---|---|
| 프록시 서버에서 캐시 최신화 방법들 (0) | 2025.05.15 |
| 컴퓨터 시스템 tiny 서버 (0) | 2025.05.07 |
| 동적 메모리 할당(Malloc) 심화 및 구현 1-2 (0) | 2025.04.30 |
| 동적 메모리 할당(Malloc) 심화 및 구현 1-1 (0) | 2025.04.28 |