BackEnd/Server

Apache JMeter๋กœ NGNIX์˜ ๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ

ddonghyeo 2023. 9. 2. 00:17

https://nginxstore.com/blog/nginx/nginx-%EC%84%B1%EB%8A%A5-%ED%99%95%EC%9E%A5%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%84%A4%EA%B3%84-%EB%B0%A9%EB%B2%95/

NGINX๋Š” Master Process์•„๋ž˜ ์—ฌ๋Ÿฌ worker์™€ helper๊ฐ€ ์žˆ๋‹ค.

# ps -ef --forest | grep nginx
root     32475     1  0 13:36 ?        00:00:00 nginx: master process /usr/sbin/nginx 
                                                -c /etc/nginx/nginx.conf
nginx    32476 32475  0 13:36 ?        00:00:00  _ nginx: worker process
nginx    32477 32475  0 13:36 ?        00:00:00  _ nginx: worker process
nginx    32479 32475  0 13:36 ?        00:00:00  _ nginx: worker process
nginx    32480 32475  0 13:36 ?        00:00:00  _ nginx: worker process
nginx    32481 32475  0 13:36 ?        00:00:00  _ nginx: cache manager process
nginx    32482 32475  0 13:36 ?        00:00:00  _ nginx: cache loader process

๋‚˜๋Š” ์ด NGINX์˜ process์™€ worker์˜ ํšจ๊ณผ๋ฅผ Apache JMeter๋ฅผ ํ†ตํ•ด์„œ ํ…Œ์ŠคํŠธ ํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

- Apache JMeter ์„ค์น˜

brew install jmeter

์œ„ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด JMeter๋ฅผ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

jmeter

์œ„ ๋ช…๋ น์–ด๋กœ JMeter๋ฅผ ์ผœ์ฃผ์ž.

- JMeter ์„ค์ •

Thread Group ๋งŒ๋“ค๊ธฐ

Test Plan์€ ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณผ ๊ณ„ํš์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

์šฐํด๋ฆญ -> Add -> Threads -> Thread Group์„ ๋ˆŒ๋Ÿฌ์„œ ์ƒˆ๋กœ์šด Thread Group์„ ์ƒ์„ฑํ•ด์ค€๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ ๊ทธ๋ฃน์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๋ฐ,

์—ฌ๊ธฐ์— ํ•ด๋‹นํ•˜๋Š” ์˜ต์…˜๋“ค์„ ๋ณด์ž.

 

Number of Threads

๋ง ๊ทธ๋Œ€๋กœ ์Šค๋ ˆ๋“œ์˜ ์ˆ˜์ด๋‹ค. HTTP์š”์ฒญ์„ ํ•˜๋Š” ์œ ์ €์˜ ์ˆ˜๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋˜๊ฒ ๋‹ค.
1000์œผ๋กœ ์„ค์ •ํ•˜๋ฉด 1000๋ช…์˜ ์œ ์ €๊ฐ€ HTTP์š”์ฒญ์„ ํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.
Ramp-up peroid

์Šค๋ ˆ๋“œ๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ์‹œ๊ฐ„์„ ๋œปํ•œ๋‹ค.
์ฆ‰, Number of Threads = 1000, Ramp-up = 10์ด๋ฉด
1000๋ช…์˜ ์œ ์ €๊ฐ€ ์ƒ์„ฑ๋˜๋Š”๋ฐ 10์ดˆ๊ฐ€ ๊ฑธ๋ฆฐ๋‹ค.
์ฆ‰ 1์ดˆ์— 100ํšŒ์˜ HTTP์š”์ฒญ์ด ์ผ์–ด๋‚  ๊ฒƒ์ด๋‹ค.

๋‚˜๋Š” Ramp-up์„ 0์œผ๋กœ ์ ‘์†ํ•ด์„œ 1000๋ช…์˜ ์œ ์ €๊ฐ€ ๋™์‹œ์ ‘์†ํ•˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณผ ๊ฒƒ์ด๋‹ค.

Loop Count

๋ฐ˜๋ณต ํšŸ์ˆ˜์ด๋‹ค.
ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•ด๋‹น ์ž‘์—…์„ ๋ฐ˜๋ณตํ•  ํšŸ์ˆ˜๋ฅผ ๋œปํ•œ๋‹ค.
Number of Threads = 1000, Loop Count =10 ์ด๋ฉด ์ด 10000๋ฒˆ ์š”์ฒญ์ด ์ƒ์„ฑ๋œ๋‹ค.

 

HTTP Request ๋งŒ๋“ค๊ธฐ

์ด์ œ ๋งŒ๋“ค์—ˆ๋˜ Thread Group ์šฐํด๋ฆญ -> Add -> Sampler -> HTTP Request๋ฅผ ๋ˆŒ๋Ÿฌ์„œ Request ์„ค์ •์„ ํ•ด์ฃผ์ž.

์—ฌ๊ธฐ๋‹ค๊ฐ€ HTTP ์š”์ฒญ์„ ํ…Œ์ŠคํŠธํ•  Request ์„ค์ •์„ ์ ์–ด๋„ฃ์œผ๋ฉด ๋˜๊ฒ ๋‹ค.

 

 

Listener ๋งŒ๋“ค๊ธฐ

์ด์ œ HTTP ์š”์ฒญ์„ ํ†ตํ•ด ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ถ„์„ํ•  ์ž๋ฃŒ๋ฅผ ๋ณด๊ธฐ ์œ„ํ•ด Listner๋ฅผ ๋งŒ๋“ค์–ด์ค˜์•ผํ•œ๋‹ค.

์›ํ•˜๋Š” ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ์„œ ์„ ํƒํ•˜๋ฉด ๋œ๋‹ค(์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค).

์ด์ œ ๋ชจ๋“  ์ค€๋น„๋Š” ์™„๋ฃŒ๋๋‹ค. Start๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

ํ…Œ์ŠคํŠธ ํ•˜๊ธฐ์ „์— ์ด์ „ ๊ธฐ๋ก๋“ค์„ ์ง€์šฐ๊ณ  ํ…Œ์ŠคํŠธ ํ•˜์ž.

 

 

 

- ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ

Settings

CPU : AWS t2.medium - 2 vCPU
Framework : Django
Protocol : uWSGI

Request:

์ด 10000๋ช…์˜ ์œ ์ €๊ฐ€ html, js, cssํŒŒ์ผ ์„ธ ๊ฐœ๋ฅผ ๋ฐ›๋Š”๋‹ค๊ณ  ๊ฐ€์ •ํ•ด์„œ Loop Count๋ฅผ 3์œผ๋กœ ์ •ํ–ˆ๋‹ค.
๋ชจ๋“  ์œ ์ €๊ฐ€ ๋™์‹œ ์ ‘์†์„ ํ•œ๋‹ค.

 

 

 

case 1.

[NGINX]
worker_processes : 1
worker_connections : 1024

[uWSGI]
processes : 5

 

- ๊ฒฐ๊ณผ

๋ฌด๋ ค 32%, ์•ฝ 1/3์ด Error๋ฅผ ๋ฐ›์€ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. Error ๋กœ๊ทธ๋Š” Socket Closed์˜€๋‹ค.

๋™์‹œ ์ ‘์†์ด ๊ฐ€๋Šฅํ•œ ์ˆ˜๋ฅผ ์ดˆ๊ณผํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์†Œ์ผ“์ด ๋‹ซํžŒ ๊ฒƒ์ด๋‹ค.

์œ ์ €๊ฐ€ ๋งŽ์ด ๋ชฐ๋ฆฌ๋Š” ์ดˆ๋ฐ˜, ์‘๋‹ต ์‹œ๊ฐ„์ด ์•ฝ 3000ms(3์ดˆ)๋Œ€์ธ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ดˆ๋ฐ˜ ์œ ์ €๊ฐ€ ์ฒ˜๋ฆฌ๋œ ์ดํ›„๋กœ๋Š” 1000ms(1์ดˆ)์ด๋‚ด๋ฅผ ๋จธ๋ฌผ๋‹ค๊ฐ€ ์•ˆ์ •ํ™”๋œ ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

 

 

case 2.

[NGINX]
worker_processes : 2
worker_connections : 1024

[uWSGI]
processes : 5

 

process๋ฅผ ํ•˜๋‚˜ ๋” ๋Š˜๋ ธ๋‹ค.

- ๊ฒฐ๊ณผ

Error๊ฐ€ 32% -> 28%๋กœ ์กฐ๊ธˆ ์ค„์–ด๋“  ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

ํšจ๊ณผ๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ๋งŽ์ด ๋‹ฌ๋ผ์ง€์ง„ ์•Š์•˜๋‹ค. ์˜คํžˆ๋ ค ์‘๋‹ต์‹œ๊ฐ„์ด ๋Š˜์–ด๋‚˜๊ธด ํ–ˆ์ง€๋งŒ, ๋น„์Šทํ•˜๋‹ค๊ณ  ๋ณด๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

case 3.

[NGINX]
worker_processes : 2
worker_connections : 4000

[uWSGI]
processes : 5

worker๋ฅผ 4000์œผ๋กœ ๋Š˜๋ ธ๋‹ค.

 

- ๊ฒฐ๊ณผ

Error๊ฐ€ ์•ฝ 13%๋กœ ๋‚˜์™”๋‹ค. ๋งŽ์ด ์ค„์–ด๋“  ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์‘๋‹ต ์†๋„๊ฐ€ 1600ms(์•ฝ 1.6์ดˆ) ์ •๋„์— ์ตœ๋Œ€๋ฅผ ์ฐ์—ˆ์ง€๋งŒ, ์‘๋‹ต ์†๋„๊ฐ€ ๋งŽ์ด ์ข‹์•„์ง„ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

case 4.

[NGINX]
worker_processes : 2
worker_connections : 4000

[uWSGI]
processes : 10

uwsgi์˜ process๋ฅผ ๋Š˜๋ ธ๋‹ค.

 

- ๊ฒฐ๊ณผ

 

Error๊ฐ€ ๋งŽ์ด ์ค„์—ˆ๋‹ค.

์‘๋‹ต ์‹œ๊ฐ„์€ ์ „๊ณผ ๋น„์Šทํ–ˆ๋‹ค.

 

 

 

- ๊ฒฐ๊ณผ

 

ํ‘œ๋กœ ์ •๋ฆฌํ•ด๋ณด๋ฉด ๋Œ€๋žต ์ด๋ ‡๋‹ค.

  [NGINX]
processes : 1
connections : 1024

[uWSGI]
processes : 5
[NGINX]
processes : 2
connections : 1024

[uWSGI]
processes : 5
[NGINX]
processes : 2
connections : 4000

[uWSGI]
processes : 5
[NGINX]
processes : 2
connections : 4000

[uWSGI]
processes : 10
Error (%) 32 28 12 3
Max Response Time 3.2s 4.8s 1.4s 1.7s

 

์—ฌ๊ธฐ์„œ ๋ˆˆ์—ฌ๊ฒจ ๋ณผ ๊ฒƒ์ด ์žˆ๋‹ค.

 

1. NGINX์˜ process๊ฐ€ 1 -> 2๋กœ ๋Š˜์–ด๋‚ฌ์Œ์—๋„ ์™œ Error๋‚˜ Response Time์ด ๋ˆˆ์— ๋„๊ฒŒ ๊ฐœ์„ ๋˜์ง€ ์•Š์•˜์„๊นŒ?

 

 

NGINX process๋Š” ๋ชจ๋“  request๋ฅผ ๋น„๋™๊ธฐ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค.

 

๋”ฐ๋ผ์„œ, worker์˜ ๊ฐœ์ˆ˜๊ฐ€ ํ•˜๋‚˜์—ฌ๋„ ์„œ๋ฒ„๋Š” ์ตœ๋Œ€ํ•œ์˜ ์„ฑ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌํ•œ๋‹ค.

 

worker์˜ ๊ฐœ์ˆ˜๋ฅผ ๋Š˜๋ฆฌ๋Š” ๊ฒƒ์ด ์„ฑ๋Šฅ ํ–ฅ์ƒ์— ํšจ๊ณผ๊ฐ€ ์—†๋‹ค.

 

2. NGINX์˜ connections๊ฐ€ 1024 -> 4000์œผ๋กœ ๋Š˜์–ด๋‚  ๋•Œ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋๋‹ค.

 

connections๋Š” ๋™์‹œ์— ์ ‘์† ๊ฐ€๋Šฅํ•œ connection์˜ ์ˆ˜๋ฅผ ๋œปํ•œ๋‹ค.

 

๋”ฐ๋ผ์„œ, ์ตœ๋Œ€ ์—ฐ๊ฒฐ ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

Max Connections = worker_processes * worker_connections

 

์ด๋กœ์จ process๊ฐ€ ๋Š˜์–ด๋‚˜๋„ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋˜์ง€ ์•Š์•˜๊ณ ,

connections๊ฐ€ ๋Š˜์–ด๋‚ฌ์Œ์— ๋”ฐ๋ผ ์ตœ๋Œ€ connection์ด ๋Š˜์–ด๋‚ฌ์œผ๋ฏ€๋กœ, ๋™์‹œ ์ ‘์†์— ๋Œ€ํ•œ ์š”๊ตฌ๋Ÿ‰ ์ถฉ์กฑ์ด ๋งŽ์•„์กŒ๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋œ ๊ฒƒ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.