nginx는 정적 파일을 너무 느리게 제공합니다.

nginx는 정적 파일을 너무 느리게 제공합니다.

성능을 테스트하는 데 사용했던 nginx에서 제공하는 약 2M의 약간 큰 자바 스크립트 파일이 있는데 ab약 5/초로 매우 느렸습니다. CPU 및 메모리 사용량이 매우 낮고 CPU 부하도 매우 낮고 interruputs매우 높지만 dstat반대로 interrupts매우 낮 top으며 네트워크 대역폭 사용량은 13M에 불과합니다.

결과 dstat:

 ----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
 usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw 
  0   0  99   0   0   0|   0     0 | 449k   13M|   0     0 |  14k 3985 
  1   0  99   0   0   0|   0    75k| 450k   13M|   0     0 |  13k 4096 
  0   0  99   0   0   0|   0     0 | 456k   13M|   0     0 |  14k 4063 
  0   1  99   0   0   0|   0  4096B| 449k   13M|   0     0 |  14k 4099 
  1   0  99   0   0   0|   0    41k| 451k   13M|   0     0 |  14k 4090 
  1   1  99   0   0   0|   0     0 | 431k   13M|   0     0 |  13k 4015 
  2   3  94   1   0   1|   0    37k| 442k   13M|   0     0 |  14k 4732 
  0   1  98   0   0   1|   0     0 | 455k   13M|   0     0 |  14k 3937 
  0   1  99   0   0   0|   0  4096B| 441k   13M|   0     0 |  14k 4061 
  0   0  99   0   0   0|   0    32k| 452k   13M|   0     0 |  13k 3895 
  0   0  99   0   0   1|   0     0 | 449k   13M|   0     0 |  14k 4025 
  0   1  99   0   0   0|   0    75k| 449k   13M|   0     0 |  14k 4087 
  1   0  99   0   0   0|   0     0 | 459k   13M|   0     0 |  14k 4068

결과 top:

top - 01:30:22 up 32 days, 15:55,  4 users,  load average: 0.06, 0.04, 0.05
 Tasks: 209 total,   1 running, 207 sleeping,   0 stopped,   1 zombie
 %Cpu0  :  0.4 us,  0.4 sy,  0.0 ni, 98.4 id,  0.5 wa,  0.0 hi,  0.4 si,  0.0 st
 %Cpu1  :  0.5 us,  0.4 sy,  0.0 ni, 98.6 id,  0.0 wa,  0.0 hi,  0.5 si,  0.0 st
 %Cpu2  :  0.4 us,  0.5 sy,  0.0 ni, 99.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
 %Cpu3  :  0.4 us,  0.4 sy,  0.0 ni, 98.3 id,  0.0 wa,  0.0 hi,  0.9 si,  0.0 st
 KiB Mem :  8009116 total,  2860992 free,  2376112 used,  2772012 buff/cache
 KiB Swap:  8257532 total,  6995792 free,  1261740 used.  5289404 avail Mem

nginx 구성:

user  root;
worker_processes  4;


events {
    worker_connections  10240;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$request_time"';

    access_log  logs/access.log  main;

    sendfile        on;

    keepalive_timeout  65;


    server {
        listen       80;
        server_name  localhost;
        location ^~ /static/js {
                alias /root/static;
        }
    }
}

시험 결과 ab:

ab -c 50 -n 1000 http://172.16.10.252/static/js/mapcube.js
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 172.16.10.252 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        nginx/1.18.0
Server Hostname:        172.16.10.252
Server Port:            80

Document Path:          /static/js/mapcube.js
Document Length:        2067001 bytes

Concurrency Level:      50
Time taken for tests:   177.033 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      2067254000 bytes
HTML transferred:       2067001000 bytes
Requests per second:    5.65 [#/sec] (mean)
Time per request:       8851.632 [ms] (mean)
Time per request:       177.033 [ms] (mean, across all concurrent requests)
Transfer rate:          11403.56 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   44 230.9      4    3010
Processing:  3356 8729 2531.8   8484   27916
Waiting:        1   20  96.9      5    1465
Total:       3360 8773 2537.0   8503   27921

Percentage of the requests served within a certain time (ms)
  50%   8503
  66%   9628
  75%  10282
  80%  10667
  90%  11868
  95%  13021
  98%  14240
  99%  16293
 100%  27921 (longest request)

nginx 액세스 로그:

172.16.13.163 - - [09/Aug/2021:01:32:32 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "10.531"
172.16.13.163 - - [09/Aug/2021:01:32:32 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "9.056"
172.16.13.163 - - [09/Aug/2021:01:32:32 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "4.995"
172.16.13.163 - - [09/Aug/2021:01:32:32 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "7.615"
172.16.13.163 - - [09/Aug/2021:01:32:33 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "12.134"
172.16.13.163 - - [09/Aug/2021:01:32:33 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "10.562"
172.16.13.163 - - [09/Aug/2021:01:32:33 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "6.037"
172.16.13.163 - - [09/Aug/2021:01:32:33 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "7.596"
172.16.13.163 - - [09/Aug/2021:01:32:34 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "9.360"
172.16.13.163 - - [09/Aug/2021:01:32:34 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "10.697"
172.16.13.163 - - [09/Aug/2021:01:32:33 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "10.562"
172.16.13.163 - - [09/Aug/2021:01:32:33 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "6.037"
172.16.13.163 - - [09/Aug/2021:01:32:33 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "7.596"
172.16.13.163 - - [09/Aug/2021:01:32:34 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "9.360"
172.16.13.163 - - [09/Aug/2021:01:32:34 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "10.697"
172.16.13.163 - - [09/Aug/2021:01:32:34 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "4.924"
172.16.13.163 - - [09/Aug/2021:01:32:34 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "10.588"
172.16.13.163 - - [09/Aug/2021:01:32:34 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "13.913"
172.16.13.163 - - [09/Aug/2021:01:32:34 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "11.859"
172.16.13.163 - - [09/Aug/2021:01:32:35 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "11.748"
172.16.13.163 - - [09/Aug/2021:01:32:35 +0800] "GET /static/js/mapcube.js HTTP/1.0" 200 2067001 "-" "ApacheBench/2.3" "-" "7.987"

172.16.13.163(ab)에서 172.16.10.252(nginx)로 핑:

ping 172.16.10.252
PING 172.16.10.252 (172.16.10.252) 56(84) bytes of data.
64 bytes from 172.16.10.252: icmp_seq=1 ttl=63 time=0.329 ms
64 bytes from 172.16.10.252: icmp_seq=2 ttl=63 time=0.412 ms
64 bytes from 172.16.10.252: icmp_seq=3 ttl=63 time=0.443 ms
64 bytes from 172.16.10.252: icmp_seq=4 ttl=63 time=0.459 ms
64 bytes from 172.16.10.252: icmp_seq=5 ttl=63 time=0.892 ms
64 bytes from 172.16.10.252: icmp_seq=6 ttl=63 time=0.443 ms

172.16.10.252 네트워크 카드:

ethtool ens192 | grep Speed
    Speed: 10000Mb/s

nginx 정보:

./sbin/nginx -V
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --user=xxx --prefix=/home/xxx/softs/nginx --with-http_stub_status_module --with-http_ssl_module --with-file-aio --with-http_realip_module --add-module=../nginx-http-flv-module

두 가지 질문이 있습니다.

  1. interruptsdstat그림과 같이 14k높나요 아니면 정상인가요 ? 너무 낮은 것 interrupts같고 충돌하는 것 같나요?top0.0~0.9
  2. nginx가 왜 그렇게 느린가요? 성능을 향상시키려면 어떻게 해야 합니까? 병목 현상을 어떻게 찾을 수 있나요?

추신: ab사용법 으로 Keep Alive를 http/1.0사용했지만 ad -k작동하지 않습니다. 그래서 siege테스트에 사용하도록 변경했습니다 . siege -c 50 -r 20 -H "Connection: keep-alive" http://172.16.10.252/static/js/mapcube.js하지만 tps는 ab테스트만큼 낮습니다.

포위 결과:

HTTP/1.1 200     5.56 secs: 2067001 bytes ==> GET  /static/js/mapcube.js
HTTP/1.1 200     3.13 secs: 2067001 bytes ==> GET  /static/js/mapcube.js
HTTP/1.1 200     2.68 secs: 2067001 bytes ==> GET  /static/js/mapcube.js
HTTP/1.1 200     1.41 secs: 2067001 bytes ==> GET  /static/js/mapcube.js
HTTP/1.1 200     4.71 secs: 2067001 bytes ==> GET  /static/js/mapcube.js
HTTP/1.1 200     1.17 secs: 2067001 bytes ==> GET  /static/js/mapcube.js
HTTP/1.1 200     1.67 secs: 2067001 bytes ==> GET  /static/js/mapcube.js
HTTP/1.1 200     2.51 secs: 2067001 bytes ==> GET  /static/js/mapcube.js
HTTP/1.1 200     0.62 secs: 2067001 bytes ==> GET  /static/js/mapcube.js
HTTP/1.1 200     1.12 secs: 2067001 bytes ==> GET  /static/js/mapcube.js
HTTP/1.1 200     0.21 secs: 2067001 bytes ==> GET  /static/js/mapcube.js
HTTP/1.1 200     4.29 secs: 2067001 bytes ==> GET  /static/js/mapcube.js
HTTP/1.1 200     0.23 secs: 2067001 bytes ==> GET  /static/js/mapcube.js

Transactions:               1000 hits
Availability:             100.00 %
Elapsed time:             178.83 secs
Data transferred:        1971.25 MB
Response time:              8.69 secs
Transaction rate:           5.59 trans/sec
Throughput:            11.02 MB/sec
Concurrency:               48.60
Successful transactions:        1000
Failed transactions:               0
Longest transaction:           36.69
Shortest transaction:           0.21

위와 같이 siege -H "Connection: keep-alive"요청 1,000개를 테스트 해서 time_wait빠르게 1,000개로 늘렸는데 keep-alive잘 안되더라구요.

netstat -ant | awk '{print $6}' | sort | uniq -c
      1 established)
      1 ESTABLISHED
      1 Foreign
     10 LISTEN
   1000 TIME_WAIT

관련 정보