Proxy server #2 / TIL

프록시 서버 실습

Featured image

Proxy Server

내 컴퓨터를 origin 서버의 리버스 프록시 서버로 만드는 실습을 해보자 ! (캐싱 기능을 포함한 프록시 서버를 작성해야 한다.)

먼저 프록시 서버를 만들기 위해서 /etc/nginx/nginx.conf 파일을 sudo 권한으로 다음과 같이 수정한다.

server {
	listen 10026;
	server_name localhost;

	location / {
		proxy_pass http://3.39.193.36:8080;
        # nginx가 요청을 프록시 해야하는 업 스트림 서버의 URL이다.
		proxy_set_header myname "devops-04-OSeaYeon";
        # my name이라는 사용자 지정 헤더를 설정하고 " " 안의 값을 할당한다.
		proxy_set_header X-Real-IP $remote_addr;
        # X-Real-Ip 헤더를 요청하는 클라이언트의 IP 주소를 설정한다.
        # $remote_addr은 요청을 만드는 클라이언트 IP 주소를 포함하는 변수이다.
		proxy_set_header Host $host;
        # Host 헤더를 원래 요청의 Host 헤더 값으로 설정한다.
    }
}

수정 후 다음 명령어를 차례대로 실행해 본다.


$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
// 제대로 된 코드가 작성되지 않으면 failed가 뜬다.

$ sudo systemctl reload nginx
# 만약 nginx가 시작되지 않은 상태라면 'reload'가 아닌 'start'로 실행한다.

$ curl -I http://localhost:10026

origin 서버의 주소는 3.39.193.136:8080 이며, 프록시 서버(localhost:10026)로 요청을 보내면 아래와 같은 화면으로 서버가 작동된다. 출력되는 내용은 내가 프록시 서버에 요청을 세 번 보냈기 때문에 이름이 세 번 뜨는 것이다.



프록시 서버에 캐싱 기능 포함하기

이제 다시 nginx.conf 파일을 수정해서 캐싱 기능을 포함해보자.

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=5s;
# 업스트림 서버에서 캐시된 응답을 저장하는 데 사용할 Nginx의 캐시 경로를 /var/cache/nginx로 설정한다.
# 캐시 영역의 이름(key_zone)은 my_cache이며, 메모리는 10MB로 제한된다.
# inactive : 5초 동안 액세스 하지 않은 캐시 항목은 자동으로 제거된다.

proxy_cache_key "$scheme$request_method$host$request_uri";
# 캐시된 각 요청에 대한 캐시 키를 설정한다.
# 캐시 키는 요청 방법($request_method), 요청 스키마($scheme), 호스트 이름($host) 및 URI($request_uri)를 기반으로 한다.

server {
	listen 10026;
	server_name localhost;

		location / {
		proxy_pass http://3.39.193.136:8080;
		proxy_set_header myname "devops-04-OSeaYeon"; 
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header Host $host;

		proxy_cache my_cache;
        # 현재 위치 블록과 일치하는 요청에 대한 캐싱을 활성화한다.
        # 사용할 캐시 영역의 이름(my_cache)을 지정한다.

        proxy_cache_valid any 5s;
        # 응답 상태 코드에 관계 없이 각 응답의 캐싱 시간을 5초로 설정한다.

		add_header X-Cache-Status $upstream_cache_status;
        # 응답이 캐시에 제공되고 있는지 여부를 나타낸다.
        # 헤더의 값은 $upstream_cache_status 변수의 값으로 설정된다.

		if ($upstream_cache_status = "MISS") {
			add_header Cache-Control "public, max-age=5";
		}
        # 업스트림 서버에 캐시를 찾을 수 없는 상태면
        # 사용자의 브라우저 캐시가 이 응답을 최대 5초 동안 저장할 수 있음을 의미한다.
		if ($upstream_cache_status = "HIT") {
			add_header Cache-Control "public, max-age=5, must-revalidate";
		}
        # 업스트림 서버에서 응답이 캐시에서 제공되었음을 나타내며
        # 사용자의 브라우저 캐시는 최대 5초 동안 이 응답을 저장할 수 있지만,
        # 해당 시간 이후 캐시된 복사본을 사용하기 전에 서버에서 유효성 검사를 다시 해야한다.
		if ($upstream_cache_status = "EXPIRED") {
			add_header Cache-Control "no-cache";
		}
        # 업스트림 서버에서 응답이 캐시에서 발견되었지만 만료되었음을 나타내며
        # 사용자 브라우저 캐시가 이 응답의 캐시된 복사본을 사용할 수 없으며
        # 서버에 다시 요청해야 함을 의미한다.

        # 위의 if 문은 $upstream_cache_status 변수 값을 기반으로 서버 응답에 특정 Cache-Control 헤더를 추가하는 구문이다.
	}
}

코드를 위와 같이 작성한 뒤 nginx 테스트와 reload를 해준 후 curl로 요청을 보내게 되면 요청의 결과에 헤더 값이 다음과 같이 출력된다.

$ curl -I http://localhost:10026
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Mon, 10 Apr 2023 04:21:22 GMT
Content-Type: text/plain
Content-Length: 43
Connection: keep-alive
Last-Modified: Mon, 10 Apr 2023 04:21:14 GMT
ETag: "64338eba-2b"
X-Cache-Status: MISS
Accept-Ranges: bytes

$ curl -I http://localhost:10026
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Mon, 10 Apr 2023 04:21:26 GMT
Content-Type: text/plain
Content-Length: 43
Connection: keep-alive
Last-Modified: Mon, 10 Apr 2023 04:21:14 GMT
ETag: "64338eba-2b"
X-Cache-Status: HIT
Accept-Ranges: bytes

$ curl -I http://localhost:10026
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Mon, 10 Apr 2023 04:21:28 GMT
Content-Type: text/plain
Content-Length: 86
Connection: keep-alive
Last-Modified: Mon, 10 Apr 2023 04:21:22 GMT
ETag: "64338ec2-56"
X-Cache-Status: EXPIRED
Accept-Ranges: bytes

위와 같이 나오는 이유에 대해 더 자세히 알아보자.