TPA & Alibaba Cloud ผนึกกำลัง สร้างสรรค์สัมมนาและอบรม ต่อยอดความร่วมมือสู่อนาคต
เมื่อวันที่ 21 พฤศจิกายน ที่ผ่านมา คุณเซฟ พงษ์ศิริ นายก […]
การทำ Cluster มีความหมายค่อนข้างกว้างและเกี่ยวกับเรื่องการจัดกลุ่ม สำหรับไลบรารี่ Cluster ของ NodeJS คือการแตกโปรเซสออกเป็นหลายๆ โปรเซส เพื่อกระจายการทำงาน สำหรับ NodeJS จะทำงานแบบ Single Thread ถ้าต้องการกระจายงานให้สามารถทำงานพร้อมกันได้หลายงานต้องทำการแตกโปรเซสออกเป็นหลายๆตัว ซึ่งก็คือการทำ Cluster
ข้อแนะนำจากนักออกแบบสถาปัตยกรรมซอฟแวร์ แนะนำว่า ไม่ควรจะแยกเกินจำนวน CPU ที่มีในเครื่อง เพราะแยกเกินก็ไม่ได้ความว่าเครื่องจะทำงานเร็วขึ้น ต้องดูว่า CPU มีความพร้อมในการประมวลผลแค่ไหน ถ้าแตกเกินจำนวน CPU ที่มี โปรเซสที่มีมากมายก็ต้องรอการทำงานของ CPU ที่สามารถทำงานนั้นๆให้ได้อยู่ดี และระบบส่วนใหญ่ก็มักจะไปคอขวดที่ฐานข้อมูลเป็นหลัก ดังนั้นแต่ละระบบก็ต้องออกแบบการแยก Cluster ให้เหมาะสมกับความสามารถในการรับโหลดของฐานข้อมูลด้วย ทั้งนี้ก็ขึ้นอยู่กับรูปแบบของแต่ละแอพพลิเคชั่นว่ามีรูปแบบการทำงานอย่างไร
[img src=”/wp-content/uploads/2016/02/nodecluster.png”]
ตัวอย่างโค้ด
const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { // Fork workers. for (var i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); }); } else { // Workers can share any TCP connection // In this case it is an HTTP server http.createServer((req, res) => { res.writeHead(200); res.end('hello worldn'); }).listen(8000); }
โค้ดนี้นำมาจาก https://nodejs.org/api/cluster.html
อธิบายโค้ด
const cluster = require('cluster');
เรียกใช้ไลบรารี่ cluster
const numCPUs = require('os').cpus().length;
เรียกใช้ ไลบรารี่ os ซึ่งจะมีข้อมูลสำคัญๆของเครื่องซึ่งเอามาจากระบบปฏิบัติการ เช่น จำนวน CPU , memory , disk
if (cluster.isMaster) { // Fork workers. for (var i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); }); }
ตรวจสอบว่าเป็น master cluster หรือไม่ จากนั้นวนลูปสร้างโปรเซสขึ้นตามจำนวน CPU
for (var i = 0; i < numCPUs; i++) { cluster.fork(); }
ถ้าโปรเซสไหนตายให้แสดงข้อความ บอกเลข processid ที่ตาย
cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); });
หากไม่ใช่ master โปรเซสให้สร้าง http server ที่ port 8000
http.createServer((req, res) => { res.writeHead(200); res.end('hello worldn'); }).listen(8000);
ทำการทดสอบ เปิด Browser พิมพ์ localhost:8000
เปิดโปรแกรม Activity Monitor หรือ Task Manager
[img src=”/wp-content/uploads/2016/02/nodeclusterprocess.png”]
จากรูปจะพบว่าที่เครื่องที่มี CPU 4 Cores มี node ทั้งหมด 5 โปรเซส จะมี 1 โปรเซสที่ทำหน้าที่เป็น Load Balance คอยกระจายงานให้โปรเซสอื่นๆ
ในการใช้งานจริงผมจะไม่ได้มาเขียนฟังก์ชั่นสำหรับทำ cluster แบบนี้ จะใช้เครื่องมือสำหรับ monitor และสร้าง cluster ได้ นอกจากนั้นเมื่อมีโปรเซสตายก็จะสร้างโปรเซสใหม่ขึ้นทันที ทำให้โปรเซสของ node รันได้ตลอดเวลา โดยเครื่องมือนั้นชื่อว่า PM2
ติดตั้ง pm2
npm install pm2 -g
pm2 ต้องใช้ออพชั่น -g เพื่อให้สามารถรันคำสั่ง pm2 จาก terminal ได้
รัน pm2
นำไฟล์ตัวอย่างตอนที่ 5 มารันคำสั่ง ดังนี้
pm2 start ch5_restapi.js -i 4
[img class=”alignnone size-large wp-image-1292″ src=”/wp-content/uploads/2016/02/pm2.png”/]
จากคำสั่งก่อนหน้า ออบชั่น -i ตามด้วยตัวเลข คือจำนวน cluster ที่ต้องการแบ่ง จะเห็นได้ว่าเราไม่จำเป็นต้องเขียนโค้ดเลย แถมบอกสถานะแต่ละ cluster เป็นอย่างไรบ้าง เมื่อโปรเซสไหนตาย ก็จะ Start ขึ้นมาใหม่อัตโนมัติ
หากต้องการ ลบโปรเซสทั้งหมดใช้คำสั่ง
pm2 kill
สำหรับคำสั่งของ pm2 สามารถพิมพ์ pm2 ที่ terminal ได้ หรือหาข้อมูลเพิ่มเติมได้ที่ https://github.com/Unitech/pm2
นอกจากนั้นยังมีเครื่องมือในการ monitor nodejs อย่าง http://pm2.keymetrics.io/
โปรดติดตามตอนที่ 10 การทำงานกับไฟล์