Search

๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ

๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ (Load Balancing)

๊ฐœ์š”

๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ์ด๋ž€ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์„ ์—ฌ๋Ÿฌ ๋Œ€์˜ ์„œ๋ฒ„์— ๋ถ„์‚ฐ์‹œ์ผœ ํ•œ ์„œ๋ฒ„๊ฐ€ ๊ณผ๋ถ€ํ•˜๋˜์ง€ ์•Š๋„๋ก ์กฐ์ ˆํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค.
์‰ฝ๊ฒŒ ๋งํ•ด "์ค„ ์„ธ์šฐ๊ธฐ ๋„์šฐ๋ฏธ"์˜ˆ์š”!
๋งˆํŠธ์— ๊ณ„์‚ฐ๋Œ€๊ฐ€ 1๊ฐœ๋ผ๋ฉด ์•„๋ฌด๋ฆฌ ์ง์›์ด ๋น ๋ฅด๊ฒŒ ์ผํ•ด๋„ ์†๋‹˜์ด ๋ชฐ๋ฆฌ๋ฉด ์ค„์ด ์—„์ฒญ ๊ธธ์–ด์ง€์ฃ . ๊ทธ๋Ÿฐ๋ฐ ๊ณ„์‚ฐ๋Œ€๋ฅผ 3~4๊ฐœ๋กœ ๋Š˜๋ฆฌ๊ณ  "์†๋‹˜ ์—ฌ๊ธฐ๋กœ ์˜ค์„ธ์š”, ์ €์ชฝ์œผ๋กœ ์˜ค์„ธ์š”" ํ•˜๊ณ  ์•ˆ๋‚ดํ•ด์ฃผ๋Š” ์ง์›์ด ์žˆ๋‹ค๋ฉด? ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”!
Nginx๊ฐ€ ๋ฐ”๋กœ ๊ทธ ์•ˆ๋‚ด ์ง์› ์—ญํ• ์„ ํ•˜๋Š” ๊ฑฐ์˜ˆ์š”. ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ์—ฌ๋Ÿฌ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„ ์ค‘ ์ ์ ˆํ•œ ๊ณณ์œผ๋กœ ๋ถ„์‚ฐ์‹œ์ผœ ์ฃผ๋Š” ๊ฑฐ์ฃ .
๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ์„ ์“ฐ๋ฉด:
โ€ข
๊ณ ๊ฐ€์šฉ์„ฑ โ€” ํ•œ ์„œ๋ฒ„๊ฐ€ ์ฃฝ์–ด๋„ ๋‹ค๋ฅธ ์„œ๋ฒ„๊ฐ€ ์ฒ˜๋ฆฌ
โ€ข
์„ฑ๋Šฅ ํ–ฅ์ƒ โ€” ํŠธ๋ž˜ํ”ฝ์„ ๋ถ„์‚ฐํ•ด ์‘๋‹ต ์†๋„ ์ฆ๊ฐ€
โ€ข
์ˆ˜ํ‰ ํ™•์žฅ โ€” ์„œ๋ฒ„๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์„ฑ๋Šฅ์ด ์„ ํ˜•์ ์œผ๋กœ ์ฆ๊ฐ€
โ€ข
๋ฌด์ค‘๋‹จ ๋ฐฐํฌ โ€” ์„œ๋ฒ„ ํ•˜๋‚˜์”ฉ ๋‚ด๋ ธ๋‹ค ์˜ฌ๋ฆฌ๋ฉฐ ์—…๋ฐ์ดํŠธ

๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ ์•„ํ‚คํ…์ฒ˜

graph TD
    A["๐Ÿ‘ค ํด๋ผ์ด์–ธํŠธ 1"] -->|"์š”์ฒญ"| LB
    B["๐Ÿ‘ค ํด๋ผ์ด์–ธํŠธ 2"] -->|"์š”์ฒญ"| LB
    C["๐Ÿ‘ค ํด๋ผ์ด์–ธํŠธ 3"] -->|"์š”์ฒญ"| LB
    D["๐Ÿ‘ค ํด๋ผ์ด์–ธํŠธ 4"] -->|"์š”์ฒญ"| LB

    LB["โš–๏ธ Nginx<br/>๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ<br/>:80 / :443"]

    LB -->|"์š”์ฒญ 1"| S1["๐Ÿ–ฅ๏ธ Server 1<br/>:8080"]
    LB -->|"์š”์ฒญ 2"| S2["๐Ÿ–ฅ๏ธ Server 2<br/>:8081"]
    LB -->|"์š”์ฒญ 3"| S3["๐Ÿ–ฅ๏ธ Server 3<br/>:8082"]

    style LB fill:#FFD700
    style S1 fill:#87CEEB
    style S2 fill:#87CEEB
    style S3 fill:#87CEEB
Mermaid
๋ณต์‚ฌ

๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋น„๊ต

์•Œ๊ณ ๋ฆฌ์ฆ˜
Nginx ์„ค์ •
๋ถ„๋ฐฐ ๋ฐฉ์‹
์ ํ•ฉํ•œ ์ƒํ™ฉ
Round Robin
(๊ธฐ๋ณธ๊ฐ’)
์ˆœ์„œ๋Œ€๋กœ ๋Œ์•„๊ฐ€๋ฉฐ
์„œ๋ฒ„ ์„ฑ๋Šฅ์ด ๋™์ผํ•  ๋•Œ
Least Connections
least_conn;
์—ฐ๊ฒฐ ์ˆ˜ ์ ์€ ์„œ๋ฒ„ ์šฐ์„ 
์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด ๋‹ค์–‘ํ•  ๋•Œ
IP Hash
ip_hash;
ํด๋ผ์ด์–ธํŠธ IP ๊ธฐ์ค€ ๊ณ ์ •
์„ธ์…˜ ์œ ์ง€๊ฐ€ ํ•„์š”ํ•  ๋•Œ
Weighted
weight=N;
๋น„์œจ์— ๋”ฐ๋ผ ๋ถ„๋ฐฐ
์„œ๋ฒ„ ์„ฑ๋Šฅ์ด ๋‹ค๋ฅผ ๋•Œ
Random
random;
๋ฌด์ž‘์œ„ ๋ถ„๋ฐฐ
๊ฐ„๋‹จํ•œ ๋ถ„์‚ฐ์ด ํ•„์š”ํ•  ๋•Œ
Hash
hash $๋ณ€์ˆ˜;
ํŠน์ • ๊ฐ’ ๊ธฐ์ค€ ๊ณ ์ •
URL ์บ์‹ฑ ํšจ์œจํ™”

upstream ๋ธ”๋ก โ€” ํ•ต์‹ฌ ์„ค์ •

๋ชจ๋“  ๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ์˜ ์‹œ์ž‘์€ upstream ๋ธ”๋ก์ด์—์š”!
# upstream = ๋ฐฑ์—”๋“œ ์„œ๋ฒ„ ๊ทธ๋ฃน์„ ์ •์˜ํ•˜๋Š” ๋ธ”๋ก upstream backend { server localhost:8080; server localhost:8081; server localhost:8082; } server { listen 80; server_name example.com; location / { proxy_pass <http://backend>; # upstream ์ด๋ฆ„์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ } }
Plain Text
๋ณต์‚ฌ
upstream ๋ธ”๋ก์— ์„œ๋ฒ„ ์ฃผ์†Œ๋ฅผ ๋‚˜์—ดํ•˜๋ฉด, Nginx๊ฐ€ ์•Œ์•„์„œ ๋ถ„์‚ฐํ•ด์ค˜์š”!

์•Œ๊ณ ๋ฆฌ์ฆ˜๋ณ„ ์ƒ์„ธ ์„ค์ •

1. Round Robin (๋ผ์šด๋“œ ๋กœ๋นˆ) โ€” ๊ธฐ๋ณธ๊ฐ’

sequenceDiagram
    participant LB as โš–๏ธ Nginx
    participant S1 as ๐Ÿ–ฅ๏ธ Server 1
    participant S2 as ๐Ÿ–ฅ๏ธ Server 2
    participant S3 as ๐Ÿ–ฅ๏ธ Server 3

    LB->>S1: ์š”์ฒญ 1
    LB->>S2: ์š”์ฒญ 2
    LB->>S3: ์š”์ฒญ 3
    LB->>S1: ์š”์ฒญ 4 (๋‹ค์‹œ ์ฒ˜์Œ์œผ๋กœ)
    LB->>S2: ์š”์ฒญ 5
Mermaid
๋ณต์‚ฌ
upstream backend { # ๋ณ„๋„ ์„ค์ • ์—†์œผ๋ฉด ์ž๋™์œผ๋กœ ๋ผ์šด๋“œ ๋กœ๋นˆ server localhost:8080; server localhost:8081; server localhost:8082; }
Plain Text
๋ณต์‚ฌ
ํŠน์ง•: ๊ฐ€์žฅ ๋‹จ์ˆœํ•˜๊ณ  ๊ณตํ‰ํ•˜๊ฒŒ ๋ถ„๋ฐฐ. ์„œ๋ฒ„ ์„ฑ๋Šฅ์ด ๋™์ผํ•œ ๊ฒฝ์šฐ ์ตœ์ ์ด์—์š”.

2. Least Connections (์ตœ์†Œ ์—ฐ๊ฒฐ) โ€” ์‹ค๋ฌด ์ถ”์ฒœ

graph LR
    LB["โš–๏ธ Nginx"] -->|"๋‹ค์Œ ์š”์ฒญ"| S2

    S1["๐Ÿ–ฅ๏ธ Server 1<br/>ํ˜„์žฌ ์—ฐ๊ฒฐ: 10๊ฐœ"] -.->|"๋ฐ”์จ"| LB
    S2["๐Ÿ–ฅ๏ธ Server 2<br/>ํ˜„์žฌ ์—ฐ๊ฒฐ: 2๊ฐœ โญ"] -.->|"์—ฌ์œ  ์žˆ์Œ"| LB
    S3["๐Ÿ–ฅ๏ธ Server 3<br/>ํ˜„์žฌ ์—ฐ๊ฒฐ: 7๊ฐœ"] -.->|"๋ณดํ†ต"| LB

    style S2 fill:#90EE90
Mermaid
๋ณต์‚ฌ
upstream backend { least_conn; # ์—ฐ๊ฒฐ ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ์ ์€ ์„œ๋ฒ„๋กœ ์š”์ฒญ ์ „๋‹ฌ server localhost:8080; server localhost:8081; server localhost:8082; }
Plain Text
๋ณต์‚ฌ
ํŠน์ง•: ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด ๋“ค์‘ฅ๋‚ ์‘ฅํ•œ API ์„œ๋ฒ„์— ๋”ฑ! ํŒŒ์ผ ์—…๋กœ๋“œ, ๋™์˜์ƒ ์ฒ˜๋ฆฌ ๋“ฑ์— ์œ ๋ฆฌํ•ด์š”.

3. IP Hash โ€” ์„ธ์…˜ ๊ณ ์ •

graph LR
    C1["๐Ÿ‘ค IP: 1.1.1.1"] -->|"ํ•ญ์ƒ"| S1["๐Ÿ–ฅ๏ธ Server 1"]
    C2["๐Ÿ‘ค IP: 2.2.2.2"] -->|"ํ•ญ์ƒ"| S2["๐Ÿ–ฅ๏ธ Server 2"]
    C3["๐Ÿ‘ค IP: 3.3.3.3"] -->|"ํ•ญ์ƒ"| S1["๐Ÿ–ฅ๏ธ Server 1"]
    C4["๐Ÿ‘ค IP: 4.4.4.4"] -->|"ํ•ญ์ƒ"| S3["๐Ÿ–ฅ๏ธ Server 3"]

    LB["โš–๏ธ Nginx<br/>(ip_hash)"] --- C1
    LB --- C2
    LB --- C3
    LB --- C4

    style LB fill:#FFD700
Mermaid
๋ณต์‚ฌ
upstream backend { ip_hash; # ํด๋ผ์ด์–ธํŠธ IP๋ฅผ ํ•ด์‹œํ•ด์„œ ํ•ญ์ƒ ๊ฐ™์€ ์„œ๋ฒ„๋กœ server localhost:8080; server localhost:8081; server localhost:8082; }
Plain Text
๋ณต์‚ฌ
ํŠน์ง•: ๊ฐ™์€ ์‚ฌ์šฉ์ž๋Š” ํ•ญ์ƒ ๊ฐ™์€ ์„œ๋ฒ„์— ์ ‘์†ํ•ด์š”. ๋กœ๊ทธ์ธ ์„ธ์…˜์ด ์„œ๋ฒ„์— ์ €์žฅ๋œ ๊ฒฝ์šฐ ํ•„์ˆ˜! ๋‹จ, ์„œ๋ฒ„๊ฐ€ ๋‹ค์šด๋˜๋ฉด ์„ธ์…˜์ด ๋‚ ์•„๊ฐˆ ์ˆ˜ ์žˆ์–ด์š”.

4. Weighted (๊ฐ€์ค‘์น˜)

graph LR
    LB["โš–๏ธ Nginx"] -->|"6๋ฒˆ ์ค‘ 3๋ฒˆ"| S1["๐Ÿ–ฅ๏ธ Server 1<br/>weight=3<br/>(๊ณ ์„ฑ๋Šฅ ์„œ๋ฒ„)"]
    LB -->|"6๋ฒˆ ์ค‘ 2๋ฒˆ"| S2["๐Ÿ–ฅ๏ธ Server 2<br/>weight=2<br/>(์ค‘๊ฐ„ ์„œ๋ฒ„)"]
    LB -->|"6๋ฒˆ ์ค‘ 1๋ฒˆ"| S3["๐Ÿ–ฅ๏ธ Server 3<br/>weight=1<br/>(์ €์„ฑ๋Šฅ ์„œ๋ฒ„)"]

    style S1 fill:#90EE90
    style S2 fill:#FFD700
    style S3 fill:#FFB366
Mermaid
๋ณต์‚ฌ
upstream backend { server localhost:8080 weight=3; # 3/6 = 50% ํŠธ๋ž˜ํ”ฝ server localhost:8081 weight=2; # 2/6 = 33% ํŠธ๋ž˜ํ”ฝ server localhost:8082 weight=1; # 1/6 = 17% ํŠธ๋ž˜ํ”ฝ }
Plain Text
๋ณต์‚ฌ
ํŠน์ง•: ์„œ๋ฒ„ ์‚ฌ์–‘์ด ๋‹ค๋ฅผ ๋•Œ ์œ ์šฉํ•ด์š”. ๊ณ ์„ฑ๋Šฅ ์„œ๋ฒ„์— ๋” ๋งŽ์€ ์š”์ฒญ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์–ด์š”.

์„œ๋ฒ„ ์ƒํƒœ ์„ค์ •

์„œ๋ฒ„๋งˆ๋‹ค ํŠน์ˆ˜ ์ƒํƒœ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์–ด์š”!
upstream backend { server localhost:8080; # ์ •์ƒ ์„œ๋ฒ„ server localhost:8081 down; # ์™„์ „ ๋น„ํ™œ์„ฑํ™” (์œ ์ง€๋ณด์ˆ˜ ์ค‘) server localhost:8082 backup; # ํ‰์†Œ์—” ์•ˆ ์“ฐ๊ณ  ๋‹ค๋ฅธ ์„œ๋ฒ„ ๋ชจ๋‘ ๋‹ค์šด ์‹œ ์‚ฌ์šฉ server localhost:8083 max_fails=3 # 3๋ฒˆ ์‹คํŒจํ•˜๋ฉด fail_timeout=30s; # 30์ดˆ๊ฐ„ ์ œ์™ธ }
Plain Text
๋ณต์‚ฌ
์˜ต์…˜
์„ค๋ช…
์‚ฌ์šฉ ์ƒํ™ฉ
weight=N
๋ถ„๋ฐฐ ๋น„์œจ ์กฐ์ •
์„œ๋ฒ„ ์„ฑ๋Šฅ ์ฐจ์ด๊ฐ€ ์žˆ์„ ๋•Œ
max_fails=N
N๋ฒˆ ์‹คํŒจ ์‹œ ๋น„ํ™œ์„ฑํ™”
์ž๋™ ์žฅ์•  ๊ฐ์ง€
fail_timeout=Ns
N์ดˆ ํ›„ ์žฌ์‹œ๋„
max_fails์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ
down
์„œ๋ฒ„ ์™„์ „ ๋น„ํ™œ์„ฑํ™”
์œ ์ง€๋ณด์ˆ˜
backup
์˜ˆ๋น„ ์„œ๋ฒ„
๋ชจ๋“  ์„œ๋ฒ„ ๋‹ค์šด ์‹œ ํˆฌ์ž…
max_conns=N
์ตœ๋Œ€ ๋™์‹œ ์—ฐ๊ฒฐ ์ˆ˜ ์ œํ•œ
์„œ๋ฒ„ ๋ณดํ˜ธ

Health Check (ํ—ฌ์Šค ์ฒดํฌ)

์„œ๋ฒ„๊ฐ€ ์‚ด์•„์žˆ๋Š”์ง€ ์ฃผ๊ธฐ์ ์œผ๋กœ ํ™•์ธ!
stateDiagram-v2
    [*] --> Active: ์„œ๋ฒ„ ์ •์ƒ
    Active --> Inactive: ์š”์ฒญ ์‹คํŒจ (max_fails ์ดˆ๊ณผ)
    Inactive --> Active: fail_timeout ํ›„ ์žฌ์‹œ๋„ ์„ฑ๊ณต
    Inactive --> Inactive: ์žฌ์‹œ๋„ ์‹คํŒจ
Mermaid
๋ณต์‚ฌ

ํŒจ์‹œ๋ธŒ ํ—ฌ์Šค ์ฒดํฌ (Nginx ๋ฌด๋ฃŒ)

์š”์ฒญ์ด ์‹คํŒจํ•˜๋ฉด ์ž๋™์œผ๋กœ ์„œ๋ฒ„๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•ด์š”:
upstream backend { server localhost:8080 max_fails=3 fail_timeout=30s; server localhost:8081 max_fails=3 fail_timeout=30s; } server { location / { proxy_pass <http://backend>; # ์‹คํŒจ ์‹œ ๋‹ค์Œ ์„œ๋ฒ„๋กœ ์ž๋™ ์žฌ์‹œ๋„ proxy_next_upstream error timeout http_500 http_502 http_503; proxy_next_upstream_tries 2; } }
Plain Text
๋ณต์‚ฌ

์•กํ‹ฐ๋ธŒ ํ—ฌ์Šค ์ฒดํฌ (Nginx Plus ์œ ๋ฃŒ)

upstream backend { server localhost:8080; server localhost:8081; } server { location / { proxy_pass <http://backend>; health_check interval=5s fails=2 passes=2 uri=/health; } }
Plain Text
๋ณต์‚ฌ
๋ฌด๋ฃŒ ๋ฒ„์ „์—์„œ ํ—ฌ์Šค ์ฒดํฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด nginx_upstream_check_module ๊ฐ™์€ ์จ๋“œํŒŒํ‹ฐ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ผ์š”.

Keepalive ์—ฐ๊ฒฐ ์ตœ์ ํ™”

๋ฐฑ์—”๋“œ ์„œ๋ฒ„์™€ ์—ฐ๊ฒฐ์„ ์žฌ์‚ฌ์šฉํ•ด์„œ ์„ฑ๋Šฅ์„ ๋†’์—ฌ์š”!
upstream backend { server localhost:8080; server localhost:8081; keepalive 32; # ์ตœ๋Œ€ 32๊ฐœ ์—ฐ๊ฒฐ ์žฌ์‚ฌ์šฉ (์ปค๋„ฅ์…˜ ํ’€) } server { location /api/ { proxy_pass <http://backend>; # keepalive๋ฅผ ์“ฐ๋ ค๋ฉด ์•„๋ž˜ ๋‘ ์ค„์ด ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•ด์š”! proxy_http_version 1.1; proxy_set_header Connection ""; } }
Plain Text
๋ณต์‚ฌ
keepalive ์—†์ด: ์š”์ฒญํ•  ๋•Œ๋งˆ๋‹ค TCP ์—ฐ๊ฒฐ ์ƒˆ๋กœ ๋งบ์Œ โ†’ ๋А๋ฆผ
keepalive ์žˆ์ด: ๊ธฐ์กด ์—ฐ๊ฒฐ ์žฌ์‚ฌ์šฉ โ†’ ๋น ๋ฆ„, ์„œ๋ฒ„ ๋ฆฌ์†Œ์Šค ์ ˆ์•ฝ

์‹ค์ „ ์„ค์ • ์˜ˆ์ œ

Spring Boot ๊ณ ๊ฐ€์šฉ์„ฑ ๊ตฌ์„ฑ

upstream spring_backend { least_conn; server 10.0.0.10:8080 weight=2 max_fails=3 fail_timeout=30s; server 10.0.0.11:8080 weight=2 max_fails=3 fail_timeout=30s; server 10.0.0.12:8080 weight=1 max_fails=3 fail_timeout=30s backup; keepalive 64; } server { listen 80; server_name api.example.com; location / { proxy_pass http://spring_backend; proxy_http_version 1.1; proxy_set_header Connection ""; 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 $scheme; proxy_connect_timeout 5s; proxy_read_timeout 60s; proxy_send_timeout 60s; proxy_next_upstream error timeout http_500 http_502 http_503; proxy_next_upstream_tries 2; } }
Plain Text
๋ณต์‚ฌ

๋ฌด์ค‘๋‹จ ๋ฐฐํฌ ํ”Œ๋กœ์šฐ

sequenceDiagram
    participant Dev as ๐Ÿ‘จโ€๐Ÿ’ป ๊ฐœ๋ฐœ์ž
    participant LB as โš–๏ธ Nginx
    participant S1 as ๐Ÿ–ฅ๏ธ Server 1
    participant S2 as ๐Ÿ–ฅ๏ธ Server 2

    Note over S1,S2: ํ‰์ƒ์‹œ โ€” ๋‘ ์„œ๋ฒ„ ๋ชจ๋‘ ํŠธ๋ž˜ํ”ฝ ์ฒ˜๋ฆฌ

    Dev->>S1: ๋ฐฐํฌ ์‹œ์ž‘ (S1 ์ข…๋ฃŒ)
    Note over LB: S1 max_fails ๊ฐ์ง€ โ†’ ์ž๋™ ์ œ์™ธ
    LB->>S2: S2๋กœ๋งŒ ์š”์ฒญ ์ „๋‹ฌ

    Dev->>S1: ์ƒˆ ๋ฒ„์ „ ๋ฐฐํฌ ํ›„ ๊ธฐ๋™
    Note over LB: S1 ๋ณต๊ตฌ ๊ฐ์ง€ โ†’ ์ž๋™ ํฌํ•จ
    LB->>S1: S1, S2 ์–‘์ชฝ์œผ๋กœ ๋ถ„๋ฐฐ ์žฌ๊ฐœ

    Dev->>S2: S2๋„ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋ฐฐํฌ
    Note over LB: S2 max_fails ๊ฐ์ง€ โ†’ ์ž๋™ ์ œ์™ธ
    LB->>S1: S1์œผ๋กœ๋งŒ ์š”์ฒญ ์ „๋‹ฌ

    Dev->>S2: ์ƒˆ ๋ฒ„์ „ ๋ฐฐํฌ ํ›„ ๊ธฐ๋™
    Note over S1,S2: ๋ฐฐํฌ ์™„๋ฃŒ โ€” ๋‘ ์„œ๋ฒ„ ๋ชจ๋‘ ์ตœ์‹  ๋ฒ„์ „
Mermaid
๋ณต์‚ฌ

์„ฑ๋Šฅ ๋น„๊ต

๊ตฌ์„ฑ
์ดˆ๋‹น ์ฒ˜๋ฆฌ ์š”์ฒญ
์žฅ์•  ๋ณต๊ตฌ
๋ฐฐํฌ ๋ฐฉ์‹
์„œ๋ฒ„ 1๋Œ€
1,000 RPS
๋ถˆ๊ฐ€
์„œ๋น„์Šค ์ค‘๋‹จ
์„œ๋ฒ„ 2๋Œ€ (๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ)
2,000 RPS
๊ฐ€๋Šฅ
๋ฌด์ค‘๋‹จ
์„œ๋ฒ„ 4๋Œ€ (๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ)
4,000 RPS
๊ฐ€๋Šฅ
๋ฌด์ค‘๋‹จ
RPS(Requests Per Second) โ€” ์ดˆ๋‹น ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅํ•œ ์š”์ฒญ ์ˆ˜. ์„œ๋ฒ„๋ฅผ N๋ฐฐ ๋Š˜๋ฆฌ๋ฉด ์ฒ˜๋ฆฌ๋Ÿ‰๋„ ๊ฑฐ์˜ N๋ฐฐ!

๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ ์ƒํƒœ ํ™•์ธ

# Nginx ์„ค์ • ํ…Œ์ŠคํŠธ nginx -t # ์„ค์ • ์ ์šฉ systemctl reload nginx # ์—๋Ÿฌ ๋กœ๊ทธ ์‹ค์‹œ๊ฐ„ ํ™•์ธ tail -f /var/log/nginx/error.log # ์—ฐ๊ฒฐ ์ƒํƒœ ํ™•์ธ ss -tnp | grep nginx # ๊ฐ upstream ์„œ๋ฒ„ ์‘๋‹ต ํ…Œ์ŠคํŠธ curl -H "Host: api.example.com" <http://localhost>
Bash
๋ณต์‚ฌ

์ฒดํฌ๋ฆฌ์ŠคํŠธ

upstream ๋ธ”๋ก์— ๋ฐฑ์—”๋“œ ์„œ๋ฒ„ ์ฃผ์†Œ ๋ชจ๋‘ ๋“ฑ๋ก?
๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์„ ํƒ ์™„๋ฃŒ? (round robin / least_conn / ip_hash)
max_fails, fail_timeout ์„ค์ •์œผ๋กœ ์ž๋™ ์žฅ์•  ๊ฐ์ง€?
keepalive ์„ค์ •์œผ๋กœ ์—ฐ๊ฒฐ ์žฌ์‚ฌ์šฉ ์ตœ์ ํ™”?
proxy_next_upstream์œผ๋กœ ์‹คํŒจ ์‹œ ์ž๋™ ์žฌ์‹œ๋„?
backup ์„œ๋ฒ„ ์ง€์ • ์™„๋ฃŒ?
nginx -t ์„ค์ • ํ…Œ์ŠคํŠธ ํ†ต๊ณผ?
๊ฐ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„ ์ง์ ‘ ์ ‘์† ํ…Œ์ŠคํŠธ ์™„๋ฃŒ?
๋ฌด์ค‘๋‹จ ๋ฐฐํฌ ํ๋ฆ„ ๊ฒ€์ฆ ์™„๋ฃŒ?
ํ—ฌ์Šค ์ฒดํฌ ์—”๋“œํฌ์ธํŠธ(/health) ๊ตฌ์„ฑ ์™„๋ฃŒ?

ํ•ต์‹ฌ ์ •๋ฆฌ

๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ = ์—ฌ๋Ÿฌ ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ถ„์‚ฐํ•ด ์„ฑ๋Šฅ๊ณผ ์•ˆ์ •์„ฑ์„ ๋™์‹œ์— ํ™•๋ณด
upstream ๋ธ”๋ก = ๋ฐฑ์—”๋“œ ์„œ๋ฒ„ ๊ทธ๋ฃน ์ •์˜ โ†’ proxy_pass๋กœ ์—ฐ๊ฒฐ
์•Œ๊ณ ๋ฆฌ์ฆ˜ ์„ ํƒ: ๊ธฐ๋ณธ์€ Round Robin, ์ฒ˜๋ฆฌ ์‹œ๊ฐ„ ๋‹ค์–‘ํ•˜๋ฉด Least Conn, ์„ธ์…˜ ์œ ์ง€ ํ•„์š”ํ•˜๋ฉด IP Hash
max_fails + fail_timeout = ์ž๋™ ์žฅ์•  ๊ฐ์ง€ ๋ฐ ๋ณต๊ตฌ (ํŒจ์‹œ๋ธŒ ํ—ฌ์Šค ์ฒดํฌ)
keepalive = ์—ฐ๊ฒฐ ์žฌ์‚ฌ์šฉ์œผ๋กœ ์„ฑ๋Šฅ ํ–ฅ์ƒ (proxy_http_version 1.1 + Connection "" ํ•„์ˆ˜)
backup ์„œ๋ฒ„ = ๋ชจ๋“  ์„œ๋ฒ„ ๋‹ค์šด ์‹œ ์ตœํ›„์˜ ๋ณด๋ฃจ
๋ฌด์ค‘๋‹จ ๋ฐฐํฌ = ์„œ๋ฒ„ ํ•˜๋‚˜์”ฉ ๋‚ด๋ ธ๋‹ค ์˜ฌ๋ฆฌ๋ฉฐ ์„œ๋น„์Šค ์ค‘๋‹จ ์—†์ด ์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅ