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

이러한 서버에는 각 고객이 두 개의 서버 블록을 갖고 있습니다. 하나는 표준 포트에서 수신 대기하는 공개 서버 블록이고 다른 하나는 캐싱을 수행하는 내부 블록입니다. 후자는 고유 포트에서 로컬 호스트 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 패키지를 사용해 보려고 고려하고 있지만 이것은 프로덕션 시스템입니다. 테스트 시스템에서 문제가 나타날지 확실하지 않습니다.

편집하다: 이 질문을 한 후, 다시 로드하지 않고 Nginx가 더 오래 실행될수록 문제가 나타날 가능성이 더 높다는 것을 관찰한 결과 3시간마다 다시 로드하는 cron 작업을 추가하기로 결정했습니다. 오늘은 크론이 실행된 지 3일째이며 모든 서버가 다시 로드에 올바르게 응답하지만 아직 어느 서버에서도 문제가 관찰되지 않았습니다. 기껏해야 이것은 임시방편일 뿐 실제 문제를 해결하는 것은 아닙니다. 그러나 그것은 내가 생각해낸 것 중 최고이며 작동하는 것으로 보이는 거의 유일한 것입니다.

편집2: 크론을 추가해도 문제가 해결되지 않았지만 시도해야 했습니다. 그런 다음 작업할 수 있는 최소한의 모듈을 사용하여 소스에서 Nginx를 컴파일하고 서버 중 하나에 설치했습니다. 이것은 7일 전의 일이었고 그 이후로 이 서버에는 문제가 없었습니다. 3일 전 시간이 촉박해지면서 더 이상 기다리지 않기로 결정하고 Nginx를 새로 컴파일된 버전으로 교체하기 위해 프로덕션 서버를 한 번에 하나씩 제거하기 시작했습니다. 지금까지는 매우 좋았으며 더 이상 문제의 징후가 나타나지 않습니다. 세 번째 편집을 위해 다시 돌아오지 않기를 바랍니다.

답변1

이것은 때때로 발생합니다. 그래서 그것에 대해 특별한 것은 없습니다.

서비스를 다시 시작하거나 다시 로드하려는 경우 다음 접근 방식을 설정했습니다.

1. 구성이 예상대로 작동하는지 확인합니다.

nginx -t

2. Nginx를 다시 시작하고 응답을 확인합니다.

service nginx restart

3. 포트 충돌로 인해 재시작이 불가능한 경우...

포트를 차단하는 서비스를 확인하세요.

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

해당 서비스를 종료합니다:

killall nginx

어떤 경우에는 하나의 프로세스가 정지될 수 있습니다. 더 많은 전력을 사용하여 행잉 프로세스를 종료해야 합니다.

kill -9 {process_id}

관련 정보