nginx + PHP-fpm에서 502 Bad gateway 에러 해결법 총정리

필자는 개인적으로 최근 버전의 php-7.0을 사용하고 나서 502 Bad gateway 에러가 나는 빈도수가 거의 없어진 것을 느끼고 있습니다. 우분투에서 php 7.0을 설치하시는 방법이 궁금하신 분들은 여기를 누르셔서 PHP 업그레이드를 시도해 보시기 바랍니다.

 

nginx는 Apache2에 비해서 빠르고 더 많은 트래픽을 처리할 수 있는 HTTP 처리 능력을 가진 웹서버 데몬입니다. 아울러 PHP와 같이 구동되는 웹 어플리케이션을 사용할 때는, PHP-fpm을 사용하여 더 빠른 PHP 처리를 이끌어 낼 수 있지요.

하지만, 간혹 nginx + php-fpm 조합을 활용하여 웹 어플리케이션을 구동할 경우, 특정한 상황의 경우 502 Bad gateway 에러를 내뿜는 경우를 확인할 수 있습니다.

[ 필자의 경우는 CloudFlare의 502 에러 페이지입니다만, 이와 유사한 에러가 자주 등장 ]

[ 필자의 경우는 CloudFlare의 502 에러 페이지입니다만, 이와 유사한 에러가 자주 등장 ]

제가 추론하고 있는 특정한 상황은,

  1. PHP-fpm으로 처리 해야 되는 자료 중에서 굉장히 크기가 큰 요청을 처리하는 경우
  2. 서버 반응속도가 느려 PHP-fpm으로 가는 도중에 서버 요청에 긴 시간을 요구하는 경우
    (저의 경우가 이 사례인 것 같은데, 라즈베리파이2에서 서버를 구동하다 보니 왠만한 php 요청이 timeout이 발생하는 것 같았습니다.)

라고 생각되었습니다.

따라서 이것을 해결하기 위해 수 많은 구글링을 해 본 결과, 저에게 맞는 해결책을 일단 찾게 되었습니다.

 

 

▶ 문제점

– nginx + php-fpm (저의 경우에는 php7.0-fpm을 통해 서버를 구동했습니다만, php5-fpm 의 경우에도 같은 문제가 지속적으로 발견되는 것을 확인했습니다.) 조합에서 PHP 요청을 할 경우, 간혹 502 Bad gateway 에러를 내뿜음

– 502 Bad gateway 에러를 내뿜은 뒤, 다른 PHP 파일 또한 응답을 하지 않음

– 콘솔에서 다음과 같은 명령어를 활용해, php-fpm과 nginx의 프로세스 상태를 보면 정상 작동하고 있음 (…)

$  sudo service nginx status
$  sudo service php7.0-fpm status
[ nginx와 php-fpm의 서비스 상태는 정상 작동함을 확인할 수 있습니다. ]

[ nginx와 php-fpm의 서비스 상태는 정상 작동함을 확인할 수 있습니다. ]

nginx의 에러 로그(예: sudo cat /var/log/nginx/error.log)를 살펴보면 다음과 유사한 에러가 나타남을 확인할 수 있음

$  sudo cat /var/log/nginx/error.log


 결과값 예: 
2016/01/08 00:36:53 [error] 1911#0: *3 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 123.456.789.012, server: example.com, request: "GET /your/address/ HTTP/1.1", upstream: "fastcgi://unix:/your/php/socket/php7.0-fpm.sock:", host: "example.com"
2016/01/08 00:36:59 [error] 1911#0: *5 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 123.456.789.012, server: example.com, request: "GET /your/address/ HTTP/1.1", upstream: "fastcgi://unix:/your/php/socket/php7.0-fpm.sock:", host: "example.com"

 

 

▶ 해결책 1 : nginx HTTP 부분에서 fastcgi 버퍼 사이즈와 timeout 시간 변경

– 이 해결 방법은 가장 대중적인 해결 방법으로써, nginx가 php-fpm으로 PHP 처리 요청을 보냈을 때, 버퍼의 크기를 늘려 처리 용량을 확대해주고 timeout이 처리되는 시간을 늘려주는 방법

(참고 : 502 Bad Gateway on Nginx with BuddyPress)

nginx의 HTTP(최근 버전의 nginx에서는 /etc/nginx/sites-available/default 등) 안의 php 소켓 관련 설정에서, 아래와 같은 설정을 추가

server {
 (... 중략 ...)

     location ~ \.php$ {
           # With php7-fpm:
           fastcgi_split_path_info ^(.+\.php)(/.+)$;
           fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
           fastcgi_index index.php;
           fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

          # 아래부터 버그 해결을 위해 추가해 주실 옵션입니다.
          # 502 에러를 없애기 위한 proxy 버퍼 관련 설정입니다.
          proxy_buffer_size               128k;
          proxy_buffers                   4 256k;
          proxy_busy_buffers_size         256k;

          # 502 에러를 없애기 위한 fastcgi 버퍼 관련 설정입니다.
          fastcgi_buffering               on;
          fastcgi_buffer_size             16k;
          fastcgi_buffers                 16 16k;

          # 최대 timeout 설정입니다.
          fastcgi_connect_timeout         600s;
          fastcgi_send_timeout            600s;
          fastcgi_read_timeout            600s;

          # 이 아래 설정은 PHP 성능 향상을 위한 옵션입니다. 추가해 주시면 좋습니다.
          sendfile                        on;
          tcp_nopush                      off;
          keepalive_requests              0;

 (... 이하 생략 ...)

– 이후 nginx와 php7.0-fpm 을 restart (또는 reload) 해주시면 됩니다.
아마 이것으로 대부분의 502 에러는 해결이 됩니다.

$  sudo service nginx restart
$  sudo service php7.0-fpm restart

 

 

▶ 해결책 2 : nginx의 설정 파일과 php-fpm 설정 파일의 소켓 일치시키기

– 간혹 nginx의 설정 안에서의 ‘fastcgi-pass’ 경로와, php-fpm 설정 파일의 listen 경로가 다른 경우, 502 Bad gateway 에러가 나타나는 경우가 있다고도 합니다. 이런 경우에는 PHP를 불러오는 대다수의 경우의 에러가 발생하는 경우가 많습니다.

– 먼저 nginx 설정 파일에서 PHP를 처리하는 부분의, fastcgi-pass 값을 확인하여 PHP-fpm sock 파일이 정상적으로 위치해 있는지 확인합니다. (없는 경우에는, sock 파일을 찾아서 적당한 경로로 입력해 주어야 합니다. 많은 경우에는 /var/ 디렉토리 안에서 php 관련 폴더 안에 위치하고 있습니다.)

# nginx 설정 파일 내 PHP 처리 부분(저의 경우는 /etc/nginx/sites-available/default 내)에서,
# location ~ \.php$ { 부분으로 시작하는 곳을 찾습니다.

        location ~ \.php$ {
# 안에서,
                fastcgi_pass unix:/your/php/sample/php7.0-fpm.sock;
# 부분의 경로에 sock 파일이 있는지 확인합니다.

 -------------------------

$  ls -al /your/php/sample/
-rw-r--r--  1 root     root       4  1월  8 12:34 php7.0-fpm.pid

 

– sock 파일이 있는 것을 확인했다면, PHP-fpm 설정 파일에서 listen 부분의 sock 파일이 경로가 동일한지 확인합니다.

$  sudo nano /etc/php/7.0/fpm/pool.d/www.conf
 (PHP 버전 및 설치 방법에 따라 설정파일 경로가 다를 수 있음)


[www]
 (중에서, )

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /your/php/sample/php7.0-fpm.sock

 (listen 부분의 경로가 nginx 설정 파일의 경로와 일치하게 수정)

 

설정이 끝난 이후, nginx와 php-fpm을 재시작(또는 reload) 해 줍니다.

$  sudo service nginx restart
$  sudo service php7.0-fpm restart

 

 

▶ 해결책 3 : php-fpm 설치 후 php-fpm을 실행하지 않은 경우 (…)

– 매우 드문 경우이긴 합니다만, php-fpm 을 설치한 이후 실행하지 않아서 작동하지 않는 경우가 있을 수도 있습니다. (…) service 명령어를 이용해 아래와 같은 명령어들을 실행해 봅니다.

$  sudo service php-fpm start
$  sudo service php5-fpm start
$  sudo service php7.0-fpm start

– 혹은 그저, 프로세스의 문제로 재시작을 하여 문제가 해결되는 경우도 있다고 합니다.

$  sudo service php-fpm restart
$  sudo service php5-fpm restart
$  sudo service php7.0-fpm restart

 

 

▶ 끝마치며

nginx와 php-fpm은 간혹 다양한 문제를 내뿜기도 합니다만, 확실히 Apache2 + PHP 조합보다 더 나은 성능과, 복합적인 처리 능력을 자랑하는 만큼, 다양한 에러를 해결해 나가면서 점점 nginx가 최적화 될 수 있도록 설정하실 수 있으실 것이라고 확신합니다.

502 Bad gateway 또한 다양한 이유에 의해 문제가 발생하고 있기도 하고, 또 다양한 방법으로 해결되기도 합니다. 그런 만큼, 포기하지 마시고 해결하실 수 있으시면 좋겠습니다.

이상으로 글을 마치겠습니다.
다양한 코멘트 늘 기다리고 있습니다. ^^

gomgom

무엇을 하든 곰곰히 생각하는 곰곰입니다.

You may also like...

13 Responses

  1. 이온디 댓글:

    팁 감사합니다.
    default.conf 에만 위 사항(팁1번)을 적용시켜두면
    나머지 계정 들은 안 적어줘도 상관 없는가요?

    저의 경우 서버에 유저 계정을 여러개 두고 있는데
    각 유저.conf 파일마다 다 저렇게 입력해두어야 하는지 궁금합니다.

    • 곰곰 댓글:

      안녕하세요. 댓글 감사드립니다. ^^
      default.conf 에 1번 팁을 적용하실 경우에는, 각 도메인별 설정 파일의 server { } 안에 내용을 넣어주셔야 할 것 같습니다. ^^;

      단, 기본으로 적용되는 nginx 설정 파일(예: /etc/nginx/nginx.conf)에 server { } 를 만들어서 그 안에 내용을 넣어주면 공통으로 적용될 것 같긴 한데,
      nginx.conf 기본 파일에 server { } 가 있어도 되었는지 안되었는지가 기억이 애매모호합니다… ^^;

      한 번 시도해보시고, 혹시 안되는 경우는 개별 사이트 설정 파일마다 입력을 해 주셔야 할 것 같습니다. ^^

  2. 이온디 댓글:

    안녕하세요 곰곰이님.
    제 경우는 음.. 뭔가 계속 게시판을 통해서 뭔가를 계속 시도하는 것 같아요.
    GET /eond/?mid=link&document_srl=&page=&accept_agreement=&user_id=RulhmcDXOqPqfgc&password1=&password2=&user_name=jonn1&nick_name=jonn1&email_address=email%40gmail.com&homepage=http%3A%2F%2Fwww.interracial-romance.heartwoodcellars.com%2Famericana%2Fepub-229-1075-sejf.pdf&blog=VWSHhixtTzBlmvLHu&birthday=&allow_mailing=Y&open_whyjoin=&whyjoin=comment3%2C+http%3A%2F%2Fwww.young-adult-fantasy.southdenvermassive.com%2Fhealth%2Fepub-371-2992-jutro_niedziela_i_inne_opowiadania.pdf+Jutro+niedziela+i+inne+opowiadania%2C++vxdn%2C+http%3A%2F%2Fwww.flash-fiction.pilatesnewswire.com%2Fthreesome%2Fepub-204-3291-das_kleine_buch_des_friedens_das_kleine_buch_des_friedens.pdf+Das+kleine+Buch+des+Friedens+Das+kleine+Buch+des+Friedens%2C++925%2C+http%3A%2F%2Fwww.gods.heartwoodcellars.com%2Fcanadian-literature%2Fepub-41-866-the_island_of_lost_maps_a_true_story_of_cartographic_crime.pdf+The+Island+of+Lost+Maps%3A+A+True+Story+of+Cartographic+Crime%2C++%3D-O%2C+http%3A%2F%2Fwww.coding.pilatesnewswire.com%2Fhorticulture%2Fepub-13-2467-worship_the_king.pdf+Worship+the+King%2C++%3D%5D%5D%5D%2C+http%3A%2F%2Fwww.tudor-period.pilatesnewswire.com%2F20th-century%2Fepub-12-3772-liar_s_house.pdf+Liar’s+House%2C++009317%2C+http%3A%2F%2Fwww.public-transport.heartwoodcellars.com%2Fbiblical%2Fepub-228-4387-llewellyn_s_2012_witches_spell_a_day_almanac.pdf+Llewellyn’s+2012+Witches’+Spell-A-Day+Almanac%2C++8-%5D%5D%5D%2C+http%3A%2F%2Fwww.public-transport.heartwoodcellars.com%2Fbiblical%2Fepub-118-3422-design_and_nature_v_comparing_design_in_nature_with_science_and_engineering_wit_transactions_on_ecology_and_the_environment_.pdf

    게시판에 아이디와 비번을 대입해서 뭔가를 ? 하는 것 같기도 한데, 이런 경우 저 아이피를 막아야 하나요?;;

    • 곰곰 댓글:

      선생님 홈페이지에 접속을 해서 이리 저리 확인해봐도 어떤 부분에 요청을 보내고 있는지 잘 확인되지 않는 부분이 있네요.
      근데 링크의 내용을 보면 (제가 경험하고 있는 것들이기에) 제가 예상하는 낌새로는, 워드프레스 블로그에 광고를 남기기 위해 댓글을 달도록 하는 자동 스크립트가 선생님 사이트에도 요청을 보내고 있는 것이 아닌가 싶습니다. (선생님 홈페이지를 들어가보면 제로보드 XE 기반의 사이트인 것 같은데, 왜 저런 요청이 가는지는 이해가 안 되네요. ^^; 아니면 혹시… XE용 스팸 작성 요청인걸까요…?)

      제 블로그에는 외국인이 이름, 이메일 등을 포함한 내용으로 영문 스팸을 다는 경우가 많습니다.
      만약 그런 경우인 경우, 서버에 위해를 가하는 그런 것들은 아니지만, 스팸 요청이라고 판단해도 좋을 것 같습니다.

      저러한 내용의 요청을 deny 하시던지, IP를 차단하는 방법도 좋을 것 같습니다. ^^;

      (추: 사실 저도… 비전공자라 자세한 내용을 알고 있지는 못 합니다. ^^; 정말 걱정되신다면 stackoverflow 등에 문의를 해 보셔도 좋을 것 같습니다. ^^)

  3. 우와 댓글:

    감사합니다.

    저는 해결책 3번으로

    fpm restart 로 해결이 되었습니다.

    최근에 리눅스 업데이트하고 뭐하고

    건드는게 있었나봐요 ㅎㅎㅎ

    • 곰곰 댓글:

      잘 해결되셔서 다행입니다. ^^ 사실 저도 프로세스가 켜지지 않아 왜 이러지 하고 고민했던 적이 많았답니다. ㅋㅋ
      댓글 감사드리고 즐거운 하루 되세요! ^^

  4. DAN 댓글:

    안녕하세요 502 에러떄문에 구글링하다가 이렇게 찾아오게되었습니다
    좋은 정보덕분에 금방해결할수있었어요 ㅠㅠ 감사합니다
    이런경우가 또 발생할수있을까봐 적어두고 사용하려하는데
    제 블로그에 출처남기고 사필했는데
    문제가있으면 바로 삭제하도록하겠습니다~

    이메일주세요!

  5. ay 댓글:

    저는 컴맹인지 봐도 모르겠네요..ㅠ.ㅠ
    cmd에서 뭐라고 쳐야하나요..?ㅠㅠ
    죽겠네요..ㅠ.ㅠ

  1. 2016년 10월 2일

    […] 위장한 php파일을 업로드하여 동작시키는 거 방지!) ※ nginx 설정 부분은 >곰곰이오님 블로그<를 […]

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다