Node.js üzerinde eşzamanlı görevler için hangisi daha iyi olur? Lifler? Web işçiler? veya Konular?


111

Bir süre önce node.js üzerinde tökezlemiştim ve çok beğendim. Ancak çok geçmeden CPU-yoğun görevleri yerine getirme yeteneğinden çok yoksun olduğunu anladım. Böylece, googling yapmaya başladım ve sorunu çözmek için şu yanıtları aldım: Fiberler, Web Çalışanları ve İplikler (thread-a-gogo). Şimdi hangisinin kullanılacağı bir kafa karışıklığı ve bunlardan birinin kesinlikle kullanılması gerekiyor - sonuçta IO'da sadece iyi olan ve başka hiçbir şey olmayan bir sunucuya sahip olmanın amacı nedir? Önerilere ihtiyaç var!

GÜNCELLEME:

Gecikmiş bir yol düşünüyordum; sadece önerilere ihtiyacım var. Şimdi, düşündüğüm şey şuydu: Biraz konuya sahip olalım (thread_a_gogo veya belki webworker kullanarak). Şimdi, daha fazlasına ihtiyacımız olduğunda, daha fazlasını yaratabiliriz. Ancak yaratma sürecinde bazı sınırlamalar olacaktır. (sistem tarafından ima edilmemiştir ancak muhtemelen genel giderler nedeniyle). Şimdi, sınırı aştığımızda, yeni bir düğümü çatallayabilir ve onun üzerinde iş parçacıkları oluşturmaya başlayabiliriz. Bu şekilde, bir sınıra ulaşana kadar devam edebilir (sonuçta, işlemlerin de büyük bir yükü vardır). Bu sınıra ulaşıldığında, sıraya alma görevlerine başlarız. Bir iş parçacığı serbest kaldığında, ona yeni bir görev atanacaktır. Bu şekilde sorunsuz devam edebilir.

Ben de öyle düşündüm. Bu fikir iyi mi? Tüm bu süreç ve iş parçacıkları konusunda biraz yeniyim, bu yüzden herhangi bir uzmanlığım yok. Lütfen görüşlerinizi paylaşın.

Teşekkürler. :)


Lütfen dikkat: Çalışanlar bir tarayıcı özelliğidir, bir Javascript özelliği değildir.
FredTheWebGuy

Bunu görüyorum. Sorum node.js hakkındaydı - sunucu kodu ve istemci tarafı ile ilgili değil!
Parth Thakkar

Sadece bir açıklama - Görüyorum ki asıl soru NodeJ'lerdeki Webworkers'la ilgiliydi, ki bu imkansızdır - NodeJs "Threads" kullanıyor. Ancak, NodeJs çalışma zamanı içinde WebWorker sözdizimine izin veren, etrafında dolaşan bir NodeJS modülü vardır.
FredTheWebGuy

Yanıtlar:


331

Düğümün tamamen farklı bir paradigması vardır ve doğru bir şekilde yakalandığında, problem çözmenin bu farklı yolunu görmek daha kolaydır. Bir Node uygulamasında (1) asla birden fazla iş parçacığına ihtiyacınız olmaz çünkü aynı şeyi yapmanın farklı bir yolu vardır. Birden çok işlem oluşturursunuz; ancak, örneğin Apache Web Sunucusunun Prefork mpm'nin yaptığından çok farklıdır.

Şimdilik, sadece bir CPU çekirdeğimiz olduğunu düşünelim ve biraz iş yapmak için bir uygulama (Düğüm yolunda) geliştireceğiz. Bizim işimiz, içeriği bayt bayt üzerinde çalışan büyük bir dosyayı işlemektir. Yazılımımızın en iyi yolu, işe dosyanın başından başlamak, bayt bayt sonuna kadar takip etmektir.

- Hey, Hasan, galiba sen ya çaylaksın ya da büyükbabamın zamanından kalma çok eski bir okulsun !!! Neden bazı konular oluşturup daha hızlı hale getirmiyorsunuz?

- Sadece bir CPU çekirdeğimiz var.

-- Ne olmuş yani? Biraz ip yarat adamım, daha hızlı yap!

- Böyle çalışmıyor. İplikler oluşturursam, daha yavaş yapacağım. Çünkü iş parçacıkları arasında geçiş yapmak, onlara sadece bir süre vermek için sisteme çok fazla ek yük ekleyeceğim ve sürecimin içinde bu iş parçacıkları arasında iletişim kurmaya çalışacağım. Tüm bu gerçeklere ek olarak, tek bir işi paralel olarak yapılabilecek birden fazla parçaya nasıl böleceğimi de düşünmem gerekecek.

- Tamam tamam, fakir olduğunu görüyorum. Bilgisayarımı kullanalım, 32 çekirdeği var!

- Vay canına, harikasın sevgili dostum, çok teşekkür ederim. Bunu takdir ediyorum!

Sonra işe geri dönüyoruz. Zengin dostumuz sayesinde artık 32 cpu çekirdeğimiz var. Uymamız gereken kurallar az önce değişti. Şimdi bize verilen tüm bu serveti kullanmak istiyoruz.

Birden çok çekirdek kullanmak için, çalışmamızı paralel olarak halledebileceğimiz parçalara ayırmanın bir yolunu bulmalıyız. Düğüm olmasaydı, bunun için evreleri kullanırdık; Her cpu çekirdeği için bir tane olmak üzere 32 iş parçacığı. Ancak Node'umuz olduğu için 32 Node süreci oluşturacağız.

İş parçacığı, Düğüm süreçlerine iyi bir alternatif olabilir, hatta daha iyi bir yol olabilir; ancak yalnızca işin zaten tanımlandığı ve işin nasıl yapılacağı konusunda tam kontrole sahip olduğumuz belirli bir işte. Bunun dışında, işin kontrolümüzün olmadığı bir şekilde dışarıdan geldiği ve olabildiğince çabuk cevap vermek istediğimiz her türlü problem için Node'un yolu tartışmasız üstündür.

- Hey, Hasan, hala tek iş parçacığı mı çalışıyorsun? Senin sorunun ne adamım? Sana istediğini verdim. Artık bahanen yok. İş parçacığı oluşturun, daha hızlı çalışmasını sağlayın.

- Çalışmayı parçalara ayırdım ve her süreç bu parçalardan biri üzerinde paralel olarak çalışacak.

- Neden konu oluşturmuyorsunuz?

- Üzgünüm, kullanılabilir olduğunu sanmıyorum. İstersen bilgisayarını alabilir misin?

- Hayır tamam, ben iyiyim, neden ipleri kullanmadığını anlamıyorum?

- Bilgisayar için teşekkürler. :) Çalışmayı zaten parçalara ayırdım ve bu parçalar üzerinde paralel olarak çalışmak için süreçler oluşturuyorum. Tüm CPU çekirdekleri tam olarak kullanılacaktır. Bunu süreçler yerine iş parçacıklarıyla yapabilirim; ancak Node'un yolu bu ve patronum Parth Thakkar benden Node'u kullanmamı istiyor.

- Tamam, başka bir bilgisayara ihtiyacın olursa haber ver. : p

32 yerine 33 işlem oluşturursam, işletim sisteminin zamanlayıcısı bir iş parçacığını duraklatacak, diğerini başlatacak, birkaç döngüden sonra duraklatacak, diğerini yeniden başlatacak ... Bu gereksiz ek yük. Onu istemiyorum. Aslında, 32 çekirdekli bir sistemde, tam olarak 32 işlem oluşturmak bile istemem, 31 daha iyi olabilir . Çünkü bu sistemde çalışacak olan sadece benim uygulamam değil. Diğer şeyler için biraz yer bırakmak iyi olabilir, özellikle de 32 odamız varsa.

İşlemcileri CPU yoğun görevler için tam olarak kullanma konusunda artık aynı sayfada olduğumuza inanıyorum .

- Hmm, Hasan, seninle biraz alay ettiğim için üzgünüm. Şimdi seni daha iyi anladığıma inanıyorum. Yine de açıklamaya ihtiyacım olan bir şey var: Yüzlerce iş parçacığı çalıştırmanın tüm vızıltıları nedir? Her yerde iş parçacığı oluşturmanın çatal işlemlerinden çok daha hızlı ve aptal olduğunu okudum. İş parçacıkları yerine süreçleri çatallıyorsunuz ve Node ile elde edeceğiniz en yüksek değer olduğunu düşünüyorsunuz. O halde Node bu tür işler için uygun değil mi?

- Endişelenme, ben de iyiyim. Herkes böyle şeyler söylüyor, bu yüzden duymaya alışkın olduğumu düşünüyorum.

-- Yani? Düğüm bunun için iyi değil mi?

- Düğüm, iş parçacıkları da iyi olabilse de bunun için mükemmel derecede iyidir. İş parçacığı / süreç oluşturma ek yüküne gelince; çok tekrarladığınız şeylerde her milisaniye önemlidir. Ancak ben sadece 32 işlem oluşturuyorum ve çok az zaman alacak. Sadece bir kez olacak. Hiç fark etmeyecek.

- O halde ne zaman binlerce iş parçacığı oluşturmak istiyorum?

- Asla binlerce iş parçacığı oluşturmak istemezsiniz. Ancak, HTTP isteklerini işleyen bir web sunucusu gibi, dışarıdan gelen işleri yapan bir sistemde; her istek için bir iş parçacığı kullanıyorsanız, çoğu iş parçacığı oluşturursunuz.

- Yine de düğüm farklı mı? Sağ?

-- Evet kesinlikle. Node'un gerçekten parladığı yer burasıdır. Bir iş parçacığı bir işlemden çok daha hafifse, bir işlev çağrısı da bir iş parçacığından çok daha hafiftir. Düğüm, iş parçacığı oluşturmak yerine işlevleri çağırır. Bir web sunucusu örneğinde, gelen her istek bir işlev çağrısına neden olur.

-- Hmm, ilginç; ancak birden fazla iş parçacığı kullanmıyorsanız aynı anda yalnızca bir işlevi çalıştırabilirsiniz. Web sunucusuna aynı anda çok sayıda istek ulaştığında bu nasıl çalışır?

- İşlevlerin nasıl çalıştığı konusunda tamamen haklısınız, ikisi birden paralel değil. Demek istediğim, tek bir işlemde, bir seferde yalnızca bir kod kapsamı çalışıyor. İşletim Sistemi Zamanlayıcı, sürecimizdeki başka bir iş parçacığına değil, başka bir işleme zaman vermek için işlemi duraklatmadığı sürece, bu işlevi durdurmaz ve başka bir işleme geçmez. (2)

- O halde bir süreç bir seferde 2 isteği nasıl işleyebilir?

- Sistemimiz yeterli kaynağa (RAM, Ağ, vb.) Sahip olduğu sürece, bir süreç bir seferde on binlerce isteği işleyebilir. Bu işlevlerin nasıl çalıştığı ANAHTAR FARK.

- Hmm, şimdi heyecanlanmalı mıyım?

- Belki :) Düğüm, kuyruk üzerinde bir döngü çalıştırır. Bu kuyrukta bizim işlerimiz, yani gelen talepleri işlemeye başladığımız aramalar var. Buradaki en önemli nokta, işlevlerimizi çalışacak şekilde tasarlama şeklimizdir. Bir talebi işleme koymaya başlamak ve arayanı işi bitirene kadar bekletmek yerine, kabul edilebilir miktarda iş yaptıktan sonra işlevimizi hızlı bir şekilde sonlandırıyoruz. Başka bir bileşenin biraz iş yapması ve bize bir değer vermesini beklememiz gereken bir noktaya geldiğimizde, bunu beklemek yerine, işin geri kalanını kuyruğa ekleyerek işlevimizi bitiririz.

- Kulağa çok mu karmaşık geliyor?

- Hayır hayır, karmaşık gelebilirim; ancak sistemin kendisi çok basit ve çok mantıklı.

Şimdi, bu iki geliştirici arasındaki diyaloğu alıntı yapmayı bırakmak ve bu işlevlerin nasıl çalıştığına dair son hızlı bir örnekten sonra cevabımı bitirmek istiyorum.

Bu şekilde, OS Scheduler'ın normalde yapacağı şeyi yapıyoruz. Çalışmamızı bir noktada durdururuz ve sıramızı tekrar alana kadar diğer işlev çağrılarının (çok iş parçacıklı bir ortamdaki diğer evreler gibi) çalışmasına izin veririz. Bu, işi sistemdeki her iş parçacığına sadece zaman vermeye çalışan OS Scheduler'a bırakmaktan çok daha iyidir. Neyi yaptığımızı OS Scheduler'ın yaptığından çok daha iyi biliyoruz ve durmamız gerektiğinde durmamız bekleniyor.

Aşağıda, veriler üzerinde biraz çalışma yapmak için bir dosyayı açıp okuduğumuz basit bir örnek verilmiştir.

Senkron Yol:

Open File
Repeat This:    
    Read Some
    Do the work

Eşzamansız Yol:

Open File and Do this when it is ready: // Our function returns
    Repeat this:
        Read Some and when it is ready: // Returns again
            Do some work

Gördüğünüz gibi, fonksiyonumuz sistemden bir dosyayı açmasını istiyor ve açılmasını beklemiyor. Dosya hazır olduktan sonra sonraki adımları sağlayarak kendini tamamlar. Geri döndüğümüzde, Node kuyrukta diğer fonksiyon çağrılarını çalıştırır. Tüm fonksiyonların üzerinden geçtikten sonra, olay döngüsü bir sonraki sıraya geçer ...

Özetle, Node'un çok iş parçacıklı geliştirmeden tamamen farklı bir paradigması vardır; ancak bu, eksik olduğu anlamına gelmez. Eşzamanlı bir iş için (işleme sırasına ve yöntemine karar verebileceğimiz), çok iş parçacıklı paralelliğin yanı sıra çalışır. Sunucuya yapılan istekler gibi dışarıdan gelen bir iş için, basitçe üstündür.


(1) C / C ++ gibi diğer dillerde kitaplıklar oluşturmadığınız sürece, bu durumda işleri bölmek için yine de iş parçacıkları oluşturmazsınız. Bu tür işler için, biri gerçek işi yaparken diğeri Düğüm ile iletişime devam edecek iki iş parçacığına sahipsiniz.

(2) Aslında, her Node işleminin ilk dipnotta bahsettiğim aynı nedenlerle birden fazla iş parçacığı vardır. Ancak bu, benzer işler yapan 1000 iş parçacığına benzemez. Bu ekstra iş parçacıkları, IO olaylarını kabul etmek ve süreçler arası mesajlaşmayı yönetmek gibi şeyler içindir.

GÜNCELLEME (Yorumlarda iyi bir soruya yanıt olarak)

@Mark, yapıcı eleştirileriniz için teşekkür ederim. Düğüm paradigmasında, kuyruktaki diğer tüm çağrılar birbiri ardına çalışacak şekilde tasarlanmadıkça işlenmesi çok uzun süren işlevlere asla sahip olmamalısınız. Hesaplama açısından pahalı görevler söz konusu olduğunda, resme tam olarak bakarsak, bunun "iş parçacıkları veya süreçler kullanmalı mıyız?" Sorusu olmadığını görürüz. ancak "Bu görevleri, sistemde birden fazla CPU çekirdeği kullanarak paralel olarak çalıştırabileceğimiz alt görevlere dengeli bir şekilde nasıl bölebiliriz?" Diyelim ki 8 çekirdekli bir sistemde 400 video dosyası işleyeceğiz. Bir seferde bir dosyayı işlemek istiyorsak, aynı dosyanın farklı kısımlarını işleyecek bir sisteme ihtiyacımız var, bu durumda, belki, çok iş parçacıklı tek işlemli bir sistemin oluşturulması daha kolay ve daha da verimli olacaktır. Durum paylaşımı / iletişimi gerekli olduğunda birden fazla işlem çalıştırarak ve aralarında mesajlar geçirerek bunun için Node'u kullanmaya devam edebiliriz. Daha önce de söylediğim gibi, Node ile çok süreçli bir yaklaşımbu tür görevlerde çok parçalı bir yaklaşımın yanı sıra ; ama bundan daha fazlası değil. Yine, daha önce de söylediğim gibi, Düğümün parladığı durum, bu görevlerin sisteme birden çok kaynaktan girdi olarak gelmesidir, çünkü birçok bağlantıyı aynı anda tutmak, bağlantı başına iş parçacığı veya bağlantı başına işlemle karşılaştırıldığında Düğümde çok daha hafiftir. sistemi.

setTimeout(...,0)Aramalara gelince ; bazen, kuyruktaki çağrıların işlem paylarına sahip olmasına izin vermek için zaman alıcı bir görev sırasında ara vermek gerekebilir. Görevleri farklı şekillerde bölmek sizi bunlardan kurtarabilir; ama yine de, bu gerçekten bir hack değil, sadece olay kuyruklarının çalışma şeklidir. Ayrıca, process.nextTickbu amaç için kullanmak çok daha iyidir, çünkü kullandığınızda setTimeout, geçen zamanın hesaplanması ve kontrol edilmesi gerekli olacaktır, ancak process.nextTickgerçekten istediğimiz şey budur: "Hey görev, sıranın sonuna geri dön, payını kullandın! "


9
İnanılmaz! Harika! Bu soruyu cevaplama şeklini sevdim! :)
Parth Thakkar

48
Elbette :) Bu cevap makalesine oy veren aşırı derecede kötü insanlar olduğuna gerçekten inanamıyorum! Soru soran kişi buna "Lanet Olağanüstü!" Diyor. ve bir kitap yazarı bunu gördükten sonra web sitesinde bana yazmayı teklif ediyor; ama dışarıdaki bazı dahiler bunu reddediyor. Neden acımasızca ve gizlice aşağı oy vermek yerine parlak entelektüel kalitenizi paylaşıp yorum yapmıyorsunuz? Neden güzel bir şey seni bu kadar rahatsız ediyor? Bundan gerçekten yararlanabilecek diğer insanlara ulaşmak için yararlı bir şeyi neden engellemek istiyorsunuz?
hasanyasin

9
Bu tamamen adil bir cevap değil. İşlev çağrımızı "hızlı bir şekilde sona erdiremediğimiz" hesaplama açısından pahalı görevler ne olacak? Bazı insanların bunun için bazı setTimeout(...,0)hackler kullandığına inanıyorum , ancak bu senaryoda ayrı bir iş parçacığı kullanmak kesinlikle daha iyi olur?
mpen

3
@hasanyasin Bu, şimdiye kadar bulduğum düğüm hakkında en güzel açıklama! :)
Venemo

7
@Mark Genel olarak, eğer hesaplama açısından pahalıysa, basamak / süreç çalışanları için seçenekler / modüller vardır ... Genel olarak, bu tür şeyler için, bir Mesaj Kuyruğu kullanıyorum ve bir görevi yerine getiren çalışan süreçlerim var kuyruktan çıkma zamanı ve o görevi çalıştır. Bu aynı zamanda birden çok sunucuya ölçeklendirmeye izin verir. Bu satırlar boyunca Substack, bakabileceğiniz sağlama ve ölçeklendirmeye yönelik birçok modüle sahiptir.
Tracker1

34

(2016 Güncellemesi: Web çalışanları io.js - bir Node.js çatalı Node.js v7 - aşağıya bakın.)

(Güncelleme 2017: Web işçileri vardır değil - Aşağıda bkz node.js v7 veya v8 girmeden.)

(Güncelleme 2018: Web işçileri vardır - Aşağıda bkz node.js Düğüm v10.5.0 girecek.)

Bazı açıklamalar

Yukarıdaki cevapları okuduktan sonra, web çalışanlarında genel olarak JavaScript felsefesine ve özellikle eşzamanlılıkla ilgili olarak Node felsefesine aykırı hiçbir şey olmadığını belirtmek isterim. (Olsaydı, tarayıcılarda çok daha az uygulanan WHATWG tarafından tartışılmazdı bile).

Bir web çalışanını, zaman uyumsuz olarak erişilen hafif bir mikro hizmet olarak düşünebilirsiniz. Hiçbir eyalet paylaşılmaz. Kilitlenme sorunu yoktur. Engelleme yok. Senkronizasyona gerek yoktur. Tıpkı Düğüm programınızdan bir RESTful hizmeti kullandığınızda olduğu gibi, artık "çok iş parçacıklı" olduğundan endişelenmeyin çünkü RESTful hizmeti kendi olay döngünüzle aynı iş parçacığı içinde değildir. Eşzamansız olarak eriştiğiniz ayrı bir hizmettir ve önemli olan budur.

Aynı şey web çalışanları için de geçerlidir. Tamamen ayrı bir bağlamda çalışan kodla iletişim kurmak için sadece bir API'dir ve farklı iş parçacığı, farklı süreç, farklı cgroup, bölge, kapsayıcı veya farklı bir makinede olup olmadığı tamamen eşzamansız, engellemeyen bir API nedeniyle tamamen alakasızdır. değere göre iletilen tüm verilerle.

Aslına bakılırsa web işçileri kavramsal olarak Node için mükemmel bir seçimdir ve çoğu insanın farkında olmadığı gibi tesadüfen çok yoğun bir şekilde iş parçacıkları kullanır ve aslında "kodunuz dışında her şey paralel çalışır" - bkz:

Ancak web çalışanlarının iş parçacıkları kullanılarak uygulanmasına bile gerek yoktur. Web çalışanı API'si kullanıldığı sürece, buluttaki süreçleri, yeşil konuları ve hatta RESTful hizmetlerini kullanabilirsiniz. API'yi değere göre çağrı ile geçirmenin tüm güzelliği, eşzamanlılık modelinin ayrıntıları açığa çıkmayacağından, temeldeki uygulamanın hemen hemen alakasız olmasıdır.

Tek iş parçacıklı bir olay döngüsü, G / Ç bağlantılı işlemler için mükemmeldir. CPU'ya bağlı işlemler, özellikle uzun süre çalışan işlemler için o kadar iyi çalışmaz. Bunun için daha fazla süreç üretmemiz veya iş parçacığı kullanmamız gerekiyor. Alt süreçleri ve süreçler arası iletişimi taşınabilir bir şekilde yönetmek oldukça zor olabilir ve genellikle basit görevler için bir aşırılık olarak görülürken, iş parçacığı kullanmak, doğru yapılması çok zor olan kilitler ve senkronizasyon sorunları ile uğraşmak anlamına gelir.

Genellikle önerilen şey, uzun süre çalışan CPU'ya bağlı işlemleri daha küçük görevlere bölmektir ( Speed ​​up setInterval'a cevabımın "Orijinal yanıt" bölümündeki örnek gibi ), ancak her zaman pratik değildir ve daha fazlasını kullanmaz birden fazla CPU çekirdeği.

Temelde web çalışanlarının sunucular için değil tarayıcılar için yaratıldığını söyleyen yorumları açıklığa kavuşturmak için yazıyorum (JavaScript'teki hemen hemen her şey hakkında söylenebileceğini unutarak).

Düğüm modülleri

Düğüme Web Çalışanları eklemesi gereken birkaç modül vardır:

Bunlardan hiçbirini kullanmadım ancak alakalı olabilecek iki hızlı gözlemim var: Mart 2015 itibariyle, node-webworker en son 4 yıl önce güncellendi ve node-webworker-thread'leri en son bir ay önce güncellendi. Ayrıca düğüm-webworker-thread kullanımı örneğinde, Worker kurucusuna bir argüman olarak dosya adı yerine bir fonksiyon kullanabileceğinizi görüyorum; bu, hafızayı paylaşan evreler kullanılarak uygulanırsa ince sorunlara neden olabilir ( işlevler yalnızca .toString () yöntemi için kullanılır ve aksi takdirde farklı bir ortamda derlenir, bu durumda iyi olabilir - sadece gözlemlerimi burada paylaşarak ona daha derinlemesine bakmam gerekiyor).

Düğümde web işçileri API'sini uygulayan başka bir ilgili proje varsa, lütfen bir yorum bırakın.

Güncelleme 1

Henüz yazarken bilmiyordum ama tesadüfen bu cevabı yazmadan bir gün önce Web Çalışanları io.js'ye eklendi .

( io.js , Node.js'nin bir çatalı - bakınız: io.js neden daha fazla bilgi için Mikeal Rogers ile InfoWorld röportajı olan Node.js'yi çatallamaya karar verdi .)

Yalnızca web çalışanlarında genel olarak JavaScript felsefesine ve özellikle eşzamanlılıkla ilgili olarak Node felsefesine aykırı hiçbir şeyin olmadığını kanıtlamakla kalmaz, aynı zamanda web çalışanlarının io gibi sunucu tarafı JavaScript'te birinci sınıf vatandaş olmasına neden olabilir. js (ve muhtemelen gelecekte Node.js), tıpkı tüm modern tarayıcılarda istemci tarafı JavaScript'te olduğu gibi .

Güncelleme 2

Güncelleme 1 ve de benim tweet ben atıfta bulundu io.js çekme isteği # 1159 şimdi yönlendirir Düğüm PR # 1159 ile 8 Tem kapatıldı ve yerine # 2133 Düğüm PR hala açık -. Bu çekme taleplerinin altında, io.js / Node.js'deki Web çalışanlarının durumu hakkında daha güncel bilgiler sağlayabilecek bazı tartışmalar var.

Güncelleme 3

En son bilgiler - NiCk Newman'a yorumlarda yayınladığı için teşekkürler: İşçiler var: Petka Antonov tarafından 6 Eylül 2015'ten itibaren indirilebilen ve bu ağaçta denenebilen ilk uygulama taahhüdü . Ayrıntılar için NiCk Newman tarafından yapılan yorumlara bakın .

Güncelleme 4

İtibariyle Mayıs 2016 halen açık olan PR # 2133 hakkındaki son yorumlar - işçiler: ilk uygulama 3 aylıktı. 30 Mayıs'ta Matheus Moreira, aşağıdaki yorumlarda bu cevaba bir güncelleme göndermemi istedi ve PR yorumlarında bu özelliğin mevcut durumunu sordu .

Halkla ilişkiler tartışmasındaki ilk cevaplar şüpheliydi, ancak daha sonra Ben Noordhuis , "Bunu bir şekilde veya başka bir şekilde birleştirmek v7 için yapılacaklar listemde var" diye yazdı .

Diğer tüm yorumlar ikinci sırada görünüyordu ve Temmuz 2016 itibarıyla Web Çalışanları , Ekim 2016'da piyasaya sürülmesi planlanan bir sonraki Node sürüm 7.0'da (bu tam PR biçiminde olması gerekmiyor) mevcut olacak gibi görünüyor.

Yorumlarda bunu vurguladığı ve GitHub'daki tartışmayı yeniden canlandırdığı için Matheus Moreira'e teşekkürler.

Güncelleme 5

Temmuz 2016 itibarıyla npm'de daha önce mevcut olmayan birkaç modül var - ilgili modüllerin tam listesi için arama yapın çalışanlar, web çalışanları için npm'de vb. Sizin için özellikle herhangi bir şey işe yarıyorsa veya çalışmıyorsa, lütfen bir yorum Yap.

Güncelleme 6

İtibariyle Ocak 2017 web çalışanlarının Node.js ile birleştirilmesi pek olası değildir.

Çekme talebi # 2133 işçi: Petka Antonov tarafından 8 Temmuz 2015'ten itibaren ilk uygulama nihayet kapatıldı 11 Aralık 2016'da Ben Noordhuis tarafından ve "çoklu iş parçacığı desteğinin yetersiz fayda için çok fazla yeni hata modu eklediğini" ve "biz paylaşımlı bellek ve daha verimli serileştirme gibi daha geleneksel araçları kullanarak bunu da başarabilir. "

Daha fazla bilgi için GitHub'daki PR 2133 yorumlarına bakın .

Yorumlarda bunu işaret ettiği için Matheus Moreira'ya tekrar teşekkürler.

Güncelleme 6

Birkaç gün önce, Haziran 2018'de web çalışanlarının Node v10.5.0'da --experimental-workerbayrakla etkinleştirilen deneysel bir özellik olarak göründüğünü duyurmaktan mutluluk duyuyorum .

Daha fazla bilgi için bkz .:

🎉🎉🎉 Nihayet! 3 yıllık Stack Overflow cevabımın 7. güncellemesini yapabilirim, burada bir la web işçisine iş parçacığı eklemenin Node felsefesine aykırı olmadığını, sadece bu sefer sonunda anladığımızı söyleyerek! 😜👍


1
@NiCkNewman Teşekkürler. İo.js'deki orijinal çekme isteğinin şimdi kapatıldığını ve bir başkasıyla değiştirildiğini görüyorum - orada, GitHub'daki çekme isteklerinde bazı tartışmalarla, belki orada biraz bilgi bulabilirsin. Bakınız: Cevabımda 2. Güncelleme.
rsp

1
Evet, görünen o ki son libuv sorununu çözmüşler. Modüle ne zaman ulaşabileceğimi merak ediyorum. Bekleyememek! Bizi güncel tuttuğunuz için teşekkürler ~ Düzenleme: Yeni başlatıldı: github.com/petkaantonov/io.js/commit/… İşte başlıyoruz, geliyor!
NiCk Newman

1
Evet, canlı. (Henüz resmi olarak uygulanmadı) ancak kaynağı buradan indirebilirsiniz: github.com/petkaantonov/io.js/tree/… ve test etmek istiyorsanız derleyin! Şimdi yapıyorum ~
NiCk Newman

1
@NiCkNewman Yeni bilgi için teşekkürler - cevaba ekledim.
rsp

1
Node.js workersuygulamasının durumu hakkında bizi bilgilendirebilir misiniz? PR # 2133'teki son yorumlar Şubat ayına aittir ; geliştiriciler görünüşe göre bir sorunla karşılaştı ve çözüldüğüne dair herhangi bir yorum yok.
Matheus Moreira

8

Yazılımı hızlı yapmak için çoklu iş parçacığı kullandığımız eski düşünce tarzından geliyorum. Son 3 yıldır Node.js kullanıyorum ve bunun büyük bir destekçisi. Hasanyasin, düğümün nasıl çalıştığını ve eşzamansız işlevsellik kavramını ayrıntılı olarak açıkladı. Ama buraya birkaç şey eklememe izin verin.

Eski günlerde, tek çekirdekli ve daha düşük saat hızlarında, yazılımların hızlı ve paralel çalışmasını sağlamak için çeşitli yollar denedik. DOS günlerinde her seferinde bir program çalıştırmak için kullanırız. Windows'ta birden çok uygulamayı (işlemi) birlikte çalıştırmaya başladık. Önleyici ve önleyici olmayan (veya işbirlikçi) gibi kavramlar test edildiğinde. Artık tek çekirdekli bilgisayarlarda daha iyi çoklu işlem görevinin cevabının önleyici olduğunu biliyoruz. Birlikte süreçler / görevler ve bağlam değiştirme kavramları geldi. İşlem bağlamı değiştirme yükünü daha da azaltmak için iş parçacığı kavramından daha fazlası. Yeni süreçler üretmeye hafif bir alternatif olarak üretilen iplik.

Beğenin ya da değil, çok çekirdekli ya da tek çekirdekli değil, süreçleriniz işletim sistemi tarafından önceden kesilecek ve zaman dilimlerine ayrılacaktır.

Nodejs tek bir süreçtir ve asenkron mekanizma sağlar. Burada görevler, biz görevin bitmesini bir olay döngüsünde beklerken, görevleri gerçekleştirmek için yatan işletim sistemine gönderilir. İşletim sisteminden yeşil bir sinyal aldığımızda, yapmamız gereken her şeyi yaparız. Şimdi bu bir bakıma işbirlikçi / önleyici olmayan çoklu görevdir, bu nedenle olay döngüsünü çok uzun bir süre boyunca engellememeliyiz, aksi takdirde uygulamamızı çok hızlı bozarız.
Dolayısıyla, doğası gereği engelleyen veya çok zaman alan bir görev varsa, onu OS ve iş parçacıklarının önleyici dünyasına yaymamız gerekecek. libuv belgelerinde bunun için iyi örnekler var . Ayrıca belgeleri daha fazla okursanız, FileI / O'nun node.js'deki iş parçacıklarında işlendiğini görürsünüz .

Öncelikle hepsi yazılımımızın tasarımında. İkincisi, size ne söylerlerse söylesinler, Bağlam değiştirme her zaman oluyor. İş parçacığı orada ve bir nedenden ötürü hala orada, nedeni, süreçler arasında geçiş yapmanın daha hızlı olması.

Node.js'de başlık altında tüm c ++ ve iş parçacıkları var. Ve düğüm, işlevselliğini genişletmek ve zorunlu oldukları yerlerde, yani bir kaynaktan bir kaynağa okuma, büyük veri analizi vb. Gibi görevleri engelleyerek daha da hızlandırmak için c ++ yolu sağlar.

Hasanyasin cevabının kabul edildiğini biliyorum, ancak benim için konular var olacak, ne söylerseniz söyleyin ya da onları komut dosyalarının arkasına nasıl gizlerseniz saklayın, ikincisi, hiç kimse sadece hız için bir şeyleri iplere ayırmaz, çoğunlukla görevleri engellemek için yapılır. Ve iş parçacıkları Node.js'nin arka kemiğindedir, bu nedenle çoklu iş parçacığını tamamen sıkıştırmadan önce doğrudur. Ayrıca iş parçacıkları işlemlerden farklıdır ve çekirdek başına düğüm işlemlerine sahip olma sınırlaması iş parçacığı sayısına tam olarak uygulanmaz, iş parçacıkları bir işlemin alt görevleri gibidir. aslında evreler Windows görev yöneticinizde veya linux top komutunda görünmez. bir kez daha, işlemden sonra daha az ağırlıktadırlar


Eşzamansız kod çok büyük bir yenilik değildir (aslında bunu onlarca yıldır kullanıyoruz) ve çoklu okuma, değiştirilecek kullanımdan kaldırılmış bir teknoloji değildir. Farklı değiş tokuşlara sahip farklı araçlardır ve aslında oldukça iyi bir şekilde birleştirilebilirler. Düğüm kümesini her çalıştırdığınızda, aslında birden çok "iş parçacığı" çalıştırırsınız (bu durumda işlemler, ancak aynı şey iş parçacıklarıyla da elde edilebilir ve daha da hafif olabilir). Veya binlerce yeşil ipliği çalıştırabilen Erlang veya Go'yu ele alın ...
Hejazzman

Bence kaçırdığımız en önemli nokta, OS altındaki sürecin her zaman adaleti sağlamak için önleyici bir şekilde yapılacağıdır. Ayrıca çoklu işlemcilerle gerçek paralel kod yürütme yapabilirsiniz, ancak o zaman bile önleme hakkınız olacaktır. Asenkron çalışma, bir sürecin bazılarında işletim sistemi tarafından da gerçekleştirilir.
limplash

4

Node.js sunucu üzerinde çalışırken web çalışanlarının bu durumda alakalı olup olmadıklarından emin değilim, onlar istemci tarafı teknolojidir (tarayıcıda çalışır). Anladığım kadarıyla fiberler de engelliyorlar, yani gönüllü çoklu görevler, bu yüzden onları kullanabilirsiniz, ancak bağlam anahtarlarını kendiniz yönetmelisiniz yield. İplikler aslında ihtiyacınız olan şey olabilir, ancak node.js'de ne kadar olgun olduklarını bilmiyorum.


3
sadece bilginiz için, web çalışanları node.js'ye (kısmen) uyarlandı. Ve node-workerspaket olarak mevcuttur . Şuna bir göz atın: github.com/cramforce/node-worker
Parth Thakkar

Bilmekte fayda var, teşekkürler. Dokümanlar çok az olsa da, ayrı bir iş parçacığında mı, işlemde mi yoksa yalnızca aynı süreçte mi çalıştığına dair hiçbir fikrim yok ve kodu derinlemesine incelemek için zamanım yok, bu yüzden işe yarayıp yaramayacağı hakkında hiçbir fikrim yok davanız için çalışın.
lanzz

@ParthThakkar: Bu projeye 3 yıldır dokunulmadı (gönderi paylaştığınızda 2) ve 0.0.1'i geçmedi.
mpen

@Mark: Bu konudaki cehaletimin sebebi henüz profesyonel bir programcı olmamam. Heck, ben üniversitede bile değilim. Ben hala okul çalışmalarını yönetmenin yanı sıra programlama hakkında okumaya devam eden bir Lise arkadaşıyım. Bu nedenle, tüm bu konular hakkında bilgi sahibi olmam uzaktan mümkün değil. Az önce bildiklerimi gönderdim ...
Parth Thakkar

@Mark: Yine de projenin tarihi hakkında bunu belirtmen çok hoş oldu. Gelecekteki cevaplarımda bu tür şeyler halledilecektir !! :)
Parth Thakkar

3

worker_threadsbir bayrak arkasında uygulandı ve gönderildi node@10.5.0. Hala bir ilk uygulama ve gelecekteki sürümlerde daha verimli hale getirmek için daha fazla çaba gerekiyor. En son denemeye değer node.


2

Pek çok Node geliştiricisinin görüşüne göre Node'un en iyi kısımlarından biri aslında tek iş parçacıklı doğasıdır. İleti dizileri, Node'un engellemeyen GÇ'den başka hiçbir şey yapmadan tamamen kaçındığı paylaşılan kaynaklarla bir dizi zorluk çıkarır.

Bu, Düğümün tek bir iş parçacığı ile sınırlı olduğu anlamına gelmez . Sadece iş parçacıklı eşzamanlılık elde etme yöntemi aradığınızdan farklıdır. İş parçacıklarıyla başa çıkmanın standart yolu küme kullanmaktır , Node'un kendisiyle birlikte standart olarak gelen modülünü kullanmaktır. Kodunuzda el ile işlem yapmaktan daha basit bir yaklaşımdır.

Kodunuzda eşzamansız programlama ile uğraşmak için (olduğu gibi, yuvalanmış geri arama piramitlerinden kaçınmak), Fibers kitaplığındaki [Gelecek] bileşeni iyi bir seçimdir. Asyncblock'a da göz atmanızı öneririmFibers tabanlı da . Lifler iyidir çünkü yığını çoğaltarak geri aramayı gizlemenize ve ardından gerektiğinde tek bir iş parçacığındaki yığınlar arasında atlamanıza izin verir. Size faydalar sağlarken gerçek iş parçacığı zahmetinden kurtarır. Olumsuz yanı, Fibers kullanırken yığın izlerinin biraz tuhaf olabilmesidir, ancak bunlar çok da kötü değildir.

Eşzamansız şeyler hakkında endişelenmenize gerek yoksa ve engellemeden çok fazla işlem yapmakla daha çok ilgileniyorsanız, işlem için basit bir çağrı.nextTick (geri arama) arada bir ihtiyacınız olan tek şeydir.


Pekala, sizin öneriniz - kümeler hakkında - başlangıçta düşündüğüm şeydi. Ancak bununla ilgili sorun, genel giderleridir - her yeni süreç çatallandığında (~ 30ms, 10MB) yeni bir v8 örneğinin başlatılması gerekir. Yani, çoğunu yaratamazsınız. Bu, doğrudan düğüm belgelerinden alınır: Bu çocuk Düğümler (child_processes hakkında) hala V8'in tamamen yeni örnekleridir. Her yeni Düğüm için en az 30ms başlangıç ​​ve 10mb bellek olduğunu varsayın. Yani onlardan binlercesini yaratamazsınız.
Parth Thakkar

1
Bu tam olarak küme fikridir. CPU çekirdeği başına bir işçi çalıştırırsınız. Daha fazlası büyük olasılıkla gereksizdir. Yoğun işlemci gerektiren görevler bile zaman uyumsuz bir stille sorunsuz çalışacaktır. Ancak, gerçekten tam gelişmiş iş parçacıklarına ihtiyacınız varsa, muhtemelen tamamen başka bir sunucu arka ucuna geçmeyi düşünmelisiniz.
genericdave

1

Belki hangi görevleri yerine getirdiğiniz hakkında biraz daha bilgi yardımcı olabilir. Neden (jenerik dave'nin cevabına yorumunuzda belirttiğiniz gibi) binlerce tane oluşturmanız gerekiyor? Node'da bu tür şeyleri yapmanın olağan yolu, her zaman çalışan ve mesajlar kullanılarak iletilebilen bir çalışan süreci (fork veya başka bir yöntemi kullanarak) başlatmaktır. Başka bir deyişle, yaptığınız görevi her yerine getirmeniz gerektiğinde yeni bir işçi çalıştırmayın, zaten çalışan işçiye bir mesaj gönderin ve bittiğinde bir yanıt alın. Dürüst olmak gerekirse, binlerce gerçek iş parçacığı başlatmanın da çok verimli olacağını göremiyorum , hala CPU'larınız tarafından sınırlandırılıyorsunuz.

Şimdi, tüm bunları söyledikten sonra, son zamanlarda Hook.io ile çok iş yapıyorum , bu türden yükleme görevlerinin diğer süreçlere yüklenmesi için çok iyi çalışıyor gibi görünüyor, belki de ihtiyacınız olanı başarabilir.

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.