Rakan yang menggunakan nodej semua tahu bahawa nod adalah satu-benang, yang bermaksud bahawa ia berjalan pada CPU 8 teras dan hanya boleh menggunakan kuasa pengkomputeran satu teras.
Benang tunggal sentiasa menjadi kritikan terhadap nod, tetapi dengan pengenalan kluster dalam versi 0.6, keadaan ini telah berubah Pembangun boleh bergantung pada kluster untuk mengembangkan pelayan Nod mereka dengan mudah menjadi pelayan berbilang benang.
Apakah Kluster
Kluster ialah pustaka berbilang benang yang disediakan oleh nod Pengguna boleh menggunakannya untuk membuat berbilang rangkaian . Oleh kerana setiap utas nod mengambil berpuluh-puluh megabait memori, anda tidak boleh membuat utas untuk setiap permintaan seperti yang dilakukan oleh PHP Secara umumnya, bilangan utas yang dibuat tidak akan melebihi bilangan teras CPU paling banyak.
jika (cluster.isMaster) {
// Pekerja garpu.
untuk (var i = 0; i < numCPUs; i ) {
cluster.fork();
}
cluster.on('keluar', fungsi(pekerja, kod, isyarat) {
console.log('pekerja ' pekerja.proses.pid ' meninggal dunia');
});
} lain {
// Pekerja boleh berkongsi sebarang sambungan TCP
// Dalam kes ini ia adalah pelayan HTTP
http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello worldn");
}).dengar(8000);
}
Seperti yang ditunjukkan dalam kod di atas, cluster.isMaster akan ditetapkan kepada benar apabila program sedang berjalan Selepas memanggil cluster.fork(), program akan mencipta benang dan menjalankannya semula akan ditetapkan kepada palsu. Kami terutamanya menggunakan pembolehubah ini untuk menentukan sama ada utas semasa ialah utas kanak-kanak.
Anda juga dapat melihat bahawa selepas setiap utas kanak-kanak dicipta, ia akan mendengar port 8000 tanpa menyebabkan konflik Ini adalah fungsi port kongsi kluster.
Komunikasi antara utas
Apabila benang dibuat, ia tidak berkongsi memori atau data antara satu sama lain. Semua pertukaran data hanya boleh diproses dalam utas utama melalui worker.send dan worker.on('message', handler) Berikut ialah contoh sistem penyiaran.
jika (cluster.isMaster) {
var pekerja=[];
//Buat pekerja baharu
fungsi newWorker(){
var worker=cluster.fork();
//Dengar maklumat, jika jenis disiarkan, ia ditentukan untuk disiarkan
worker.on('message', function(msg) {
If(msg.type=='broadcast'){
var event=msg.event;
//Hantar siaran ini kepada semua pekerja
pekerja.forEach(fungsi(pekerja){
worker.send(event);
})
}
});
Pekerja balik;
}
untuk (var i = 0; i < numCPUs; i ) {
Workers.push(newWorker());
}
cluster.on('online',function(worker){
console.log('pekerja %d dalam talian',worker.id);
})
} lain {
var worker=cluster.worker;
//Siaran adalah untuk menghantar mesej jenis siaran, dan acara ialah kandungan siaran
worker.broadcast=function(event){
pekerja.hantar({
Jenis:'siaran',
acara:acara
});
}
//Nampaknya maklumat yang dikembalikan tidak boleh dipantau menggunakan worker.on di sini
process.on('message',function(event){
console.log('pekerja: ' worker.id ' menerima acara daripada ' event.workerId);
})
//Hantar siaran
worker.broadcast({
Mesej: 'dalam talian',
workerId:worker.id
})
}
Isu yang memerlukan perhatian
Seperti yang dinyatakan di atas, data tidak boleh dikongsi antara utas Semua pertukaran data hanya boleh ditukar melalui komunikasi antara utas. Dan data yang ditukar semuanya boleh bersiri, jadi perkara seperti fungsi, deskriptor fail dan HttpResponse tidak boleh diluluskan.
Jika anda menggunakan kluster, anda perlu mempertimbangkan isu pertukaran data semasa reka bentuk program. Pendekatan saya sendiri adalah untuk menyimpan data seperti sesi dalam redis, dan setiap rangkaian berfungsi dengan baik untuk mengaksesnya dalam ingatan nod.
Titik terakhir, kluster pada masa ini secara rasmi ditandakan sebagai Eksperimen oleh Node dan API mungkin berubah pada masa hadapan.