Sử dụng sao chổi với PHP?


82

Tôi đã nghĩ đến việc triển khai trò chuyện thời gian thực bằng cách sử dụng phần phụ trợ PHP, nhưng tôi đã xem qua nhận xét này trên một trang web thảo luận về sao chổi:

Tôi hiểu rằng PHP là một ngôn ngữ tồi tệ đối với Comet, bởi vì Comet yêu cầu bạn phải giữ một kết nối liên tục mở cho mỗi ứng dụng khách trình duyệt. Sử dụng mod_php, điều này có nghĩa là buộc toàn thời gian con Apache cho mỗi ứng dụng khách mà không mở rộng quy mô nào cả. Những người tôi biết làm công việc Comet hầu hết đang sử dụng Twisted Python được thiết kế để xử lý hàng trăm hoặc hàng nghìn kết nối đồng thời.

Điều này có đúng không? Hay nó là thứ có thể được cấu hình xung quanh?


4
bạn có thể chạy php như fastcgi ...
Itay Moav -Malimovka

4
Sử dụng nodeJS làm máy chủ để giữ các kết nối máy khách, các cổng kết nối web bằng javascript để kết nối với máy chủ từ trình duyệt. PHP theo nghĩa này có thể là một máy khách riêng sẽ kết nối với nodejs, đẩy một số dữ liệu dịch vụ sẽ được xử lý bằng cách nào đó ở phía máy khách.
Artjom Kurapov

1
@ArtjomKurapov Bạn có thể làm cho PHP vào một máy chủ web do đó bỏ qua phương pháp xử lý yêu cầu của Apache - nghĩ về nó như một máy chủ PHP thực dùng yêu cầu chăm sóc sao chổi chỉ .
Christian

@Christian nếu bạn có nghĩa là built-in php webserver từ 5.4 thì nó chỉ cho sự phát triển và sử dụng nó vào sản xuất là một ý tưởng tồi
Artjom Kurapov

2
@ArtjomKurapov Không, ý tôi là viết một máy chủ PHP thực, bằng cách sử dụng các socket PHP để lắng nghe cổng 80 và chặn đầu vào vô thời hạn - cách máy chủ hoạt động hiệu quả. Điều này có thể được thấy trong các dự án như phpwebsocket .
Christian

Câu trả lời:


61

Đồng ý / mở rộng những gì đã nói, tôi không nghĩ FastCGI sẽ giải quyết được vấn đề.

Apache

Mỗi yêu cầu vào Apache sẽ sử dụng một luồng công nhân cho đến khi yêu cầu hoàn thành, có thể mất nhiều thời gian đối với các yêu cầu COMET.

Bài viết này trên Ajaxian đề cập đến việc sử dụng COMET trên Apache, và nó rất khó. Vấn đề không phải riêng đối với PHP và áp dụng cho bất kỳ mô-đun CGI back-end nào mà bạn có thể muốn sử dụng trên Apache.

Giải pháp được đề xuất là sử dụng mô-đun MPM 'sự kiện' để thay đổi cách các yêu cầu được gửi đến các luồng công nhân.

MPM này cố gắng khắc phục 'sự cố tiếp tục tồn tại' trong HTTP. Sau khi máy khách hoàn thành yêu cầu đầu tiên, máy khách có thể giữ kết nối mở và gửi các yêu cầu khác bằng cách sử dụng cùng một ổ cắm. Điều này có thể tiết kiệm chi phí quan trọng trong việc tạo kết nối TCP. Tuy nhiên, Apache theo truyền thống giữ toàn bộ quy trình / luồng con để chờ dữ liệu từ máy khách, điều này mang lại những bất lợi riêng. Để giải quyết vấn đề này, MPM này sử dụng một luồng chuyên dụng để xử lý cả các ổ cắm Nghe và tất cả các ổ cắm ở trạng thái Keep Alive.

Thật không may, điều đó cũng không hoạt động, vì nó sẽ chỉ 'báo lại' sau khi một yêu cầu hoàn tất, chờ một yêu cầu mới từ khách hàng.

PHP

Bây giờ, xem xét mặt khác của vấn đề, ngay cả khi bạn giải quyết vấn đề bằng cách giữ một luồng cho mỗi yêu cầu sao chổi, bạn vẫn sẽ cần một luồng PHP cho mỗi yêu cầu - đây là lý do tại sao FastCGI sẽ không giúp được gì.

Bạn cần một cái gì đó như Tiếp tục cho phép các yêu cầu sao chổi được tiếp tục khi sự kiện chúng được kích hoạt được quan sát thấy. AFAIK, đây không phải là thứ có thể thực hiện được trong PHP. Tôi chỉ thấy nó trong Java - hãy xem máy chủ Apache Tomcat .

Biên tập:

Có một bài viết ở đây về việc sử dụng bộ cân bằng tải ( HAProxy ) để cho phép bạn chạy cả máy chủ apache và máy chủ hỗ trợ sao chổi (ví dụ: jetty, tomcat cho Java) trên cổng 80 của cùng một máy chủ.


20
Tôi nhận ra điều này không chính xác cung cấp một giải pháp: /
Mike Houston

+1 vì Apache / PHP không phải là lựa chọn tốt để mở rộng giải pháp sao chổi. Các tùy chọn cho người dùng PHP là 1) như bạn đã đề cập, cấu hình điên rồ của các máy chủ và proxy bổ sung hoặc 2) sử dụng giải pháp SaaS và giảm tải nội dung sao chổi thông qua thứ gì đó như WebSync On-Demand.
jvenema

1
Điều này sai ở một số khía cạnh. Nếu ai đó muốn rời khỏi phương thức một luồng cho mỗi người dùng, nó có thể dễ dàng đạt được bằng cách xóa Apache làm trung gian và để PHP xử lý các yêu cầu này. Tất nhiên, Apache hoạt động tốt hơn trong việc cung cấp nội dung, vì vậy tôi sẽ chạy máy chủ PHP không có apache này trên một miền phụ không phân phát bất kỳ nội dung nào.
Christian

@MikeHouston Vậy thử sao chổi với php trong IIS.?
ravi404 27/09/12

@ravz, có một số nội dung ở đây về IIS và sao chổi: stackoverflow.com/questions/1898848/comet-programming-in-iis , nhưng tôi nghi ngờ mô-đun fast-cgi PHP có những hạn chế tương tự như với apache. Nó đề cập đến một môi trường luồng đơn tại đây: microsoft.com/web/platform/phponwindows.aspx - Bản thân tôi không sử dụng máy chủ Windows, vì vậy tôi không chắc chắn về mô hình phân luồng.
Mike Houston

14

Bạn có thể sử dụng Nginx và JavaScript để triển khai hệ thống trò chuyện dựa trên Comet có khả năng mở rộng rất cao với ít bộ nhớ hoặc sử dụng CPU.

Tôi có một ví dụ rất đơn giản ở đây có thể giúp bạn bắt đầu. Nó bao gồm việc biên dịch Nginx với mô-đun NHPM và bao gồm mã cho các vai trò nhà xuất bản / người đăng ký đơn giản trong jQuery, PHP và Bash.

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


10

PHP

Tôi thấy điều này hài hước chút Screencasts giải thích sao chổi đơn giản. Như một lưu ý phụ, tôi thực sự nghĩ rằng điều này sẽ giết chết máy chủ của bạn khi tải thực. Khi chỉ có một vài người dùng, tôi sẽ nói chỉ sử dụng giải pháp này. Giải pháp này thực sự đơn giản để thực hiện (các video truyền hình chỉ mất 5 phút thời gian của bạn :)). Nhưng như tôi đã nói trước đây, tôi không nghĩ nó tốt cho nhiều người dùng đồng thời (Đoán rằng bạn nên đánh giá điểm chuẩn cho nó;)) bởi vì:

  1. Nó sử dụng tệp I / O chậm hơn nhiều sau đó chỉ lấy dữ liệu từ bộ nhớ. Ví dụ như các chức năng filemtime(),
  2. Thứ hai, nhưng tôi không nghĩ rằng PHP không có một mô hình luồng tốt. PHP không được thiết kế cho việc này vì mô hình không chia sẻ gì cả . Giống như các trang trình bày nói "Dữ liệu được chia sẻ được đẩy xuống tầng lưu trữ dữ liệu" như MySQL chẳng hạn.

Giải pháp thay thế

Tôi thực sự nghĩ rằng bạn nên thử các lựa chọn thay thế nếu bạn muốn thực hiện bất kỳ cuộc thăm dò sao chổi / dài. Bạn có thể sử dụng nhiều ngôn ngữ như ví dụ:

  • Java / JVM: Sự liên tục của cầu tàu .
  • Python: Dustin's slosh .
  • Erlang: Ngôn ngữ phổ biến cho sao chổi / vv.
  • Lua, Ruby, C, Perl chỉ để kể tên một vài.

Chỉ cần thực hiện một tìm kiếm google đơn giản, sẽ cho bạn thấy rất nhiều lựa chọn thay thế cũng là PHP (tôi nghĩ rằng trên bất kỳ tải lớn nào sẽ giết chết máy chủ của bạn).



6

Bạn cũng có thể thử https://github.com/reactphp/react

React là một thư viện cấp thấp để lập trình theo hướng sự kiện trong PHP. Cốt lõi của nó là một vòng lặp sự kiện, trên đó nó cung cấp các tiện ích cấp thấp, chẳng hạn như: Tóm tắt luồng, trình phân giải dns không đồng bộ, máy khách / máy chủ mạng, máy khách / máy chủ http, tương tác với các quy trình. Thư viện của bên thứ ba có thể sử dụng các thành phần này để tạo máy khách / máy chủ mạng không đồng bộ và hơn thế nữa.

Vòng lặp sự kiện dựa trên mẫu lò phản ứng (do đó có tên) và được truyền cảm hứng mạnh mẽ từ các thư viện như EventMachine (Ruby), Twisted (Python) và Node.js (V8).

Ví dụ giới thiệu cho thấy một máy chủ HTTP đơn giản đang lắng nghe trên cổng 1337:

<?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

Tôi đang gặp vấn đề tương tự. Một tùy chọn mà tôi thấy thú vị là sử dụng máy chủ Comet hiện có, như cometd-java hoặc cometd-python, làm trung tâm thông báo cốt lõi. Mã PHP của bạn sau đó chỉ là một ứng dụng khách đối với máy chủ Comet - nó có thể đăng hoặc đọc tin nhắn từ các kênh, giống như các ứng dụng khách khác.

Có một đoạn mã thú vị được liên kết ở đây: http://morglog.org/?p=22=1 triển khai một phần của phương pháp này (mặc dù cũng có các bit mã gỡ lỗi được lan truyền xung quanh).


3

Tôi hiện đang triển khai một máy chủ PHP Comet có thể mở rộng bằng cách sử dụng các hàm socket. Nó được gọi là 'phet' ([ph] p com [et])

Trang dự án: http://github.com/Tim-Smart/phet

Miễn phí miễn phí để tham gia phát triển. Tôi hiện đã quản lý để hoàn thành hầu hết logic máy chủ, chỉ cần hoàn thành công việc phía máy khách.

CHỈNH SỬA: Khả năng 'Đa luồng' được thêm gần đây bằng pcntl_forkphương pháp :)


Không có sẵn ví dụ về cách sử dụng thư viện này.
ftrotter

3

Bạn sẽ gặp khó khăn trong việc triển khai sao chổi trong PHP, chỉ vì nó vốn có một luồng đơn.

Kiểm tra Websync On-Demand - dịch vụ cho phép bạn tích hợp PHP thông qua xuất bản phía máy chủ, giảm tải nội dung kết nối đồng thời nặng nề và cho phép bạn tạo ứng dụng trò chuyện thời gian thực ngay lập tức.



1

Bạn sẽ phải tạo máy chủ của riêng mình bằng PHP. Sử dụng Apache / mod_php hoặc thậm chí fastcgi sẽ không mở rộng quy mô. Mới vài tuổi, nhưng bạn có thể bắt đầu:

PHP-Comet-Server: http://sourceforge.net/projects/comet/


0

Tôi nghĩ rằng đây là một vấn đề mà có nhiều luồng apache chạy mọi lúc là một vấn đề. Điều đó sẽ tồn tại với bất kỳ ngôn ngữ nào nếu nó hoạt động thông qua apache theo cách giống như PHP (thông thường).


1
Tôi nghĩ vấn đề là bạn thường chạy php trong một quy trình cho mỗi yêu cầu, thay vì một chuỗi cho mỗi yêu cầu.
troelskn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.