nginx는 Apache2에 비해서 빠르고 더 많은 트래픽을 처리할 수 있는 HTTP 처리 능력을 가진 웹서버 데몬입니다. 아울러 PHP와 같이 구동되는 웹 어플리케이션을 사용할 때는, PHP-fpm을 사용하여 더 빠른 PHP 처리를 이끌어 낼 수 있지요.
하지만, 간혹 nginx + php-fpm 조합을 활용하여 웹 어플리케이션을 구동할 경우, 특정한 상황의 경우 502 Bad gateway 에러를 내뿜는 경우를 확인할 수 있습니다.
![[ 필자의 경우는 CloudFlare의 502 에러 페이지입니다만, 이와 유사한 에러가 자주 등장 ]](https://blog.gomgom.net/wordpress/wp-content/uploads/2016/01/01_502_error.jpg)
제가 추론하고 있는 특정한 상황은,
- PHP-fpm으로 처리 해야 되는 자료 중에서 굉장히 크기가 큰 요청을 처리하는 경우
- 서버 반응속도가 느려 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의 서비스 상태는 정상 작동함을 확인할 수 있습니다. ]](https://blog.gomgom.net/wordpress/wp-content/uploads/2016/01/02_service_status.jpg)
– 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 또한 다양한 이유에 의해 문제가 발생하고 있기도 하고, 또 다양한 방법으로 해결되기도 합니다. 그런 만큼, 포기하지 마시고 해결하실 수 있으시면 좋겠습니다.
이상으로 글을 마치겠습니다.
다양한 코멘트 늘 기다리고 있습니다. ^^
답글 남기기