Node.js neden tek iş parçacıklı? [kapalı]


256

PHP (veya Java / ASP.NET / Ruby) tabanlı web sunucularında her istemci isteği yeni bir iş parçacığında başlatılır. Ancak Node.js'de tüm istemciler aynı iş parçacığında çalışır (hatta aynı değişkenleri paylaşabilirler!) Ana iş parçacığı döngüsünü engellemeyen G / Ç işlemlerinin olay tabanlı olduğunu anlıyorum.

Anlamadığım şey, Düğüm yazarı neden tek iş parçacıklı olmasını seçti? İşleri zorlaştırıyor. Örneğin, ana iş parçasını engellediğinden (ve yeni istemci istekleri engellendiğinden) CPU yoğun bir işlevi çalıştıramıyorum, bu yüzden bir işlem oluşturmam gerekiyor (bu da ayrı bir JavaScript dosyası oluşturup başka bir düğüm işlemi yürütmem gerektiği anlamına geliyor) o). Ancak, PHP cpu yoğun görevler her istemcinin farklı bir iş parçacığında olduğu için diğer istemcileri engellemeyin. Çok iş parçacıklı web sunucularına kıyasla avantajları nelerdir?

Not: Bunu aşmak için kümelemeyi kullandım, ama bu hoş değil.


12
Kısa süre önce Düğüm'ün arkasındaki teoriyi açıklayan iyi bir video izledim (29 dakika). Ben bile adam CPU yoğun görevler ve kısaca bunları nasıl ele alacağını düşünüyorum: youtube.com/watch?v=L0pjVcIsU6A
whirlwin

24
Bunu biliyor olabilirsiniz, ancak net olmak gerekirse Node.js tek iş parçacıklı değildir. JavaScript kodunuz tek iş parçacıklı çalışır, ancak IO işlemleri ve eklentilerin iş parçacığı havuzunda bitebileceği diğer şeyler. Node.js, çok iş parçacıklı kodla uğraşmak zorunda kalmadan çok iş parçacıklı olmanın avantajını sağlar. Ayrıca, Node.js katkıda bulunanlar JavaScript'in tek iş parçacıklı yapısını seçmediler, JavaScript yazarları bunu yaptı. JS'nin çok iş parçacıklı bir bağlamda çalışabileceği bir yol düşünemiyorum, ancak olsa bile, V8 Node.js'nin JavaScript motoru olarak kullandığı şekilde yazılmıyor.
Brad

5
PHP, JavaScript'ten daha çok iş parçacıklıdır. Muhtemelen FastCGI veya mod_php gibi sunucu modüllerini düşünüyorsunuz. Aslında, Node.js'yi PHP, Java veya Ruby ile değil, Apache, Nginx veya IIS ile karşılaştırıyorsunuz.
Álvaro González

34
Düğüm tek iş parçacıklı değil. Bu popüler bir yanlış anlama. Basit bile sistemimde beş iş parçacığınode -e 'setTimeout(()=>{},1000);' & ps -T h $! | wc -l; kill $! görüntüler . Ana olay döngüsü tek iş parçacıklıdır (olmasaydı pek mantıklı olmaz), ancak Düğüm çok iş parçacıklıdır ve isterseniz çok iş parçacıklı tek işlem uygulamaları yazabilirsiniz. Bu konuda kapsamlı bir cevap yazmak isterim, ancak bazı insanlar sorunuzu kapatmaya karar verdiler, bu yüzden yapamam. Tekrar açmak için oy kullanıyorum. Daha fazla oy alır ve tekrar açılırsa lütfen yorumda bana bahset.
rsp

2
@ rsp Yorumunuz için teşekkürler, ancak ana iş parçacığı i / o ilgili değil demek istedim. bir şey yapan bir büyük for döngüsü gibi bir şey cpu yapıyorsanız, sunucu bağlantıları işlemeyi durdurur. yani, sunucu o anda kullanılamaz. bu nedenle, çoğu sunucunun yaptığı gibi her bağlantıyı doğal olarak işlemek yerine, bu kadar basit bir şey yapmak için kümeler gibi kesmek kullanıyoruz. jxcore.com bunu ele almaya çalıştı, ancak daha sonra benim için kullanılamaz hale getiren özel / değiştirilmiş düğüm eklentilerini kullanıyor.
foreyez

Yanıtlar:


292

Node.js, zaman uyumsuz işlemede açıkça bir deneme olarak oluşturuldu. Teori, tek bir iş parçacığı üzerinde zaman uyumsuz işlem yapmanın, tipik web yükleri altında, tipik iş parçacığı tabanlı uygulamadan daha fazla performans ve ölçeklenebilirlik sağlayabileceğiydi.

Ve biliyor musun? Bence bu teori ortaya çıktı. CPU yoğunluklu şeyler yapmayan bir node.js uygulaması, Apache veya IIS veya diğer iş parçacığı tabanlı sunuculardan binlerce eşzamanlı bağlantı çalıştırabilir.

Tek dişli, asenkron doğa işleri karmaşık hale getirir. Ama dürüstçe bunun diş çekmekten daha karmaşık olduğunu düşünüyor musunuz? Bir yarış koşulu tüm ayınızı mahvedebilir! Ya da bir yerdeki bazı ayarlardan dolayı iş parçacığı havuzunuzu boşaltın ve yanıt sürenizi yavaş yavaş izleyin! Kilitlenmelerden, öncelikli ters çevirmelerden ve çoklu iş parçacığıyla giden diğer tüm devirlerden bahsetmiyorum bile.

Sonunda, evrensel olarak daha iyi veya daha kötü olduğunu düşünmüyorum; farklı ve bazen daha iyi, bazen de değil. İş için doğru aracı kullanın.


26
Ancak web sunucuları genellikle SADECE veritabanı getirme cpu yoğun şeyler ALOT yapar. Getirdiğimiz şeyi işlememiz ve müşteriye sunmadan önce çok fazla iş mantığı yapmamız gerekiyor.
foreyez

22
Yani sadece işçileri yumurtla! Node.js ile olan anlaşma budur. Ağır şeyler başka bir işlemde çalışabilir ve bunun hafif bir geri arama ile sonuçlandığını işlersiniz.
MaiaVictor

7
Sorun, işçi başına çalışan bir os seviyesi işlem olmasıdır .. "ps" komutunu kullanarak onları göreceksiniz. Böylece bu, potansiyel olarak makinede aynı anda çalışan binlerce işlem anlamına gelir - bu delilik!
foreyez

9
@foreyez, Kullanıcı başına bir işleme ihtiyacınız yoktur. Yükü nasıl böleceğiniz konusunda seçim yapabilirsiniz. Ayrıca, herkes yoğun bir CPU yoğunluğu yapmıyor. Düğüm bir iş için bir araçtır ... belki sizin işiniz değil, birçok iş türü.
Brad

15
Aslında, @foreyez "web sunucuları genellikle cpu yoğun şeyler ALOT (sic) için" bu ifadeyi yedeklemek istiyorum. Benim tecrübelerime göre, değiller. Ya da belki 'yoğun cpu' tanımım ondan farklıdır. Ürün verilerini bir kullanıcı arayüzüne dönüştürmek CPU yoğun değildir ve siparişleri veya benzerini hesaplamaz. Web'in çoğu oldukça işlemsel. CPU yoğun şeyler videoları dönüştürmek, görüntü formatlarını dönüştürmek vb. Ve dönüştürmeye adanmış başka bir sürece aktarmayı kolaylaştırır.
Paul

63

Bir sunucu için "istek başına bir iş parçacığı" modelindeki sorun, olay döngüsü iş parçacığı modeline kıyasla çeşitli senaryolar için iyi ölçeklenmemesidir.

Tipik olarak, G / Ç yoğun senaryolarında talepler çoğu zaman G / Ç'nin tamamlanmasını bekleyerek geçirir. Bu süre zarfında, "istek başına bir iş parçacığı" modelinde, iş parçacığına (bellek gibi) bağlı kaynaklar kullanılmaz ve bellek sınırlayıcı faktördür. Olay döngüsü modelinde, döngü iş parçacığı işlemek için bir sonraki olayı (G / Ç tamamlandı) seçer. Bu yüzden iş parçacığı her zaman meşgul (tabii ki doğru programlarsanız).

Olay döngüsü modeli, tüm yeni şeyler parlak gibi görünüyor ve tüm sorunların çözümü, ancak hangi modelin kullanılması, ele almanız gereken senaryoya bağlı olacaktır. Yoğun bir G / Ç senaryosunuz varsa (proxy gibi), olay tabanı modeli kural verirken, aynı anda çok sayıda eşzamanlı işlem içeren CPU yoğun senaryosu en iyi iş parçacığı tabanlı modelle çalışır.

Gerçek dünyada senaryoların çoğu ortada olacak. Doğru mimariyi bulmak için gerçek ölçeklenebilirlik ihtiyacını geliştirme karmaşıklığıyla dengelemeniz gerekir (örneğin, CPU yoğun görevlerin arka ucuna delege olan bir olay tabanı ön ucuna sahip olun. Ön uç, görevi bekleyen çok az kaynak kullanacaktır Herhangi bir dağıtılmış sistemde olduğu gibi, sistemin çalışması için biraz çaba gerektirir.

Herhangi bir çaba olmadan herhangi bir senaryoya uyacak gümüş mermi arıyorsanız, ayağınızda bir mermi ile sonuçlanacaksınız.


8
Node.js, v8 çoklu kullanım desteğinin olmaması nedeniyle yalnızca olay işleme ile sınırlıdır. Javascript dilinin kendisi gerekli özelliklerden yoksundur, bu nedenle herhangi bir uygulama zor olacaktır. Bence Node.js'nin asıl suçlusu. Diğer dillerde ne istediğinizi seçebilirsiniz. Ya da java NIO gibi her iki modelden de melez.
FrameGrace

2
@Kazaag Modern web sunucuları yapmak bir ThreadPool'da korumak. Sayfa yükü başına sadece yeni bir iş parçacığı oluşturmazlar. Bunlar eski web sunucuları.
Pacerier

1
@Pacerier Yeni bir iş parçacığının doğduğunu söylemedim, ancak istek tamamlanıncaya kadar her iş parçacığı bir isteğe ayrıldı.
Kazaag

2
@Kazaag Kesinlikle genel bir kural değildir, "her iş parçacığı, istek tamamlanıncaya kadar bir istek için ayrılır". Net (HTTP isteklerini işlemek dahil) async (Görev tabanlı) programlamayı kullanabilir ve kullanmalıdır ve bu, G / Ç ve diğer asenkron işlemlerin tamamlanmasını beklerken iş parçacıklarını serbest bırakır. Bu, MVC / API denetleyicileri gibi üst düzey programlama için de geçerlidir. Yani pratikte bekleyen 20 HTTP isteği olabilir, ancak sadece bir aktif iş parçacığı olabilir.
user3285954

29

Uzun lafın kısası, düğüm içten tek dişli olan V8'den geliyor. CPU yoğunluklu görevler için kısıtlamalar üzerinde çalışmanın yolları vardır.

Bir noktada (0.7) yazarlar, çok sayıda hesaplama iş parçacığını uygulamanın bir yolu olarak izolatları tanıtmaya çalıştı, ancak sonuçta kaldırıldı: https://groups.google.com/forum/#!msg/nodejs/zLzuo292hX0/F7gqfUiKi2sJ


Bu "izolat" hakkında daha fazla bilginiz var mı?
Pacerier
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.