2013-04-18 2 views
4

우리 회사의 ERP에서 긴 폴링 기반 알림 서비스를 구현하려고합니다. Facebook 알림과 비슷합니다. 사용Ajax와 PHP로 긴 폴링 - 아파치 동결

기술 :

  • PHP 60 초 timeout 세트와 반복 될 때마다 1 초로 sleep.
  • jQuery for AJAX handling.
  • 웹 서버로 아파치.

코딩 거의 한 달 후, 우리는 생산에 갔다. 배포 후 몇 분 후에 모든 것을 롤백해야했습니다. 우리 서버 (8 코어)는 ~ 5 개의 브라우저 탭을 사용하여 20 명의 직원으로부터의 긴 요청을 처리 할 수 ​​없다는 것이 밝혀졌습니다. 예 : 사용자가 ERP로 3 개의 탭을 열었습니다. 각 탭에는 하나의 긴 폴링 AJAX가 있습니다. 4 번 탭을 열면 불가능합니다. 이전 3 번 중 하나가 죽을 때까지 중단됩니다 (따라서 AJAX가 중지됩니다).

'Apache 제한'이라고 생각했습니다. 그래서 우리는 인터넷 검색을 시작했습니다. 아파치의 MPM 모듈과 설정에 대한 정보를 찾았습니다. 우리 서버는 prefork MPM을 사용합니다. apachectl -l이 표시되어 있습니다. 그래서 config에서 몇 줄을 다음과 같이 바 꾸었습니다.

<IfModule mpm_prefork_module> 
    StartServers   1 
    MinSpareServers  16 
    MaxSpareServers  32 
    ServerLimit   50% 
    MaxClients   150 
    MaxClients   50% 
    MaxRequestsPerChild 0 
</IfModule> 

재미있는 점은 비슷한 구성의 내 로컬 컴퓨터에서도 작동한다는 것입니다. 서버에서는 MinSpareServers을 16으로 설정하면 아파치가 config를 무시하는 것처럼 보입니다. 다시 시작한 후 8이됩니다. Whe는 무엇을해야할지 모른다. 이전 게시물의 첫번째 코멘트에

+1

그럴 가능성은 없지만 [서버 당 최대 영구 연결 제한] (http://stackoverflow.com)/a/985704/570812)를 여러 브라우저에서 구현했습니다. 4 번째 탭이 연결된 직원 수에 상관없이 테스트를 수행 할 수 있습니다. – Passerby

+0

아파치/PHP 스레드를 잠그는 페이지를 잠들지 마십시오. 아파치 작업자 등을 늘리고 모든 쓰레기를 처리해야합니다. 내 CRM 플랫폼에서는 사용자 ID별로 간단한 텍스트 파일 검색을 수행합니다. 마지막 체크의 타임 스탬프와 현재의 타임 스탬프가 다른 경우> 60이면 폴링을 수행하고 아무 것도하지 않습니다. 매초마다 실행되도록 스크립트를 설정하십시오. – Dave

+0

Python을 통해 webSock을 사용해보십시오. –

답변

4

지나가는 우리가 하나 개의 서버에 최대 브라우저 연결을 명중 있는지 확인하기 위해 나에게 좋은 방향을 주었다.

알고 보니, 각 브라우저가 그 한계를 가지고 있으며, (내가 아는까지) 당신이 그들을 변경할 수 없습니다. 작동시키기위한 해결 방법을 만들었습니다. 그래서

http://31289.domain.com/ajax 
http://43289.domain.com/ajax 

과 :

의 내가 최대 브라우저 연결을 치는 피하기 위해

http://domain.com/ajax 

에서 AJAX 데이터를 가져 오는 것을 가정 해 봅시다, 각 긴 폴링 AJAX처럼 임의의 하위 도메인에 연결합니다. DNS 서버에는 *.domain.com에서 domain.com 사이의 와일드 카드가 있고 하위 도메인은 각 탭에서 JS가 생성 한 고유 한 난수입니다.

자세한 내용은 this thread을 확인하십시오.

AJAX Same Origin Security에도 몇 가지 문제가 있지만 JSPHP 쪽 모두에서 적절한 헤더를 사용하여 해결할 수있었습니다.

헤더에 대해 자세히 알고 싶다면 here on StackOverflowhere on Mozilla Developer's page을 확인하십시오. 감사!

+2

연결에 브라우저 제한을 제외하고 말하면, 긴 폴링은 아파치 서버에서 잘 작동하고 있습니까? –

2

긴 폴링을 사용하여 램프 설정을 성공적으로 구현했습니다. 두 가지 사항을 염두에 두어야 할 리눅스 용 PHP 내부 실행 클럭은 'usleep()'함수에 의해 변경되거나 증가되지 않습니다.따라서 최대 실행 시간 설정은 데이터를 얻는 데 평소보다 오래 걸리는 희귀 한 경우 또는 Windows 설정의 경우에만 필요합니다. 또한 긴 폴링을 염두에두고 일단 20 초 이상 지나면 브라우저 시간 제한이 발생하는 것에 취약합니다.

두 번째로, 세션이 잠겨 있지 않은지 확인해야합니다 (세션을 사용중인 경우).

아파치는 당신이하고자하는 것에 대해 어떤 문제도 있어서는 안됩니다. 하지만, nginx 나 ajax-specific 웹 서버 같은 웹 서버가 동시 연결을 더 잘 처리 할 수 ​​있음을 인정합니다. ajax 처리기에 대한 코드를 게시 할 수 있다면 문제의 위치를 ​​파악할 수 있습니다.

하위 도메인을 사용하거나 다른 스레드가 제안한 것처럼 - 별도의 포트에 여러 웹 서버가있는 경우 JavaScript 도메인 보안 문제가 발생할 수 있음을 기억하십시오.

내가 말하기를, 문제가 발생할 때까지 아파치 설정을 변경하지 말고 모든 다른 옵션을 다 써 버렸다. PHP 세션에주의하고 AJAX가 다른 요청을 보내기 전에 AJAX가 응답을 기다리고 있는지 확인하십시오.)

+1

내 알림 서비스를 개발하는 동안 나는 많은 것을 시도했습니다. 나는 또한 당신이 제안한 것과 비슷한 것을했다. 한 번에 수백 개 (또는 그 이상)의 연결을 지원하려고 할 때 전체 아이디어가 실패합니다. 서버를 죽일뿐입니다. 내가 더 나은 솔루션을 발견 - Node.js Socket.io와 연결 프로토콜로. 나는 새로운 기술을 배우는 데 약간의 시간이 필요하다는 것을 알고 있지만, 그만한 가치가있다. 그만한 가치가있어, 나는 내 컴퓨터 과학 학위 석사 학위에 그것을 설명하는 해의 절반을 보내고있다 :) 당신은 그것을 시도해야한다! 재미있어! – ex3v