編輯:

編輯:

我正在嘗試使用我的基準測試工具達到 2000 個並髮用戶。我正在使用 Locust 來模擬它們。

我的伺服器有 24vCPU、128GB RAM、25SSD。

我希望能夠為 2000 個並髮用戶提供服務而不會出現錯誤,但在只有 700 個用戶之後我就遇到了麻煩。

鰩魚

我安裝了 gevent 以便能夠提供非同步服務,但這並沒有改變我的負載測試中的任何內容(gevent 可以不工作嗎?)。我的systemd檔如下:

mysite-生產.conf

    [Unit]
    Description=mysite production daemon
    After=network.target

    [Service]
    User=www-data
    Group=www-data
    WorkingDirectory=/var/www/mysite/production/src
    ExecStart=/var/www/mysite/production/venv/bin/gunicorn --worker-class=gevent --worker-connections=1000  --workers=49 --bind unix:/var/www/mysite/production/sock/gunicorn --log-level DEBUG --log-file '/var/www/mysite/production/log/gunicorn.log' mysite.wsgi:application
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/bin/kill -s TERM $MAINPID

    [Install]
    WantedBy=multi-user.target

根據我的計算:我可以服務的每秒 49 x 1000 = 49000 個請求。

相反,大約 700 個用戶時,我在 Locust 故障標籤中收到以下錯誤:

# fails Method  Name    Type
1227    GET     //  HTTPError('500 Server Error: Internal Server Error for url: http://my.site.com//')

它基本上說我有一個內部伺服器錯誤。

當我打開 Gunicorn.log 時我看到忽略 EPIPE

古尼康日誌

[2020-01-27 20:22:30 +0000] [13121] [DEBUG] Ignoring EPIPE
[2020-01-27 20:22:31 +0000] [13121] [DEBUG] Ignoring EPIPE
[2020-01-27 20:22:31 +0000] [13121] [DEBUG] Ignoring EPIPE
[2020-01-27 20:22:31 +0000] [13121] [DEBUG] Ignoring EPIPE
[2020-01-27 20:22:31 +0000] [13121] [DEBUG] Ignoring EPIPE

nginx

我的 nginx access.log 顯示一些 499 和 500 錯誤:

訪問日誌

185.159.126.246 - - [27/Jan/2020:19:22:25 +0000] "GET // HTTP/1.1" 200 30727 "-" "python-requests/2.22.0"
185.159.126.246 - - [27/Jan/2020:19:22:25 +0000] "GET // HTTP/1.1" 499 0 "-" "python-requests/2.22.0"
185.159.126.246 - - [27/Jan/2020:19:22:25 +0000] "GET // HTTP/1.1" 499 0 "-" "python-requests/2.22.0"
185.159.126.246 - - [27/Jan/2020:19:22:25 +0000] "GET // HTTP/1.1" 200 30727 "-" "python-requests/2.22.0"
185.159.126.246 - - [27/Jan/2020:19:22:25 +0000] "GET // HTTP/1.1" 500 2453 "-" "python-requests/2.22.0"
185.159.126.246 - - [27/Jan/2020:19:22:25 +0000] "GET // HTTP/1.1" 500 2453 "-" "python-requests/2.22.0"
185.159.126.246 - - [27/Jan/2020:19:22:25 +0000] "GET // HTTP/1.1" 499 0 "-" "python-requests/2.22.0"
185.159.126.246 - - [27/Jan/2020:19:22:25 +0000] "GET // HTTP/1.1" 499 0 "-" "python-requests/2.22.0"

nginx error.log 沒有顯示任何內容,但在先前的測試中它顯示了資源暫時無法使用

錯誤日誌


2020/01/27 19:15:32 [error] 1514#1514: *57151 connect() to unix:/var/www/mysite/production/sock/gunicorn failed (11: Resource temporarily unavailable) while connecting to upstream, client: 185.159.126.246, server: my.site.com, request: "GET // HTTP/1.1", upstream: "http://unix:/var/www/mysite/production/sock/gunicorn://", host: "my.site.com"
2020/01/27 19:15:32 [error] 1514#1514: *56133 connect() to unix:/var/www/mysite/production/sock/gunicorn failed (11: Resource temporarily unavailable) while connecting to upstream, client: 185.159.126.246, server: my.site.com, request: "GET // HTTP/1.1", upstream: "http://unix:/var/www/mysite/production/sock/gunicorn://", host: "my.site.com"

這是我的 nginx.conf:

nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
worker_rlimit_nofile 40000;

events {
        worker_connections 4096;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
   }

這是我的伺服器區塊:

my.site.com(伺服器區塊)


upstream mysite-production {
    server unix:/var/www/mysite/production/sock/gunicorn;
}
server {
    listen [::]:80;
    listen 80;
    server_name my.site.com;

    # set client body size to 100M #
    client_max_body_size 100M;

    location / {
      include proxy_params;
      proxy_pass http://unix:/var/www/mysite/production/sock/gunicorn;
    }

    location /static/ {
        root /var/www/mysite/production/;
        expires 30d;
        add_header Vary Accept-Encoding;
        access_log off;
        gzip on;
        gzip_comp_level 6;
        gzip_vary on;
        gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/rss+xml text/javascript image/svg+xml application/vnd.ms-fontobject application/x-font-ttf font/opentype;
    }

    location /media/ {
        root /var/www/mysite/production/;
        expires 30d;
        add_header Vary Accept-Encoding;
        access_log off;
    }
}

問題

當我看到這一切時出現的問題是:

502錯誤從何而來?它沒有向我顯示足夠的資訊來了解正在發生的情況...在 700 個用戶導致錯誤後,我的所有工作人員是否都被佔用了?

499錯誤從何而來?

這和我的postgresql資料庫有什麼關係嗎?如果是這樣我怎麼知道?

我如何知道 gevent 是否有效? ab 和 locust 的負載測試結果並沒有真正改變。

什麼是忽略 EPIPE意思是什麼以及為什麼會發生?

我感謝您花時間查看此內容。預先感謝您的所有評論和答覆!

如果您需要更多信息,請告訴我,我會將其添加到我的問題中。

編輯:

根據@ServerFaults 評論,我檢查了負載測試發生時消耗了多少記憶體。顯然沒有什麼真正重要的:

MemTotal:       132027088 kB
MemFree:        127013484 kB
MemAvailable:   126458072 kB
Buffers:           57788 kB
Cached:           401088 kB

運行後netstat -s(我沒有知識來理解一切的意義):

Ip:
    Forwarding: 2
    6956023 total packets received
    8 with invalid addresses
    0 forwarded
    0 incoming packets discarded
    6953503 incoming packets delivered
    6722961 requests sent out
    20 outgoing packets dropped
Icmp:
    107 ICMP messages received
    0 input ICMP message failed
    ICMP input histogram:
        destination unreachable: 45
        echo requests: 62
    968 ICMP messages sent
    0 ICMP messages failed
    ICMP output histogram:
        destination unreachable: 906
        echo replies: 62
IcmpMsg:
        InType3: 45
        InType8: 62
        OutType0: 62
        OutType3: 906
Tcp:
    222160 active connection openings
    136492 passive connection openings
    78293 failed connection attempts
    161239 connection resets received
    2 connections established
    6245053 segments received
    6487229 segments sent out
    11978 segments retransmitted
    0 bad segments received
    185530 resets sent
Udp:
    667101 packets received
    41158 packets to unknown port received
    0 packet receive errors
    727164 packets sent
    0 receive buffer errors
    0 send buffer errors
UdpLite:
TcpExt:
    2939 SYN cookies sent
    28 SYN cookies received
    215 invalid SYN cookies received
    113 resets received for embryonic SYN_RECV sockets
    18751 TCP sockets finished time wait in fast timer
    175 packetes rejected in established connections because of timestamp
    61997 delayed acks sent
    54 delayed acks further delayed because of locked socket
    Quick ack mode was activated 3475 times
    2687504 packet headers predicted
    1171485 acknowledgments not containing data payload received
    2270054 predicted acknowledgments
    TCPSackRecovery: 921
    Detected reordering 22500 times using SACK
    Detected reordering 596 times using time stamp
    139 congestion windows fully recovered without slow start
    490 congestion windows partially recovered using Hoe heuristic
    TCPDSACKUndo: 14
    413 congestion windows recovered without slow start after partial ack
    TCPLostRetransmit: 47
    TCPSackFailures: 5
    7 timeouts in loss state
    2416 fast retransmits
    123 retransmits in slow start
    TCPTimeouts: 5279
    TCPLossProbes: 4284
    TCPLossProbeRecovery: 22
    TCPSackRecoveryFail: 1
    TCPDSACKOldSent: 3482
    TCPDSACKRecv: 1996
    TCPDSACKOfoRecv: 4
    52968 connections reset due to unexpected data
    54079 connections reset due to early user close
    51 connections aborted due to timeout
    TCPDSACKIgnoredOld: 25
    TCPDSACKIgnoredNoUndo: 822
    TCPSpuriousRTOs: 81
    TCPSackShifted: 4787
    TCPSackMerged: 5128
    TCPSackShiftFallback: 33199
    TCPReqQFullDoCookies: 2939
    TCPRcvCoalesce: 84434
    TCPOFOQueue: 26
    TCPChallengeACK: 3
    TCPAutoCorking: 7
    TCPFromZeroWindowAdv: 125
    TCPToZeroWindowAdv: 125
    TCPWantZeroWindowAdv: 1376
    TCPSynRetrans: 4695
    TCPOrigDataSent: 5023492
    TCPHystartTrainDetect: 2403
    TCPHystartTrainCwnd: 53596
    TCPHystartDelayDetect: 346
    TCPHystartDelayCwnd: 9883
    TCPACKSkippedSynRecv: 6
    TCPACKSkippedPAWS: 10
    TCPACKSkippedSeq: 15
    TCPWinProbe: 15
IpExt:
    InOctets: 6090026491
    OutOctets: 7098177391
    InNoECTPkts: 6966279
    InECT0Pkts: 11
    InCEPkts: 1

編輯2:

在創建靜態 html 頁面而無需生成 Gunicorn 後,它能夠輕鬆地為 4000 個用戶提供服務,沒有任何延遲。透過worker_connections後我收到:

/loadtest/  ConnectionError(MaxRetryError("HTTPConnectionPool(host='ll-my.site.com', port=80): Max retries exceeded with url: /loadtest/ (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x....>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))"))

據我了解,NGINX 不是這裡的問題。

編輯3:

我檢查了我的 postgresql 日誌,發現它充滿了這個錯誤:

FATAL:  remaining connection slots are reserved for non-replication superuser connections

相關內容