Nginx ์ฑ๋ฅ ์ต์ ํ
๊ฐ์
Nginx ์ฑ๋ฅ ์ต์ ํ๋ ์์ปค ํ๋ก์ธ์ค ํ๋, gzip ์์ถ, ์บ์ฑ, ์ฐ๊ฒฐ ๊ด๋ฆฌ ๋ฑ์ ํตํด ๋ ์ ์ ๋ฆฌ์์ค๋ก ๋ ๋ง์ ์์ฒญ์ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํ๋๋ก ์ค์ ํ๋ ๊ฒ์ด๋ค.
Nginx๋ ๊ธฐ๋ณธ ์ค์ ๋ง์ผ๋ก๋ ๊ฝค ๋น ๋ฅด์ง๋ง, ๋ช ๊ฐ์ง ์ต์ ํ๋ฅผ ์ ์ฉํ๋ฉด 2~10๋ฐฐ ์ด์ ์ฑ๋ฅ์ ๋์ด์ฌ๋ฆด ์ ์์ด์!
์ฑ๋ฅ ์ต์ ํ๋ ํฌ๊ฒ ์ธ ๊ฐ์ง ๊ด์ ์์ ์ ๊ทผํด์:
1.
๋ ๋ง์ ๋์ ์ ์ ์ฒ๋ฆฌ (์์ปค, ์ฐ๊ฒฐ ๊ด๋ฆฌ)
2.
๋ ๋น ๋ฅธ ์๋ต ์ ๋ฌ (์์ถ, ์บ์ฑ)
3.
๋ ์ ์ ๋ฆฌ์์ค ์ฌ์ฉ (๋ฒํผ, ํ์์์)
์ต์ ํ ์์ญ ์ ์ฒด ๋งต
mindmap
root((Nginx<br/>์ฑ๋ฅ ์ต์ ํ))
์์ปค ํ๋
worker_processes
worker_connections
multi_accept
์์ถ
gzip
gzip_types
gzip_min_length
์บ์ฑ
๋ธ๋ผ์ฐ์ ์บ์ฑ
ํ๋ก์ ์บ์ฑ
expires
์ฐ๊ฒฐ ๊ด๋ฆฌ
keepalive
timeout
TCP ์ต์ ํ
๋ฒํผ
proxy_buffer
client_body_buffer
์ ์ ํ์ผ
sendfile
tcp_nopush
open_file_cacheMermaid
๋ณต์ฌ
1. ์์ปค ํ๋ก์ธ์ค ์ต์ ํ
graph TD
A["Master Process<br/>(์ค์ ๊ด๋ฆฌ)"] --> B["Worker 1"]
A --> C["Worker 2"]
A --> D["Worker 3"]
A --> E["Worker 4"]
B --> B1["์ต๋ 1024 ์ฐ๊ฒฐ"]
C --> C1["์ต๋ 1024 ์ฐ๊ฒฐ"]
D --> D1["์ต๋ 1024 ์ฐ๊ฒฐ"]
E --> E1["์ต๋ 1024 ์ฐ๊ฒฐ"]
F["์ด ๋์ ์ฐ๊ฒฐ = 4 ร 1024 = 4,096"]
style A fill:#FFD700
style F fill:#90EE90Mermaid
๋ณต์ฌ
# ์ ์ญ ์ค์
worker_processes auto; # CPU ์ฝ์ด ์๋งํผ ์๋ ์ค์
worker_rlimit_nofile 65535; # ์์ปค๋น ์ด ์ ์๋ ํ์ผ ์
events {
worker_connections 4096; # ์์ปค๋น ๋์ ์ฐ๊ฒฐ ์
multi_accept on; # ํ ๋ฒ์ ์ฌ๋ฌ ์ฐ๊ฒฐ ์๋ฝ
use epoll; # Linux ์ด๋ฒคํธ ์ฒ๋ฆฌ (๊ฐ์ฅ ํจ์จ์ )
}
Plain Text
๋ณต์ฌ
์ค์ | ๊ธฐ๋ณธ๊ฐ | ๊ถ์ฅ๊ฐ | ์ค๋ช
|
worker_processes | 1 | auto | CPU ์ฝ์ด ์์ ๋์ผํ๊ฒ |
worker_connections | 512 | 1024~4096 | ์๋ฒ ๊ท๋ชจ์ ๋ฐ๋ผ ์กฐ์ |
multi_accept | off | on | ํ ๋ฒ์ ์ฌ๋ฌ ์ฐ๊ฒฐ ๋์ ์๋ฝ |
use | ์๋ | epoll | Linux์์ ๊ฐ์ฅ ํจ์จ์ ์ธ ๋ฐฉ์ |
worker_rlimit_nofile | ์์คํ
๊ธฐ๋ณธ | 65535 | ํ์ผ ๋์คํฌ๋ฆฝํฐ ์ ํ |
์ต๋ ๋์ ์ฐ๊ฒฐ ์ = worker_processes ร worker_connections
์: 4์ฝ์ด ร 4096 = 16,384๊ฐ ๋์ ์ฐ๊ฒฐ!
2. Gzip ์์ถ
gzip ์์ถ์ ์ฌ์ฉํ๋ฉด ์๋ต ํฌ๊ธฐ๋ฅผ 30~70% ์ค์ผ ์ ์์ด์!
graph LR
A["์๋ณธ ์๋ต<br/>100KB"] -->|gzip ์์ถ| B["์์ถ๋ ์๋ต<br/>30KB"]
B -->|๋คํธ์ํฌ ์ ์ก| C["๐ค ๋ธ๋ผ์ฐ์ "]
C -->|์๋ ํด์ | D["์๋ณธ 100KB<br/>ํ์"]
style A fill:#FFB3B3
style B fill:#90EE90Mermaid
๋ณต์ฌ
http {
# gzip ์์ถ ํ์ฑํ
gzip on;
gzip_vary on; # Vary: Accept-Encoding ํค๋ ์ถ๊ฐ
gzip_proxied any; # ํ๋ก์ ์๋ต๋ ์์ถ
gzip_comp_level 6; # ์์ถ ๋ ๋ฒจ (1~9, 6 ๊ถ์ฅ)
gzip_min_length 256; # ์ต์ ํฌ๊ธฐ ์ด์๋ง ์์ถ
gzip_types
text/plain
text/css
text/xml
application/json
application/javascript
application/xml
application/xml+rss
image/svg+xml
font/woff2;
}
Plain Text
๋ณต์ฌ
์ค์ | ๊ถ์ฅ๊ฐ | ์ค๋ช
|
gzip_comp_level | 6 | 1(๋น ๋ฆ, ๋ฎ์ ์์ถ) ~ 9(๋๋ฆผ, ๋์ ์์ถ), 6์ด ์ต์ |
gzip_min_length | 256 | ๋๋ฌด ์์ ํ์ผ์ ์์ถ ํจ๊ณผ ์์ |
gzip_types | ํ
์คํธ ๊ธฐ๋ฐ | ์ด๋ฏธ ์์ถ๋ ํ์ผ(jpg, png, mp4)์ ์ ์ธ |
์ด๋ฏธ์ง(jpg, png)๋ ๋์์(mp4)์ ์ด๋ฏธ ์์ถ๋ ํ์์ด๋ผ gzip ํจ๊ณผ๊ฐ ๊ฑฐ์ ์์ด์. ์คํ๋ ค CPU๋ง ๋ญ๋นํด์!
3. ์บ์ฑ ์ ๋ต
๋ธ๋ผ์ฐ์ ์บ์ฑ
# ์ ์ ์์
โ ์ฅ๊ธฐ ์บ์ฑ (React ๋น๋ ํ์ผ์ฒ๋ผ ํด์๊ฐ ์๋ ๊ฒฝ์ฐ)
location /static/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# ์ผ๋ฐ ์ด๋ฏธ์ง โ ์ค๊ธฐ ์บ์ฑ
location ~* \\.(jpg|jpeg|png|gif|ico|webp)$ {
expires 30d;
add_header Cache-Control "public";
}
# HTML โ ์บ์ฑ ์ ํจ (ํญ์ ์ต์ ๋ฒ์ ์ ๊ณต)
location ~* \\.html$ {
expires -1;
add_header Cache-Control "no-cache";
}
Plain Text
๋ณต์ฌ
ํ์ผ ์ ํ | ์บ์ฑ ๊ธฐ๊ฐ | ์ด์ |
JS/CSS (ํด์ ํฌํจ) | 1๋
| ํ์ผ๋ช
์ ํด์ โ ๋ด์ฉ ๋ณ๊ฒฝ ์ ์ด๋ฆ๋ ๋ณ๊ฒฝ |
์ด๋ฏธ์ง | 30์ผ | ์์ฃผ ์ ๋ฐ๋ |
HTML | ์บ์ฑ ์ ํจ | ํญ์ ์ต์ JS/CSS๋ฅผ ์ฐธ์กฐํด์ผ ํจ |
API ์๋ต | ์บ์ฑ ์ ํจ | ์ค์๊ฐ ๋ฐ์ดํฐ |
ํ๋ก์ ์บ์ฑ (Nginx๊ฐ ๋ฐฑ์๋ ์๋ต์ ์บ์ฑ)
http {
# ์บ์ ์์ญ ์ ์
proxy_cache_path /var/cache/nginx levels=1:2
keys_zone=my_cache:10m
max_size=1g
inactive=60m;
server {
location /api/ {
proxy_pass <http://localhost:8080>;
# ํ๋ก์ ์บ์ฑ ์ ์ฉ
proxy_cache my_cache;
proxy_cache_valid 200 10m; # 200 ์๋ต์ 10๋ถ ์บ์ฑ
proxy_cache_valid 404 1m; # 404 ์๋ต์ 1๋ถ ์บ์ฑ
add_header X-Cache-Status $upstream_cache_status;
}
}
}
Plain Text
๋ณต์ฌ
sequenceDiagram
participant ์ฌ์ฉ์A as ๐ค ์ฌ์ฉ์ A
participant Nginx as ๐ฅ๏ธ Nginx (์บ์)
participant Spring as ๐ Spring Boot
์ฌ์ฉ์A->>Nginx: GET /api/products
Nginx->>Spring: ์บ์ ์์ โ ๋ฐฑ์๋ ์์ฒญ
Spring-->>Nginx: ์ํ ๋ชฉ๋ก (200 OK)
Nginx->>Nginx: ์บ์์ ์ ์ฅ
Nginx-->>์ฌ์ฉ์A: ์๋ต (X-Cache-Status: MISS)
Note over Nginx: 10๋ถ ์ด๋ด ๊ฐ์ ์์ฒญ โ
participant ์ฌ์ฉ์B as ๐ค ์ฌ์ฉ์ B
์ฌ์ฉ์B->>Nginx: GET /api/products
Nginx-->>์ฌ์ฉ์B: ์บ์์์ ์ฆ์ ์๋ต!<br/>(X-Cache-Status: HIT)
Note over Nginx,Spring: Spring Boot์ ์์ฒญ ์ ๊ฐ!<br/>โ ๋ฐฑ์๋ ๋ถํ ๊ฐ์Mermaid
๋ณต์ฌ
4. ์ฐ๊ฒฐ ๊ด๋ฆฌ
http {
# Keep-Alive ์ค์
keepalive_timeout 65; # ์ฐ๊ฒฐ ์ ์ง ์๊ฐ
keepalive_requests 100; # ํ๋์ ์ฐ๊ฒฐ๋ก ์ฒ๋ฆฌํ ์ต๋ ์์ฒญ ์
# TCP ์ต์ ํ
sendfile on; # ์ปค๋ ๋ ๋ฒจ์์ ํ์ผ ์ ์ก (๋ ๋น ๋ฆ)
tcp_nopush on; # ํจํท์ ๋ชจ์์ ํ ๋ฒ์ ์ ์ก
tcp_nodelay on; # ์์ ํจํท๋ ์ฆ์ ์ ์ก
# ํ์์์
client_body_timeout 12; # ์์ฒญ ๋ฐ๋ ์ฝ๊ธฐ ํ์์์
client_header_timeout 12; # ์์ฒญ ํค๋ ์ฝ๊ธฐ ํ์์์
send_timeout 10; # ์๋ต ์ ์ก ํ์์์
}
Plain Text
๋ณต์ฌ
์ค์ | ์ค๋ช
| ํจ๊ณผ |
sendfile on | OS ์ปค๋์์ ์ง์ ํ์ผ ์ ์ก | ์ ์ ํ์ผ ์ ์ก ์๋ ํฅ์ |
tcp_nopush on | ํจํท์ ๋ฌถ์ด์ ์ ์ก | ๋คํธ์ํฌ ํจ์จ์ฑ ์ฆ๊ฐ |
tcp_nodelay on | ์ง์ฐ ์์ด ์ฆ์ ์ ์ก | ์๋ต ์ง์ฐ ๊ฐ์ |
keepalive_timeout | ์ฐ๊ฒฐ ์ฌ์ฌ์ฉ ์๊ฐ | TCP ํธ๋์
ฐ์ดํฌ ์ค๋ฒํค๋ ๊ฐ์ |
5. ํ์ผ ์บ์ (open_file_cache)
http {
# ์์ฃผ ์ ๊ทผํ๋ ํ์ผ ์ ๋ณด๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์บ์ฑ
open_file_cache max=10000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}
Plain Text
๋ณต์ฌ
์ด ์ค์ ์ ํ์ผ์ ๋ฉํ๋ฐ์ดํฐ(ํฌ๊ธฐ, ์์ ์๊ฐ ๋ฑ)๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์บ์ฑํด์. ๋งค ์์ฒญ๋ง๋ค ๋์คํฌ์์ ํ์ผ ์ ๋ณด๋ฅผ ์กฐํํ๋ ๋น์ฉ์ ์ค์ฌ์ฃผ๋ ๊ฑฐ์์!
์ต์ ํ ์ ํ ๋น๊ต
ํญ๋ชฉ | ๊ธฐ๋ณธ ์ค์ | ์ต์ ํ ํ | ๊ฐ์ ๋ฅ |
๋์ ์ฐ๊ฒฐ | ~512 | ~16,384 | 32๋ฐฐ |
HTML ์๋ต ํฌ๊ธฐ | 100KB | 30KB (gzip) | 70% ๊ฐ์ |
์ ์ ํ์ผ ์ ์ก | ์ผ๋ฐ read | sendfile | ~2๋ฐฐ |
๋ฐ๋ณต ์์ฒญ ์๋ต | ๋งค๋ฒ ์ฒ๋ฆฌ | ์บ์ HIT | ์ฆ์ ์๋ต |
์ฐ๊ฒฐ ์๋ฆฝ | ๋งค๋ฒ TCP ํธ๋์
ฐ์ดํฌ | Keep-Alive ์ฌ์ฌ์ฉ | ์ง์ฐ ๊ฐ์ |
์ฑ๋ฅ ์ต์ ํ ์ฒดํฌ๋ฆฌ์คํธ
flowchart TD
A["์ฑ๋ฅ ์ต์ ํ ์ฒดํฌ๋ฆฌ์คํธ"] --> B["1๏ธโฃ worker_processes auto โ"]
A --> C["2๏ธโฃ gzip on โ"]
A --> D["3๏ธโฃ ์ ์ ํ์ผ expires ์ค์ โ"]
A --> E["4๏ธโฃ sendfile + tcp_nopush โ"]
A --> F["5๏ธโฃ keepalive ์ค์ โ"]
A --> G["6๏ธโฃ proxy_cache ์ค์ โ"]
A --> H["7๏ธโฃ open_file_cache ์ค์ โ"]
style B fill:#90EE90
style C fill:#90EE90
style D fill:#90EE90
style E fill:#90EE90
style F fill:#90EE90
style G fill:#87CEEB
style H fill:#87CEEBMermaid
๋ณต์ฌ
ํต์ฌ ์ ๋ฆฌ
์์ปค ํ๋: worker_processes auto + worker_connections 4096
gzip ์์ถ: ํ
์คํธ ๊ธฐ๋ฐ ํ์ผ 30~70% ํฌ๊ธฐ ๊ฐ์ (gzip_comp_level 6)
๋ธ๋ผ์ฐ์ ์บ์ฑ: expires + Cache-Control๋ก ๋ฐ๋ณต ์์ฒญ ์ ๊ฑฐ
ํ๋ก์ ์บ์ฑ: ๋ฐฑ์๋ ์๋ต์ Nginx๊ฐ ์บ์ฑํ์ฌ ๋ถํ ๊ฐ์
TCP ์ต์ ํ: sendfile, tcp_nopush, keepalive๋ก ์ ์ก ํจ์จ ๊ทน๋ํ




