Nginx はサイレントにリロードに失敗します (98: アドレスは既に使用されています) が、ポートでリッスンしているものは他にありません

Nginx はサイレントにリロードに失敗します (98: アドレスは既に使用されています) が、ポートでリッスンしているものは他にありません

私はもう 6 か月近く、この問題を解決しようとしています。この問題は、Nginx または Ubuntu のバージョンに関係なく、ランダムに発生します。nginx-extras パッケージは、Ubuntu リポジトリから使用されます。これは、同じ問題を抱えている、異なるハードウェアを持つ 10 台のサーバーのグループです。

簡単に言うと、Nginx はランダムにリロードに失敗します。エラー ログには、アドレスにバインドできなかったことが表示されます (現在はポート 443 で発生していますが、ポート 80 でもランダムに発生します)。 を発行すると、service nginx upgradeサーバーがリロードされることがあります。それでも失敗した場合は、 がservice nginx restart機能することもあれば、機能しないこともあります。これでも失敗した場合、構成をリロードする唯一の方法は、 を発行しservice nginx stop、数秒待ってから を実行することですservice nginx start。これらのコマンドはいずれもエラーを返すことはありませんが、[OK]コマンドが失敗した場合でもエラーを返します。

これらのマシンは大きなファイルを送信しており、転送が中断されるため、Nginx の停止と起動は問題となります。さらに、大きなファイルがバックエンドから取得されてキャッシュされる場合、再起動中にキャッシュされたバージョンが破損してしまいます。

nginx version: nginx/1.4.6 (Ubuntu)
built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3) 
TLS SNI support enabled
configure arguments: 
--with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro' 
--prefix=/usr/share/nginx 
--conf-path=/etc/nginx/nginx.conf 
--http-log-path=/var/log/nginx/access.log 
--error-log-path=/var/log/nginx/error.log 
--lock-path=/var/lock/nginx.lock 
--pid-path=/run/nginx.pid 
--http-client-body-temp-path=/var/lib/nginx/body 
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi 
--http-proxy-temp-path=/var/lib/nginx/proxy 
--http-scgi-temp-path=/var/lib/nginx/scgi 
--http-uwsgi-temp-path=/var/lib/nginx/uwsgi 
--with-debug 
--with-pcre-jit 
--with-ipv6 
--with-http_ssl_module 
--with-http_stub_status_module 
--with-http_realip_module 
--with-http_addition_module 
--with-http_dav_module 
--with-http_flv_module 
--with-http_geoip_module 
--with-http_gzip_static_module 
--with-http_image_filter_module 
--with-http_mp4_module 
--with-http_perl_module 
--with-http_random_index_module 
--with-http_secure_link_module 
--with-http_spdy_module 
--with-http_sub_module 
--with-http_xslt_module 
--with-mail 
--with-mail_ssl_module 
--add-module=/build/nginx-hzyca8/nginx-1.4.6/debian/modules/headers-more-nginx-module 
--add-module=/build/nginx-hzyca8/nginx-1.4.6/debian/modules/nginx-auth-pam
--add-module=/build/nginx-hzyca8/nginx-1.4.6/debian/modules/nginx-cache-purge 
--add-module=/build/nginx-hzyca8/nginx-1.4.6/debian/modules/nginx-dav-ext-module 
--add-module=/build/nginx-hzyca8/nginx-1.4.6/debian/modules/nginx-development-kit 
--add-module=/build/nginx-hzyca8/nginx-1.4.6/debian/modules/nginx-echo 
--add-module=/build/nginx-hzyca8/nginx-1.4.6/debian/modules/ngx-fancyindex 
--add-module=/build/nginx-hzyca8/nginx-1.4.6/debian/modules/nginx-http-push 
--add-module=/build/nginx-hzyca8/nginx-1.4.6/debian/modules/nginx-lua 
--add-module=/build/nginx-hzyca8/nginx-1.4.6/debian/modules/nginx-upload-progress 
--add-module=/build/nginx-hzyca8/nginx-1.4.6/debian/modules/nginx-upstream-fair 
--add-module=/build/nginx-hzyca8/nginx-1.4.6/debian/modules/ngx_http_substitutions_filter_module

現在実行中のプロセス:

# ps ax | grep nginx
25771 pts/1    S+     0:00 grep --color=auto nginx
29145 ?        S      0:00 nginx: master process /usr/sbin/nginx
29664 ?        RN   516:47 nginx: worker process
29665 ?        SN   513:46 nginx: worker process
29666 ?        SN   514:17 nginx: worker process
29667 ?        SN   517:24 nginx: worker process
29668 ?        SN   512:29 nginx: worker process
29669 ?        SN   515:28 nginx: worker process
29670 ?        SN   517:52 nginx: worker process
29671 ?        SN   507:52 nginx: worker process
29672 ?        S      0:13 nginx: cache manager process

再読み込みを試行しています:

# service nginx reload
 * Reloading nginx configuration nginx   [ OK ]

ps 出力をもう一度見てみると、何も起こっていません。

# ps ax | grep nginx
29145 ?        S      0:00 nginx: master process /usr/sbin/nginx
29664 ?        SN   516:54 nginx: worker process
29665 ?        SN   513:49 nginx: worker process
29666 ?        SN   514:20 nginx: worker process
29667 ?        SN   517:27 nginx: worker process
29668 ?        SN   512:34 nginx: worker process
29669 ?        SN   515:31 nginx: worker process
29670 ?        SN   518:08 nginx: worker process
29671 ?        SN   507:55 nginx: worker process
29672 ?        S      0:13 nginx: cache manager process
31121 pts/1    S+     0:00 grep --color=auto nginx

エラー ログの確認 (IP アドレスは編集済み):

2018/03/10 00:22:29 [info] 32481#0: Using 32768KiB of shared memory for push module in /etc/nginx/nginx.conf:95
2018/03/10 00:22:29 [emerg] 29145#0: bind() to 195.181.160.xx:443 failed (98: Address already in use)
2018/03/10 00:22:29 [emerg] 29145#0: bind() to 195.181.160.xx:443 failed (98: Address already in use)
2018/03/10 00:22:29 [emerg] 29145#0: bind() to 195.181.160.xx:443 failed (98: Address already in use)
2018/03/10 00:22:29 [emerg] 29145#0: bind() to 195.181.160.xx:443 failed (98: Address already in use)
2018/03/10 00:22:29 [emerg] 29145#0: bind() to 195.181.160.xx:443 failed (98: Address already in use)
2018/03/10 00:22:29 [emerg] 29145#0: still could not bind()

443 を使用する唯一のプロセスは nginx 自体です。

# sudo netstat -tulpn | grep :443
tcp        0      0 0.0.0.0:443     0.0.0.0:*      LISTEN      29145/nginx

これらのサーバーでは、各顧客に 2 つのサーバー ブロックがあります。1 つは標準ポートでリッスンするパブリック サーバー ブロック、もう 1 つはキャッシュを行う内部サーバー ブロックです。後者はローカルホスト IP の一意のポートでリッスンし、パブリック ブロックから proxy_pass を介してアクセスされます。これらの内部ブロックはすべて、別の場所への proxy_pass です。この設定の理由はここでは説明しきれないほど複雑です。

これまでに確認したこと:

  • すべての内部ブロックは上流を解決できる

  • すべての内部ポートは一意であり、他のサービスによって使用されていません。

  • SPDY は使用されていません (Nginx のメーリング リストで報告されたバグが見つかりました)

  • 問題はランダムに発生するように見えますが、Nginxインスタンスの実行時間が長くなるほど発生する可能性が高くなります。

  • この動作は、Ubuntu 14.04.X と 16.04、Nginx バージョン 1.4.6 以降の両方で発生します。

  • CPU、ディスク、ネットワーク負荷との明らかな関係はない

これらのサーバーを使用するプラットフォームによって自動的に生成されるサーバー ブロックの例 (一部の情報は編集されています):

公開ブロック:

server {

    keepalive_timeout 10;

    listen 195.xx.xx.xx:80;
    #listen 195.xx.xx.xx:80 ssl;
    root /home/nginx;  
    server_name xxxxxx.xxxxxx.com ;

    index index.php index.html index.htm index.nginx-debian.html

    error_page 403 /403.html; location = /403.html {
        return https://www.xxxxxx.com/403.php;
    }

    error_page 404 /404.html; location = /404.html {
        return https://www.xxxxxx.com/404.php;
    }

    error_page 500 /500.html; location = /500.html {
        root /home/nginx;
    }

    location ^~ /.well-known/acme-challenge/ {
        default_type "text/plain";
        return 301 http://xxxxx.xxxxxxx.com$request_uri;
    }

    location / {

        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        geo_xxxxx     $geoip_country_code;
        proxy_intercept_errors  on;

        proxy_buffering        off;
        proxy_pass             http://127.0.1.3:8213;

        set $sent_http_accept_ranges bytes;

    } 

    location ~ /playlist.m3u8 {              

        secure_link $arg_st,$arg_e;
        secure_link_md5 xxxxxxxxxxxxxxxxxxxx$uri$remote_addr$arg_e;

        if ($secure_link = "") { return 403; }
        if ($secure_link = "0") { return 410; }

            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        geo_xxxxxx     $geoip_country_code;
            proxy_intercept_errors  on;

            proxy_buffering        off;
            proxy_pass             http://127.0.1.3:8213;
    } 


    #ssl_certificate /etc/letsencrypt/live//fullchain.pem; # managed by Certbot
    #ssl_certificate_key /etc/letsencrypt/live//privkey.pem; # managed by Certbot
    #include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    limit_rate 10000k;

} 

関連するプライベートブロック:

proxy_cache_path  /home/nginx/282-281-cache levels=1:2 
keys_zone=282-281:5m inactive=48h  max_size=500g;
limit_conn_zone $http_x_forwarded_for zone=addr282-281:10m;    

map $http_user_agent $blockedUA {
default 0;
"~thisisadummyua" 1;
"~thisisanotherdummyua" 1;
} 

map $http_referer $blockedREF {
default 0;
"~thisisadummyref.com" 1;
"~thisisanotherdummyref.com" 1;
}     

server { 

    limit_conn addr282-281 100;
    limit_conn_status 429;

    keepalive_timeout 10;

    listen 127.0.1.3:8213;
    root /home/nginx;  
    server_name 127.0.1.3;   

    location ~* \.(m3u8)$ {
            real_ip_header X-Forwarded-For;
            set_real_ip_from xxx.xx.xx.xx/xx;
            proxy_set_header        geo_xxxxx     $geoip_country_code;
            proxy_set_header       Host $proxy_host;
            real_ip_recursive on;

            # CORS setup
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Expose-Headers' 'Content-Length';

            proxy_ignore_headers Cache-Control;
            add_header Cache-Control public;

            # allow CORS preflight requests
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
            }
            add_header Edge-Cache $upstream_cache_status; 
            proxy_cache            282-281;

            proxy_cache_valid      200 206 5s;
            proxy_cache_use_stale  error timeout invalid_header updating
                                   http_500 http_502 http_503 http_504;
            proxy_cache_lock       on;
            proxy_cache_lock_timeout 10s;
            proxy_cache_key        $uri;
            proxy_pass http://xxx.xx.xx.xx:41000;
    }

    location / {
            deny 10.10.10.1;
            deny 10.10.10.2;

            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Expose-Headers' 'Content-Length';

            proxy_ignore_headers X-Accel-Expires Expires Cache-Control; 
            proxy_ignore_headers Set-Cookie; 
            add_header Cache-Control public;

            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
            }

            real_ip_header X-Forwarded-For;
            set_real_ip_from xxx.xx.xx.xx/xx;
            proxy_set_header        geo_xxxxx     $geoip_country_code;
            proxy_set_header       Host $proxy_host;

            proxy_http_version 1.1;
            real_ip_recursive on;
            proxy_set_header Range $http_range;
            proxy_set_header If-Range $http_if_range;
            proxy_no_cache $http_range $http_if_range;    
            proxy_cache_bypass $http_range $http_if_range;
            proxy_temp_path        /home/nginx/282-281-temp;
            proxy_buffering        on;
            proxy_max_temp_file_size 25m;
            proxy_intercept_errors  on;

            proxy_cache_purge PURGE from all; 

            add_header Edge-Cache $upstream_cache_status; 
            proxy_cache            282-281;

            proxy_cache_valid      200 206 5m;
            proxy_cache_use_stale  error timeout invalid_header updating
                                   http_500 http_502 http_503 http_504;
            proxy_cache_lock       on;
            proxy_cache_lock_timeout 120s;
            proxy_cache_key        $uri;
            proxy_pass             http://xxx.xx.xx.xx:41000/;


    }

    if ($blockedUA = 1){
        return https://www.xxxxxxx.com/403.php;
    }    

    #if ($http_user_agent = "") { 
    #     return https://www.xxxxxxx.com/403.php;
    #}

    if ($blockedREF = 1){
        return https://www.xxxxxxx.com/403.php;
    }  

    access_log /var/log/nginx/xxxx/xxx-xxx-proxy-access.log xxxx;
    error_log /var/log/nginx/xxxx/xxx-xxx-proxy-error.log;


}`

現在、nginx-common パッケージを試してみようと考えていますが、これは実稼働システムです。テスト マシンで問題が発生するかどうかはわかりません。

編集: この質問をした後、3 時間ごとにリロードする cron ジョブを追加することにしました。これは、Nginx がリロードなしで長く実行されるほど、問題が顕在化する可能性が高いと観察したためです。今日で cron を実行して 3 日目ですが、すべてのサーバーがリロードに正しく応答し、どのサーバーでも問題はまだ確認されていません。せいぜい、これは応急処置にすぎず、実際の問題を解決していません。しかし、これが私が思いついた最善策であり、ほぼ唯一機能しているようです。

編集2: cron を追加しても問題は解決しませんでしたが、試してみる必要がありました。次に、作業できる最小限のモジュールを使用して Nginx をソースからコンパイルし、サーバーの 1 つにインストールしました。これは 7 日前のことですが、このサーバーではそれ以降問題が発生していません。3 日前、時間が迫っていたため、これ以上待つことはせず、実稼働サーバーを 1 つずつ停止して、新しくコンパイルされたバージョンの Nginx に置き換え始めました。これまでのところ順調で、どのサーバーも問題の兆候は見られません。3 回目の編集に戻らないことを祈ります。

答え1

これは時々起こることです。だから、特別なことではありません。

サービスを再起動またはリロードする場合、次のアプローチを確立しました。

1. 構成が期待どおりに動作しているかどうかを確認します。

nginx -t

2. Nginxを再起動して応答を確認します。

service nginx restart

3. ポート衝突により再起動できなかった場合...

どのサービスがポートをブロックしているかを確認します。

netstat -nltp | grep -E ':80\W|:443\W'

対応するサービスを終了します:

killall nginx

場合によっては、1 つのプロセスがフリーズすることがあります。ハングしているプロセスを、より強力なパワーで強制終了する必要があります。

kill -9 {process_id}

関連情報