[PHP x IIS] 500 에러와 ignore_user_abort, connection_* 미/오작동[PHP x IIS] 500 에러와 ignore_user_abort, connection_* 미/오작동

Posted at 2015/08/16 23:49 | Posted in 프로그래밍

나는 IIS에서 CGI 프로그램으로 PHP를 쓴다. 벌써 3년은 되었다. 한날은 IIS의 실패한 요청 추적 기능으로 기록된 로그를 살펴봤는데, 같은 날에 찍힌 게 100개 이상인 것! 뭔 일인가 싶어 보면 하나같이 밑 그림과 같은 내용이 찍혔더라..

500 Internal Server Error; ErrorCode: 작업을 완료했습니다. (0x0)

URL을 보니 저 에러는 파일 전송 중 발생한 것이었다. 사용자들이 파일을 내려받는 중에 네트워크 오류가 뜬다고 불평을 그렇게 한 게 기억난다.. 며칠 머리 싸매며 안 사실을 밑 목록에 적는다.

  1. 스크립트가 set_time_limit()으로 지정한 시간보다 빨리 종료됨.
  2. 서버 시작 후 조금 지나면 "FastCGI 프로세스가 최근에 자주 실패했습니다." 에러(위 그림)가 막 나옴.

그리고 알아낸 것은 FastCGI 설정 중 작업 시간 제한(activityTimeout)이 PHP 설정 중 max_execution_time(런타임 설정은 set_time_limit())보다 우선순위에 있다는 것이다. "최근에 자주 실패했습니다."라는 에러는 1분 당 허용 실패 횟수(rapidFailsPerMinute) 때문에 발생하는 것이라고 한다.[각주:1]

PHP 설정 중 max_execution_time보다 우선시 되는 것이 PHP 스크립트의 set_time_limit(), 그리고 이보다 우선시 되는 것이 FastCGI 설정 중 작업 시간 제한(activityTimeout)

위 그림처럼 IIS의 FastCGI 설정에 적당한 값을 입력하니 에러가 잠잠해져서 며칠 조용히 살았다.


얼마 전엔 파일 전송 후 임시 파일을 정리하는 코드를 스크립트에 추가했다. 그런데 안 되더라.. 정확히 말하면 스크립트가 중단되더라.. 대충 밑과 비슷한 소스였다.

set_time_limit(0);
header('Content-Disposition: attachment');
// 파일 전송
$fp = fopen('/tmp/bigbigfile', 'rb');
while (!feof($fp))
{
    echo fread($fp, 4096);
    flush();
}
fclose($fp);
// 로그 작성
if (connection_aborted())
{
    fwrite(fopen('/var/fail.log', 'a'), time() . ' ' . $_SERVER['REMOTE_ADDR'] . PHP_EOL);
}

물론 그냥 중단된 게 아니라 중단돼서 중단된 걸 기록해야 하는데 이게 중단된 것! 그래서 찾아보니 PHP는 기본적으로 클라이언트의 요청이 중단되면 스크립트 실행도 중단한단다. 설정으로 제어할 수 있다고 해서 추가했다.

ignore_user_abort(true);
set_time_limit(0);
...

그런데 막상 실행하니 추가 전과 다른 게 없었다. IIS에서 PHP를 돌릴 때는 ignore_user_abort가 제 역할을 못 하는 것이다. 다른 웹서버는 어떤지 모르겠지만, IIS는 설계상 FastCGI 프로그램에서 클라이언트의 요청이 중단됨을 알 수가 없다고 한다. 클라이언트의 요청이 중단되면 FastCGI 프로그램을 그냥 종료하는 듯..[각주:2] 이래서 "최근에 자주 실패했습니다." 에러가 뜬 건감.

같은 맥락으로 connection_status(), connection_aborted() 등의 함수도 IIS에서는 CONNECTION_NORMAL만을 반환한다. 조심하자. 아니면 웹서버를 바꾸든가..

PHP를 불구로 만든 IIS...

저작자 표시 비영리

http://blog.bloodcat.com/trackback/290 관련글 쓰기

Name __

Password __

Link (Your Website)

Comment

1 2 3 4 5 ... 181