PHP ile kuyruklu yıldız mı kullanıyorsunuz?


82

Bir PHP arka ucu kullanarak gerçek zamanlı sohbet uygulamayı düşünüyordum, ancak bu yorumu bir sitede kuyruklu yıldızın tartışıldığı bir sitede buldum:

Anladığım kadarıyla PHP Comet için berbat bir dildir, çünkü Comet her tarayıcı istemcisine sürekli bir bağlantı açık tutmanızı gerektirir. Mod_php kullanmak, her istemci için bir Apache çocuğunu tam zamanlı olarak bağlamak anlamına gelir ki bu hiç ölçeklenmez. Comet işi yapan tanıdığım insanlar çoğunlukla yüzlerce veya binlerce eşzamanlı bağlantıyı idare etmek için tasarlanmış Twisted Python kullanıyor.

Bu doğru mu? Yoksa etrafında yapılandırılabilen bir şey mi?


4
php'yi

4
İstemci bağlantılarını korumak için nodeJS'yi bir sunucu olarak, tarayıcıdan sunucuya bağlanmak için javascript'teki web yuvalarını kullanın. Bu anlamda PHP, nodej'lere bağlanan, istemci tarafında bir şekilde ele alınacak bazı hizmet verilerini iten ayrıcalıklı bir istemci olabilir.
Artjom Kurapov

1
@ArtjomKurapov PHP'yi bir web sunucusuna dönüştürerek Apache'nin istekleri işleme yöntemini atlayabilirsiniz - bunu yalnızca kuyruklu yıldız isteklerini dikkate alan gerçek bir PHP sunucusu gibi düşünün .
Christian

@Christian, 5.4'ten beri yerleşik php web sunucusunu kastediyorsanız, yalnızca geliştirme ve üretimde kullanmak kötü bir fikirdir
Artjom Kurapov

2
@ArtjomKurapov Hayır, 80 numaralı bağlantı noktasını dinlemek ve girişi süresiz olarak engellemek için PHP soketlerini kullanarak gerçek bir PHP sunucusu yazmayı kastettim - sunucuların nasıl etkili bir şekilde çalıştığını. Bu, phpwebsocket gibi projelerde zaten eylemde görülebilir .
Christian

Yanıtlar:


61

Daha önce söylenenleri kabul etmek / genişletmek, FastCGI'nin sorunu çözeceğini düşünmüyorum.

Apaçi

Apache'ye yapılan her istek, istek tamamlanıncaya kadar bir işçi evresi kullanır, bu COMET istekleri için uzun sürebilir.

Ajaxian hakkındaki bu makale, COMET'in Apache üzerinde kullanılmasından ve bunun zor olduğundan bahsetmektedir. Sorun PHP'ye özgü değildir ve Apache'de kullanmak isteyebileceğiniz herhangi bir arka uç CGI modülü için geçerlidir.

Önerilen çözüm, isteklerin çalışan iş parçacıklarına gönderilme şeklini değiştiren 'olay' MPM modülünü kullanmaktı .

Bu MPM, HTTP'deki 'canlı tutma sorununu' gidermeye çalışır. Bir istemci ilk isteği tamamladıktan sonra, istemci bağlantıyı açık tutabilir ve aynı soketi kullanarak başka istekleri gönderebilir. Bu, TCP bağlantıları oluştururken önemli ek yük tasarrufu sağlayabilir. Bununla birlikte, Apache geleneksel olarak tüm alt süreci / iş parçacığını istemciden gelen verileri bekleyerek tutar, bu da kendi dezavantajlarını getirir. Bu sorunu çözmek için bu MPM, hem Dinleme soketlerini hem de Canlı Tut durumundaki tüm soketleri işlemek için özel bir iş parçacığı kullanır.

Sadece 'erteleme' çünkü ne yazık ki, o, ya da çalışmaz sonra bir istek tamamlandıktan istemciden yeni isteği beklerken.

PHP

Şimdi, sorunun diğer tarafını göz önünde bulundurursak, sorunu kuyruklu yıldız isteği başına bir iş parçacığı tutmakla çözseniz bile, istek başına bir PHP iş parçacığına ihtiyacınız olacak - bu nedenle FastCGI yardımcı olmayacak.

Sen gibi bir şey gerekiyor continuations onlar tarafından tetiklenen olay algılandığında, kuyruklu yıldız istekleri devam edilmesini sağlar. AFAIK, bu PHP'de mümkün olan bir şey değil. Bunu yalnızca Java'da gördüm - Apache Tomcat sunucusuna bakın .

Düzenle:

Burada , aynı sunucunun 80 numaralı bağlantı noktasında hem bir apache sunucusunu hem de bir kuyruklu yıldız etkin sunucuyu (örneğin jetty, tomcat for Java) çalıştırmanıza izin verecek bir yük dengeleyici ( HAProxy ) kullanma hakkında bir makale var .


20
Bunun tam olarak bir çözüm sağlamadığının farkındayım: /
Mike Houston

+1 çünkü Apache / PHP bir kuyruklu yıldız çözümünü ölçeklendirmek için iyi seçenekler değildir. PHP kullanıcıları için seçenekler şunlardır: 1) Bahsettiğiniz gibi, ek sunucuların ve proxy'lerin çılgın konfigürasyonları veya 2) bir SaaS çözümü kullanmak ve WebSync On-Demand gibi bir şey aracılığıyla kuyruklu yıldız öğelerini boşaltmak.
jvenema

1
Bu birçok açıdan yanlıştır. Kullanıcı başına bir evre yönteminden ayrılmak isterse, Apache'yi aracı olmaktan çıkararak ve PHP'nin bu istekleri işlemesine izin vererek bu kolaylıkla başarılabilir. Elbette, Apache içerik sunmada daha iyi çalışıyor, bu yüzden bu apache'siz PHP sunucusunu herhangi bir içerik sunmayan bir alt etki alanında çalıştırırdım.
Christian

@MikeHouston IIS'de php ile kuyruklu yıldız denemeye ne dersiniz?
ravi404

@ravz, burada IIS ve kuyruklu yıldız hakkında bazı şeyler var: stackoverflow.com/questions/1898848/comet-programming-in-iis , ancak hızlı cgi PHP modülünün apache ile aynı sınırlamalara sahip olduğundan şüpheleniyorum. Burada tek bir iş parçacığı ortamından bahsediyor: microsoft.com/web/platform/phponwindows.aspx - Windows sunucularını kendim kullanmıyorum, bu yüzden iş parçacığı modelinden emin değilim.
Mike Houston

14

Çok az bellek veya CPU kullanımıyla çok ölçeklenebilir olan Comet tabanlı bir sohbet sistemi uygulamak için Nginx ve JavaScript kullanabilirsiniz.

Başlamanızı sağlayacak çok basit bir örneğim var burada. Nginx'in NHPM modülüyle derlenmesini kapsar ve jQuery, PHP ve Bash'deki basit yayıncı / abone rolleri için kod içerir.

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


10

PHP

Basit bir kuyruklu yıldızı açıklayan bu komik küçük ekran videolarını buldum . Bir yan not olarak, bunun sunucunuzu herhangi bir gerçek yükte öldüreceğini düşünüyorum. Sadece birkaç kullanıcı varken, sadece bu çözüme gitmeyi söyleyebilirim. Bu çözümün uygulanması gerçekten basittir (ekran video kayıtları yalnızca 5 dakikanızı alır :)). Ancak daha önce de söylediğim gibi, eşzamanlı birçok kullanıcı için iyi olduğunu düşünmüyorum (Sanırım bunu karşılaştırmalısınız;)) çünkü:

  1. Hafızadan veri almaktan çok daha yavaş dosya G / Ç kullanır. Örneğin işlevler gibi filemtime(),
  2. İkincisi, ancak PHP'nin iyi bir iş parçacığı modeline sahip olmadığını düşünmüyorum. PHP, hiçbir şey paylaşma modeli nedeniyle bunun için tasarlanmamıştır . Slaytlarda söylendiği gibi "Paylaşılan veriler veri deposu katmanına aktarılır", örneğin MySQL gibi.

Alternatifler

Herhangi bir kuyruklu yıldız / uzun yoklama yapmak istiyorsanız alternatifleri denemeniz gerektiğini düşünüyorum. Örneğin, birçok dili kullanabilirsiniz:

  • Java / JVM: İskele sürekliliği .
  • Python: Dustin'in sesi .
  • Erlang: Kuyruklu yıldız / vb. İçin popüler dil.
  • Lua, Ruby, C, Perl sadece birkaç isim.

Sadece basit bir Google araması yapmak size birçok alternatif gösterecektir.



6

Ayrıca https://github.com/reactphp/react'ı da deneyebilirsiniz.

React, PHP'de olay odaklı programlama için düşük seviyeli bir kitaplıktır. Özünde bir olay döngüsü vardır ve bunun üzerine düşük seviyeli yardımcı programlar sağlar, örneğin: Akış soyutlaması, zaman uyumsuz DNS çözümleyicisi, ağ istemcisi / sunucusu, http istemcisi / sunucusu, işlemlerle etkileşim. Üçüncü taraf kitaplıklar, eşzamansız ağ istemcileri / sunucuları ve daha fazlasını oluşturmak için bu bileşenleri kullanabilir.

Olay döngüsü reaktör modeline (dolayısıyla adı) temel alır ve EventMachine (Ruby), Twisted (Python) ve Node.js (V8) gibi kitaplıklardan büyük ölçüde esinlenmiştir.

Giriş örneği, 1337 numaralı bağlantı noktasını dinleyen basit bir HTTP sunucusunu gösterir:

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

Ben de benzer bir sorun yaşıyorum. İlginç bulduğum bir seçenek, ana mesaj merkezi olarak cometd-java veya cometd-python gibi mevcut bir Comet sunucusunu kullanmaktır. PHP kodunuz bu durumda Comet sunucusunun sadece bir istemcisidir - tıpkı diğer istemciler gibi kanallardan mesaj gönderebilir veya okuyabilir.

Burada bağlantılı ilginç bir kod parçacığı var: http://morglog.org/?p=22=1 bu yöntemin bir bölümünü uygulayan (etrafa yayılmış hata ayıklama kodu parçaları da olsa).


3

Şu anda soket işlevlerini kullanarak ölçeklenebilir bir PHP Comet sunucusu uyguluyorum. Adı 'phet' ([ph] p com [et])

Proje sayfası: http://github.com/Tim-Smart/phet

Geliştirmeye katılmak ücretsiz. Şu anda sunucu mantığının çoğunu halletmeyi başardım, sadece istemci tarafı işlerini bitirmem gerekiyor.

DÜZENLEME: pcntl_forkYöntemi kullanarak yakın zamanda eklenen 'Multi-threading' yetenekleri :)


Bu kitaplığın nasıl kullanılacağına dair halihazırda mevcut örnekler yoktur.
ftrotter

3

PHP'nin doğasında bulunan tek iş parçacıklı bir kuyruklu yıldız olduğundan, kuyrukluyıldızı uygulamakta zorlanacaksınız.

Websync On-Demand'a göz atın - hizmet, PHP'yi sunucu tarafı yayınlama yoluyla entegre etmenize, ağır eşzamanlı bağlantı öğelerini boşaltmanıza olanak tanır ve anında gerçek zamanlı bir sohbet uygulaması oluşturmanıza izin verir.




0

Bence bu daha çok sürekli çalışan çok sayıda apache iş parçacığına sahip olmanın bir sorun olduğunu düşünüyorum. Bu, apache aracılığıyla PHP ile aynı şekilde (genellikle) çalışırsa, herhangi bir dilde mevcut olacaktır.


1
Sanırım asıl mesele, php'yi istek başına bir iş parçacığı yerine genellikle istek başına bir işlemde çalıştırmanızdır.
troelskn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.