PHP와 함께 혜성을 사용하십니까?


82

PHP 백엔드를 사용하여 실시간 채팅을 구현하려고 생각했지만 혜성을 논의하는 사이트에서이 댓글을 보았습니다.

내 이해는 Comet은 각 브라우저 클라이언트에 대한 지속적인 연결을 유지하도록 요구하기 때문에 PHP는 Comet에게 끔찍한 언어라는 것입니다. mod_php를 사용하는 것은 전혀 확장되지 않는 각 클라이언트에 대해 아파치 자식을 풀 타임으로 묶는 것을 의미합니다. 내가 아는 사람들은 Comet 작업을하는 사람들이 대부분 수백 또는 수천 개의 동시 연결을 처리하도록 설계된 Twisted Python을 사용하고 있습니다.

이것이 사실입니까? 아니면 구성 할 수있는 것입니까?


4
당신은 ... FastCGI를로 PHP를 실행할 수 있습니다
Itay Moav -Malimovka에게

4
nodeJS를 서버로 사용하여 클라이언트 연결을 유지하고, 자바 스크립트의 웹 소켓을 사용하여 브라우저에서 서버에 연결합니다. 이런 의미에서 PHP는 nodejs에 연결하고 클라이언트 측에서 어떻게 든 처리 될 일부 서비스 데이터를 푸시하는 권한있는 클라이언트가 될 수 있습니다.
Artjom Kurapov

1
@ArtjomKurapov PHP를 웹 서버로 만들 수 있으므로 Apache의 요청 처리 방법을 우회 할 수 있습니다 . 혜성 요청 처리하는 실제 PHP 서버처럼 생각하면 됩니다 .
Christian

@Christian 당신이 내장 된 것을 의미하는 경우 PHP는 웹 서버 5.4 이후는 만 생산에 그것을 사용하여 개발하고 나쁜 생각은
Artjom Kurapov

2
@ArtjomKurapov 아니요, PHP 소켓을 사용하여 포트 80을 수신하고 입력을 무기한 차단함으로써 실제 PHP 서버를 작성하는 것을 의미했습니다. 효과적으로 서버가 작동하는 방식입니다. 이것은 phpwebsocket 과 같은 프로젝트에서 이미 실제로 볼 수 있습니다 .
Christian

답변:


61

이미 말한 내용에 동의 / 확대하면 FastCGI가 문제를 해결할 수 없다고 생각합니다.

Apache

Apache에 대한 각 요청은 요청이 완료 될 때까지 하나의 작업자 스레드를 사용합니다. COMET 요청에는 시간이 오래 걸릴 수 있습니다.

Ajaxian에 대한 이 기사에서는 Apache에서 COMET을 사용하는 것에 대해 언급하고 있으며 이는 어렵습니다. 이 문제는 PHP에만 국한된 것이 아니며 Apache에서 사용하려는 모든 백엔드 CGI 모듈에 적용됩니다.

제안 된 해결책은 요청이 작업자 스레드로 전달되는 방식을 변경하는 '이벤트'MPM 모듈 을 사용하는 것 입니다.

이 MPM은 HTTP의 'keep alive 문제'를 수정하려고합니다. 클라이언트가 첫 번째 요청을 완료 한 후 클라이언트는 연결을 열린 상태로 유지하고 동일한 소켓을 사용하여 추가 요청을 보낼 수 있습니다. 이것은 TCP 연결을 생성 할 때 상당한 오버 헤드를 줄일 수 있습니다. 그러나 Apache는 전통적으로 전체 자식 프로세스 / 스레드가 클라이언트의 데이터를 기다리도록 유지하므로 자체 단점이 있습니다. 이 문제를 해결하기 위해이 MPM은 전용 스레드를 사용하여 Listening 소켓과 Keep Alive 상태에있는 모든 소켓을 모두 처리합니다.

안타깝게도이 방법도 작동하지 않습니다 . 요청이 완료된 후에 만 '스누즈' 하여 클라이언트의 새 요청을 기다리기 때문입니다.

PHP

이제 문제의 다른 측면을 고려하면 comet 요청 당 하나의 스레드를 유지하는 문제를 해결하더라도 요청 당 하나의 PHP 스레드가 필요합니다. 이것이 FastCGI가 도움이되지 않는 이유입니다.

혜성 요청이 트리거 된 이벤트가 관찰 될 때 재개되도록 허용하는 Continuations 와 같은 것이 필요합니다 . AFAIK, 이것은 PHP에서 가능한 것이 아닙니다. Java에서만 본 적이 있습니다 . Apache Tomcat 서버를 참조하십시오 .

편집하다:

있다 기사는 여기 부하 분산 (사용에 대한 HAProxy를 당신이 아파치 서버와 같은 서버의 포트 80에서 혜성을 사용하는 서버 (예를 들어, 부두, 자바에 대한 바람둥이) 모두를 실행할 수 있도록).


20
나는 이것이 정확히 해결책을 제공하지 않는다는 것을 알고 있습니다 : /
Mike Houston

왜냐하면 Apache / PHP는 혜성 솔루션을 확장하기위한 좋은 옵션이 아니기 때문입니다. PHP 사용자를위한 옵션은 1) 언급했듯이 추가 서버 및 프록시의 미친 구성 또는 2) SaaS 솔루션을 사용하고 WebSync On-Demand와 같은 것을 통해 혜성을 오프로드하는 것입니다.
jvenema 2010

1
이것은 여러 측면에서 잘못된 것입니다. 사용자 당 하나의 스레드 방식을 남기고 싶다면 Apache를 중개자로서 제거하고 PHP가 이러한 요청을 처리하도록함으로써 쉽게 달성 할 수 있습니다. 물론 Apache는 콘텐츠를 제공하는 데 더 잘 작동하므로 콘텐츠를 제공하지 않는 하위 도메인에서 Apache가없는이 PHP 서버를 실행할 것입니다.
Christian

@MikeHouston IIS에서 PHP로 혜성을 시도하는 것은 어떻습니까?
ravi404

@ravz, 여기에 IIS와 혜성에 관한 몇 가지 사항이 있습니다 : stackoverflow.com/questions/1898848/comet-programming-in-iis ,하지만 fast-cgi PHP 모듈에는 아파치와 동일한 제한이 있다고 생각합니다. 여기에 단일 스레드 환경이 언급되어 있습니다. microsoft.com/web/platform/phponwindows.aspx-Windows 서버를 직접 사용하지 않으므로 스레딩 모델에 대해 잘 모르겠습니다.
Mike Houston

14

Nginx 및 JavaScript를 사용하여 메모리 또는 CPU 사용률이 거의없이 매우 확장 가능한 Comet 기반 채팅 시스템을 구현할 수 있습니다.

여기에 여러분이 시작할 수있는 아주 간단한 예가 있습니다. NHPM 모듈로 Nginx 컴파일을 다루고 jQuery, PHP 및 Bash에서 간단한 게시자 / 구독자 역할에 대한 코드를 포함합니다.

http://blog.jamieisaacs.com/2010/08/27/comet-with-nginx-and-jquery/


10

PHP

이 재미있는 작은 스크린 캐스트를 찾았습니다 단순한 혜성을 설명하는 . 부수적으로 나는 이것이 실제 부하에서 서버를 죽일 것이라고 정말로 생각합니다. 사용자가 몇 명 뿐인 경우에는이 솔루션을 선택하겠습니다. 이 솔루션은 구현하기가 정말 간단합니다 (스크린 캐스트는 5 분만 소요됩니다. :)). 그러나 이전에 말했듯이 많은 동시 사용자에게 좋지 않다고 생각합니다 (벤치 마크해야합니다;)).

  1. 메모리에서 데이터를 가져 오는 것보다 훨씬 느린 파일 I / O를 사용합니다. 예를 들어 기능처럼filemtime() ,
  2. 둘째, 그러나 최소한 PHP가 적절한 스레드 모델을 가지고 있지 않다고 생각합니다. PHP는 아무것도 공유하지 않는 모델 때문에 어쨌든 이것을 위해 설계되지 않았습니다 . 슬라이드에서 "공유 된 데이터는 데이터 저장소 계층으로 푸시 다운됩니다"(예 : MySQL).

대안

혜성 / 긴 폴링을하고 싶다면 대안을 시도해야한다고 생각합니다. 예를 들어 다음과 같은 많은 언어를 사용할 수 있습니다.

  • 자바 / JVM : Jetty 연속 .
  • Python : 더스틴의 슬로 쉬 .
  • 얼랭 : 혜성 등의 인기있는 언어입니다.
  • Lua, Ruby, C, Perl이 몇 가지 예입니다.

간단한 Google 검색을 수행하면 PHP도 많은 대안을 볼 수 있습니다 (큰 부하로 인해 서버가 죽을 것이라고 생각합니다).



6

https://github.com/reactphp/react 시도 할 수도 있습니다.

React는 PHP의 이벤트 기반 프로그래밍을위한 저수준 라이브러리입니다. 핵심에는 이벤트 루프가 있으며 그 위에는 스트림 추상화, 비동기 DNS 해석기, 네트워크 클라이언트 / 서버, http 클라이언트 / 서버, 프로세스와의 상호 작용과 같은 저수준 유틸리티를 제공합니다. 타사 라이브러리는 이러한 구성 요소를 사용하여 비동기 네트워크 클라이언트 / 서버 등을 만들 수 있습니다.

이벤트 루프는 리액터 패턴 (따라서 이름)을 기반으로하며 EventMachine (Ruby), Twisted (Python) 및 Node.js (V8)와 같은 라이브러리에서 강하게 영감을 받았습니다.

소개 예제는 포트 1337에서 수신하는 간단한 HTTP 서버를 보여줍니다.

<?php

$i = 0;

$app = function ($request, $response) use (&$i) {
    $i++;

    $text = "This is request number $i.\n";
    $headers = array('Content-Type' => 'text/plain');

    $response->writeHead(200, $headers);
    $response->end($text);
};

$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server($loop);
$http = new React\Http\Server($socket);

$http->on('request', $app);

$socket->listen(1337);
$loop->run();

4

비슷한 문제가 있습니다. 흥미로운 옵션 중 하나는 cometd-java 또는 cometd-python과 같은 기존 Comet 서버를 핵심 메시지 허브로 사용하는 것입니다. PHP 코드는 Comet 서버의 클라이언트 일뿐입니다. 다른 클라이언트와 마찬가지로 채널에서 메시지를 게시하거나 읽을 수 있습니다.

여기에 링크 된 흥미로운 코드 스 니펫이 있습니다. http://morglog.org/?p=22=1 이 메소드의 일부를 구현하는 것입니다 (비록 디버그 코드도 분산되어 있음).


3

현재 소켓 함수를 사용하여 확장 가능한 PHP Comet 서버를 구현하고 있습니다. 'phet'([ph] p com [et])라고합니다.

프로젝트 페이지 : http://github.com/Tim-Smart/phet

무료로 개발에 참여할 수 있습니다. 나는 현재 대부분의 서버 로직을 완료하고 클라이언트 측 작업을 완료하면됩니다.

편집 : 최근 pcntl_fork방법 을 사용하여 '멀티 스레딩'기능 추가 :)


이 라이브러리를 사용하는 방법에 대해 쉽게 사용할 수있는 예제는 없습니다.
ftrotter

3

고유 한 단일 스레드 특성 때문에 PHP에서 혜성을 구현하기가 어려울 것입니다.

Websync On-Demand를 확인하십시오. 이 서비스를 사용하면 서버 측 게시를 통해 PHP를 통합하고 과도한 동시 연결 작업을 오프로드 할 수 있으며 실시간 채팅 앱을 즉시 만들 수 있습니다.




0

나는 이것이 항상 많은 아파치 스레드를 실행하는 것이 문제가되는 문제라고 생각합니다. PHP (보통)와 같은 방식으로 아파치를 통해 작동하면 모든 언어에 존재합니다.


1
요점은 일반적으로 요청 당 스레드가 아닌 요청 당 프로세스에서 PHP를 실행한다는 것입니다.
troelskn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.