nginx 최적화 - 캐시, ddos 방어, proxy, 1만 연결 등을 위한 설정을 chatGPT에 물어봤을때
gunicorn와 연결되는 nginx의 최적화된 nginx.conf 파일을 보여줘 static 캐시 기능과 압축 기능도 포함되어야 하고, https 기능과 여러 gunicorn application server를 연결하는 proxy 기능이 있는데 클라이언트가 연결 되었을 때 현재 가장 연결수가 작은 gunicorn 서버에 연결이 되도록 설정해줘
아래는 요구사항에 맞게 최적화된 nginx.conf 파일입니다. 주석을 포함하여 설명드리겠습니다
# worker_processes는 CPU 코어 수를 설정해줍니다.
# 일반적으로 CPU 코어 수와 같은 값으로 설정해주는 것이 좋습니다.
worker_processes auto;
# nginx가 처리할 수 있는 커넥션의 최대 개수를 설정합니다.
# 커넥션 개수가 넘어가면 클라이언트의 요청을 처리하지 못하게 됩니다.
# 이 값을 설정하면 커넥션을 유지하면서 처리할 수 있는 요청의 최대 개수가 결정됩니다.
# 이 값을 너무 높게 설정하면 서버 리소스를 과도하게 사용하게 됩니다.
events {
worker_connections 1024;
}
http {
# nginx가 사용할 MIME 타입을 설정합니다.
include mime.types;
default_type application/octet-stream;
# 로깅 설정입니다.
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Gzip 압축 설정입니다.
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# Static 파일 캐싱 설정입니다.
# 캐시 만료 시간을 1년으로 설정했습니다.
# 다른 캐시 정책도 적용 가능합니다.
location /static/ {
alias /path/to/static/;
expires 1y;
add_header Cache-Control "public";
}
# HTTPS 설정입니다.
# 인증서 파일과 개인키 파일을 지정해주어야 합니다.
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# gunicorn application server와 연결합니다.
location / {
# 클라이언트가 연결되었을 때 현재 가장 연결수가 작은 gunicorn 서버에 연결하도록 설정합니다.
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
# HTTP 요청을 HTTPS로 리다이렉트합니다.
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
# upstream 블록에서 backend라는 이름으로 gunicorn application server를 연결합니다.
upstream backend {
server 127.0.0.1:8000;
server 127.0.0.1:8001;
server 127.0.0.1:8002;
# 연결할 gunicorn application server의 개수만큼 server 라인을 추가합니다.
# 각 server 라인에서는 IP 주소와 포트 번호를 지정해줍니다.
# 예시에서는 8000, 8001, 8002 포트를 사용하는 서버 3개를 연결하였습니다.
ddos 공격 방어를 위한 설정도 추가해줘
DDoS 공격 방어를 위해 아래와 같은 설정을 추가해줄 수 있습니다
http {
# limit_req_zone은 특정 URL 패턴에 대한 요청 허용 횟수를 설정합니다.
# burst는 초당 처리 가능한 최대 요청 횟수를 의미하며, delay는 초당 처리 가능한 요청 횟수를 넘어서는 요청을 대기시키는 시간입니다.
# zone=mylimit:10m은 10메가바이트 크기의 메모리를 사용하여 limit_req_zone을 설정합니다.
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=30r/s;
# limit_conn_zone은 IP 주소별 최대 커넥션 개수를 설정합니다.
# zone=myconn:10m은 10메가바이트 크기의 메모리를 사용하여 limit_conn_zone을 설정합니다.
limit_conn_zone $binary_remote_addr zone=myconn:10m;
# limit_conn는 limit_conn_zone에 설정한 myconn 영역의 최대 커넥션 개수를 설정합니다.
# 예시에서는 IP 주소별 최대 10개의 커넥션을 허용합니다.
limit_conn myconn 10;
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
# limit_req 지시어는 해당 URL 패턴에 대한 요청 제한을 설정합니다.
# 예시에서는 한 IP 주소당 30회의 요청만 허용하도록 설정합니다.
limit_req zone=mylimit burst=50 nodelay;
# limit_conn 지시어는 해당 URL 패턴에 대한 커넥션 개수 제한을 설정합니다.
limit_conn myconn;
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
}
위 설정을 추가하면, limit_req_zone, limit_conn_zone을 이용하여 IP 주소별 최대 요청 횟수 및 커넥션 개수를 제한할 수 있습니다. 또한, limit_req, limit_conn 지시어를 이용하여 특정 URL 패턴에 대한 요청 및 커넥션 개수 제한을 설정할 수 있습니다. 이를 통해 DDoS 공격에 대한 방어를 할 수 있습니다.
위에 말해준 설정값들을 하나로 정리해서 django를 위한 설정도 추가 해주고 최근 가장 선호도가 높은 설정들도 해줘 주석을 자세해게 달아줘. 그리고 10k 연결이 가능할 수 있는 조건과 설정들도 알려줘
아래는 Nginx의 설정 파일인 nginx.conf에 대한 요구사항들을 하나로 정리한 것입니다
worker_processes auto;
worker_rlimit_nofile 100000;
events {
worker_connections 10240;
multi_accept on;
use epoll;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
client_body_timeout 12;
client_header_timeout 12;
keepalive_timeout 15;
send_timeout 10;
# Gzip 압축 기능을 설정합니다.
gzip on;
gzip_min_length 1000;
gzip_proxied any;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 정적 파일 캐싱 기능을 설정합니다.
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors off;
# limit_req_zone과 limit_conn_zone을 설정합니다.
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=30r/s;
limit_conn_zone $binary_remote_addr zone=myconn:10m;
server {
listen 80 default_server;
server_name _;
return 444;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# limit_req, limit_conn을 설정합니다.
location / {
limit_req zone=mylimit burst=50 nodelay;
limit_conn myconn;
# Django를 위한 설정입니다.
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
# 설정을 위한 기본값은 10,240개이며, 연결을 최대 10,000개까지 허용합니다.
# 만약 worker_connections 값을 더 크게 설정하면 연결 개수가 더 많이 가능합니다.
# 또한, 연결 개수를 더 많이 허용하고 싶다면 worker_rlimit_nofile 값을 증가시키면 됩니다.
# 이는 운영체제에서 각 worker process가 열 수 있는 최대 파일 개수를 조정하는 값입니다.
# 단, rlimit_nofile 값도 함께 증가시켜야 합니다.
# 이를 위해 /etc/security/limits.conf 파일에서 아래와 같이 설정할 수 있습니다.
# * soft nofile 100000
# * hard nofile 100000
}
}
}
위 설정 파일에는 Nginx 기본 설정뿐만 아니라, Django를 위한 프록시 설정, 정적 파일 캐싱 기능, Gzip 압축 기능 등이 포함되어 있습니다. 또한, DDoS 공격 방어를 위해 limit_req_zone과 limit_conn_zone을 설정하였으며, 클라이언트 연결 개수 제한을 위해 worker_connections 값
위 설정값이 최대의 성능을 발휘하기 위한 최적의 서버 cpu, ram, ssd 등의 하드웨어 조건을 상세히 정리해서 알려줘
Nginx 설정의 최적화는 하드웨어 스펙에 따라 다를 수 있으므로, 하드웨어의 사양과 애플리케이션의 특성에 따라 성능 최적화를 해야합니다. 그러나 일반적으로 Nginx가 서빙하는 콘텐츠의 크기와 동시 접속자 수에 따라 CPU, 메모리, 디스크 등의 하드웨어 스펙이 달라질 수 있습니다.
일반적으로 Nginx는 CPU를 많이 사용하지 않고, 주로 메모리를 사용합니다. 따라서 높은 메모리 용량이 필요합니다. 동시 접속자 수가 높을 경우에는 CPU와 메모리 용량이 더 많이 필요합니다.
SSD는 HDD에 비해 높은 I/O 처리 성능을 제공하므로, 정적 파일을 많이 서빙하는 경우에는 SSD가 더욱 적합합니다. 따라서 정적 파일을 많이 서빙하는 경우, SSD를 사용하면 Nginx의 처리 속도를 높일 수 있습니다.
하지만 최적의 하드웨어 스펙을 결정하는 가장 좋은 방법은 특정 환경에서 성능을 테스트하는 것입니다. 서버의 하드웨어 스펙을 결정할 때, 일반적으로 다음과 같은 요소들을 고려할 수 있습니다.
- CPU: 높은 시스템 클럭 속도와 다중 코어를 가진 CPU가 더 좋은 성능을 제공합니다.
- 메모리: 운영 체제, Nginx, 백엔드 서버 등이 사용하는 메모리 공간을 고려하여 충분한 용량을 제공해야합니다.
- 디스크: SSD는 I/O 처리 속도가 빠르므로, 정적 파일을 많이 서빙하는 경우에 유용합니다. 또한, 파일 시스템 캐시 기능을 사용하면 더 빠른 I/O 처리 속도를 얻을 수 있습니다.
- 네트워크: 서버와 클라이언트 간의 물리적 거리와 네트워크 대역폭을 고려하여 네트워크 인터페이스를 선택해야합니다.
위에서 알려준 nginx.conf 파일로 단일 서버에서 c10k 문제를 해결하려면 최적의 서버 하드웨어 조건이 어떻게 되어야 하는지 속도, 용량을 정확히 산정해서 알려줘
위에서 제시된 Nginx 설정으로 단일 서버에서 c10k 문제를 해결하기 위한 최적의 서버 하드웨어 조건은 다음과 같습니다.
- CPU: Intel Xeon 또는 AMD EPYC과 같은 고성능 멀티코어 프로세서
- 메모리: 32GB 이상의 메모리 (동시 접속자 수에 따라 다르지만, 대략적으로 1GB당 1000명의 접속자를 처리할 수 있습니다.)
- 디스크: SSD 디스크 (정적 파일을 많이 서빙하는 경우에는 NVMe SSD가 더욱 적합합니다.)
- 네트워크: 1Gbps 또는 10Gbps 이상의 높은 대역폭 네트워크 인터페이스
이러한 하드웨어 스펙을 가진 서버에서 위에서 제시한 Nginx 설정을 사용하면 단일 서버에서 10,000개 이상의 동시 접속자를 처리할 수 있습니다. 그러나 이는 일반적인 가이드일 뿐, 실제 서비스에서는 애플리케이션의 특성과 환경에 따라 다를 수 있습니다. 따라서 최적의 하드웨어 스펙을 결정하기 위해서는 애플리케이션의 특성과 예상되는 트래픽 양을 고려하여 충분한 성능을 제공할 수 있는 하드웨어를 선택하는 것이 중요합니다.
위에서 알려준 모든 조건에 부합되는 최적의 서버를 aws의 ec2 인스턴스 중에서 선택해서 알려줘 그리고 oracle cloud Infrastructure 에서도 선택해서 알려줘
AWS EC2 인스턴스와 Oracle Cloud Infrastructure(OCI) 인스턴스 중에서는 다양한 유형의 인스턴스가 제공되며, 서버의 성능 요구 사항과 예산에 따라 선택할 수 있습니다.
AWS EC2에서는 다음과 같은 인스턴스 유형이 적합할 수 있습니다.
- 인스턴스 유형: c5.2xlarge
- CPU: Intel Xeon Platinum 8124M(스카이레이크) 8 코어 16 스레드 3.0 GHz
- 메모리: 16GB DDR4
- 디스크: 500GB NVMe SSD
- 네트워크: 10 Gbps
OCI에서는 다음과 같은 인스턴스 유형이 적합할 수 있습니다.
- 인스턴스 유형: VM.Standard2.4
- CPU: AMD EPYC 2.3 GHz 4 코어
- 메모리: 16GB DDR4
- 디스크: 320GB NVMe SSD
- 네트워크: 10 Gbps
위의 인스턴스는 예시이며, 서버의 성능 요구 사항에 따라 더 나은 인스턴스 유형을 선택할 수 있습니다. 이러한 인스턴스는 AWS 및 OCI에서 쉽게 프로비저닝하고 관리할 수 있으며, 선택한 인스턴스 유형에 맞게 운영체제, 미들웨어 및 애플리케이션을 설치하여 최적의 성능을 발휘할 수 있습니다.
각각에 대한 월별 비용은 어떻게 될까?
AWS EC2 및 Oracle Cloud Infrastructure의 인스턴스 가격은 지역, 인스턴스 유형, 운영 체제 등에 따라 다르기 때문에 일반적인 비용을 정확히 산정하기는 어렵습니다. 하지만 인스턴스 유형에 따른 가격을 살펴보면 다음과 같습니다.
AWS EC2 c5.2xlarge 인스턴스 가격:
- On-Demand 가격: US$0.34/hour (기본적으로 리전과 운영체제 선택에 따라 다를 수 있습니다.)
- 예약 인스턴스 가격: US$0.168/hour (1년 예약, 부분 전액 선불)
Oracle Cloud Infrastructure VM.Standard2.4 인스턴스 가격:
- On-Demand 가격: US$0.1152/hour (기본적으로 리전과 운영체제 선택에 따라 다를 수 있습니다.)
- 예약 인스턴스 가격: US$0.0624/hour (1년 예약, 부분 전액 선불)
각각의 클라우드 프로바이더에서는 인스턴스 타입, 지역, 운영 체제, 사용량 등에 따라 가격이 다르기 때문에 정확한 비용 산정을 위해서는 AWS와 Oracle Cloud Infrastructure의 공식 웹사이트를 참조하시기 바랍니다.
매일 24시간씩 1달을 사용하면 비용은 어떻게 될까?
매일 24시간씩 인스턴스를 사용하는 경우 월별 사용 시간은 730시간입니다. 이를 기준으로 AWS EC2 및 Oracle Cloud Infrastructure의 인스턴스 가격을 살펴보면 다음과 같습니다.
AWS EC2 c5.2xlarge 인스턴스 월별 가격:
- On-Demand 가격: US$247.20/month (730시간 x US$0.34/hour)
- 예약 인스턴스 가격: US$120.96/month (730시간 x US$0.168/hour)
Oracle Cloud Infrastructure VM.Standard2.4 인스턴스 월별 가격:
- On-Demand 가격: US$83.81/month (730시간 x US$0.1152/hour)
- 예약 인스턴스 가격: US$45.54/month (730시간 x US$0.0624/hour)
다만, 인스턴스 운영에 따라 추가적인 비용이 발생할 수 있습니다. 예를 들어, 네트워크 트래픽, 데이터 전송, 스토리지 사용 등이 해당됩니다. 따라서 실제 사용 시에는 이러한 요소들도 고려하여 총 비용을 계산해야 합니다.
오늘 기준 한국 원화로 얼마가 되는지 알려줘
오늘 기준(2023년 3월 19일) AWS EC2 c5.2xlarge 인스턴스 On-Demand 가격은 296,298원, 예약 인스턴스 가격은 143,489원입니다.
Oracle Cloud Infrastructure VM.Standard2.4 인스턴스 On-Demand 가격은 102,672원, 예약 인스턴스 가격은 55,946원입니다.
단, 환율 변동 등의 영향으로 가격이 변경될 수 있으니, 정확한 가격은 해당 클라우드 프로바이더의 웹사이트나 가격 책정 페이지에서 확인하시는 것이 좋습니다.
예약 인스턴스는 1년을 계약해야 제공받을 수 있는 조건이야?
AWS EC2 및 Oracle Cloud Infrastructure 예약 인스턴스는 기본적으로 1년 또는 3년의 계약 기간을 설정하여 사용할 수 있습니다. 예약 인스턴스를 이용하면 일정 기간 동안 일정한 금액으로 인스턴스를 사용할 수 있어서 비용을 절감할 수 있습니다.
AWS의 경우, 예약 인스턴스는 Standard, Convertible, Scheduled 3가지 옵션이 제공되며, 최소 1년 이상 계약해야 합니다. 3년 계약 시 더욱 저렴한 가격으로 제공받을 수 있습니다. 계약 기간 동안 인스턴스의 사용량을 조정할 수 있고, 계약 종료 전에 예약 인스턴스를 해지할 수도 있습니다.
Oracle Cloud Infrastructure의 예약 인스턴스는 Flexible 옵션과 Reserved 옵션이 있으며, 최소 1년 이상 계약해야 합니다. Flexible 인스턴스의 경우, 계약 기간 동안 인스턴스 크기를 변경할 수 있으며, Reserved 인스턴스는 고정된 크기의 인스턴스를 제공합니다.
예약 인스턴스의 계약 기간 및 가격 책정 등에 대한 상세한 내용은 AWS 또는 Oracle Cloud Infrastructure의 웹사이트에서 확인하실 수 있습니다.
동적 웹서버의 경우 nginx를 어떻게 캐시 서버로 사용할 수 있는지 nginx.conf 파일로 만들어 자세하게 주석을 달아줘
동적 웹 서버의 경우, Nginx를 캐시 서버로 사용하여 응답 속도를 높일 수 있습니다. Nginx의 캐시 기능을 사용하면, 매번 요청이 들어올 때마다 웹 서버에서 동적으로 컨텐츠를 생성하는 것이 아니라, 이전에 생성된 컨텐츠를 캐시에서 가져와서 바로 클라이언트에게 응답할 수 있습니다. 이를 통해 웹 서버의 부하를 줄이고, 빠른 응답 속도를 유지할 수 있습니다.
다음은 Nginx를 캐시 서버로 사용하기 위한 Nginx.conf 파일의 예시입니다.
# Nginx 캐시 설정
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 60m;
proxy_cache_valid 404 1m;
proxy_cache_bypass $http_pragma;
proxy_cache_revalidate on;
# upstream 서버 정의
upstream app_servers {
server 127.0.0.1:8000;
server 127.0.0.1:8001;
server 127.0.0.1:8002;
}
# 기본 서버 설정
server {
listen 80 default_server;
server_name example.com;
# 캐시 적용을 위한 proxy_pass 설정
location / {
proxy_pass http://app_servers;
proxy_cache my_cache;
proxy_cache_lock on;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_min_uses 1;
proxy_cache_methods GET HEAD;
proxy_cache_key "$scheme$request_method$host$request_uri";
add_header X-Cache-Status $upstream_cache_status;
expires 1m;
}
}
위의 설정 파일에서는 proxy_cache_path를 통해 캐시 디렉토리 경로와 캐시 옵션을 설정합니다. keys_zone은 캐시 키를 저장할 메모리 영역의 이름과 크기를 지정하고, inactive는 캐시가 유효하지 않은 상태로 판단되기까지의 시간을 설정합니다.
proxy_cache_valid는 어떤 HTTP 응답 코드에 대해 얼마나 오래 캐시를 유지할 것인지를 설정합니다. 이 예시에서는 200 코드는 60분, 404 코드는 1분 동안 캐시를 유지합니다.
proxy_cache_bypass는 캐시를 우회할 HTTP 헤더를 지정합니다.
upstream 블록에서는 웹 서버로 요청을 전달할 upstream 서버를 정의합니다. 이 예시에서는 3개의 서버를 Round-robin 방식으로 사용합니다.
server 블록에서는 기본 서버 설정과 함께 캐시를 적용할 경로들을 설정해주어야 합니다. 이를 위해 proxy_cache_path 디렉티브를 사용하며, 캐시 파일들이 저장될 경로를 설정해주어야 합니다. 또한, 캐시 파일들의 크기와 유효 시간 등을 설정해줄 수도 있습니다. 이렇게 설정한 캐시는 매 요청마다 동적으로 생성되는 응답을 캐싱하여 다음 요청 시에는 캐시된 응답을 바로 전달함으로써 서버의 부하를 줄일 수 있습니다.
만약에 위에서 말한 nginx 캐시 서버에 연결된 web application에서 create, update, delete가 발생한 경우에 캐시는 어떻게 갱신할 수 있어?
Nginx에서는 캐시 갱신을 위한 여러 가지 기술적인 방법을 제공합니다. 가장 기본적인 방법으로는 캐시 유효 시간을 설정하고, 캐시 유효 시간이 만료되면 자동으로 갱신됩니다. 이 방법은 캐시를 얼마나 오랫동안 유지할지에 따라 성능과 적중률을 균형있게 조절할 수 있습니다.
또한, 만약 Web Application에서 데이터가 변경되었을 때 캐시를 갱신하고 싶다면, Nginx에서는 Cache Purge 모듈을 사용할 수 있습니다. Cache Purge 모듈은 특정 URL의 캐시를 삭제하는 기능을 제공하며, HTTP 요청을 통해 캐시를 갱신할 수 있습니다. 이를 위해 Web Application에서 Cache Purge 요청을 보내면, 해당 URL의 캐시가 삭제되고 다음 요청부터는 새로운 응답을 캐싱합니다.
또한, Nginx에서는 Cache Stale 모듈을 제공합니다. Cache Stale 모듈은 만료된 캐시를 사용하되, 동시에 백그라운드에서 새로운 캐시를 생성하도록 할 수 있습니다. 이를 통해 캐시 갱신 시간이 걸리는 상황에서도 캐시를 사용하여 응답 속도를 유지할 수 있습니다.
이렇게 다양한 방법으로 Nginx에서는 캐시 갱신을 제어할 수 있으며, Web Application에서 캐시를 갱신하고자 할 때에는 Cache Purge 모듈을 사용하여 Nginx의 캐시를 갱신할 수 있습니다.
만약에 위에서 말한 nginx 캐시 서버에 연결된 web application에서 create, update, delete가 발생한 경우에 캐시는 어떻게 갱신할 수 있는지 가장 많이 선호하는 방법을 예시와 함께 자세히 알려줘
일반적으로 가장 많이 사용되는 방법은 캐시 무효화(invalidation)입니다.
예를 들어, 웹 어플리케이션에서 게시물이나 상품 정보 등이 업데이트된 경우, 해당 URL의 캐시를 무효화하여 새로운 데이터를 가져와 캐시를 갱신하는 방식입니다.
이를 위해서는 웹 어플리케이션에서 업데이트가 발생할 때, 해당 URL을 무효화하는 신호를 보내는 것이 필요합니다. 보통은 웹 어플리케이션에서 HTTP PURGE 요청을 보내는 방식으로 구현됩니다.
예를 들어, 웹 어플리케이션에서 새로운 게시물을 업로드할 때, 해당 게시물의 URL을 무효화하는 HTTP PURGE 요청을 보내도록 구현할 수 있습니다. 이때, nginx의 캐시는 해당 URL에 대한 캐시를 무효화하고, 새로운 데이터를 가져와 캐시를 갱신합니다.
또한, nginx는 캐시의 유효기간을 설정할 수 있습니다. 예를 들어, 캐시 유효기간을 10분으로 설정하면, 10분 이내에 해당 URL에 대한 요청이 발생하면 캐시를 사용하고, 10분 이후에는 웹 어플리케이션에서 데이터를 가져와 새로운 캐시를 생성합니다.
이렇게 캐시 무효화와 캐시 유효기간 설정을 함께 사용하여, 웹 어플리케이션의 데이터 갱신에 대응할 수 있습니다.
댓글