ตามที่ชื่อคำถามแสดงว่าฉันมีเวลายากที่จะทราบว่าสามารถปรับปรุงอะไรในแอปพลิเคชันของฉัน (หรือปรับในระบบปฏิบัติการ, Ubuntu) เพื่อให้ได้ประสิทธิภาพที่ยอมรับได้ แต่ก่อนอื่นฉันจะอธิบายสถาปัตยกรรม:
เซิร์ฟเวอร์ front-end เป็นเครื่อง 8 คอร์ที่มี 8 gigs RAM ใช้งาน Ubuntu 12.04 แอปพลิเคชั่นเขียนทั้งหมดใน javascript และทำงานใน node.js v 0.8.22 (เนื่องจากโมดูลบางตัวดูเหมือนจะบ่นกับโหนดเวอร์ชั่นใหม่กว่า) ฉันใช้ nginx 1.4 ถึงปริมาณการรับส่งข้อมูลพร็อกซี HTTP จากพอร์ต 80 และ 443 ถึง 8 คนทำงานโหนดที่จัดการ และเริ่มใช้โหนดคลัสเตอร์ api ฉันใช้ socket.io เวอร์ชันล่าสุด 0.9.14 เพื่อจัดการการเชื่อมต่อ websocket ซึ่งฉันได้เปิดใช้งานเฉพาะ websockets และ xhr-polling เป็นการขนส่งที่มีอยู่ ในเครื่องนี้ฉันยังใช้งาน Redis (2.2)
ฉันเก็บข้อมูลถาวร (เช่นผู้ใช้และคะแนน) บนเซิร์ฟเวอร์ตัวที่สองบน mongodb (3.6) ด้วย 4gigs RAM และ 2 คอร์
แอพนี้กำลังใช้งานมาตั้งแต่ไม่กี่เดือน (มันทำงานบนกล่องเดียวจนกระทั่งไม่กี่สัปดาห์ที่ผ่านมา) และมันถูกใช้งานโดยผู้ใช้ประมาณ 18k ต่อวัน มันทำงานได้ดีมากนอกเหนือจากปัญหาหลักอย่างหนึ่งคือประสิทธิภาพลดลง ด้วยการใช้งานปริมาณของซีพียูที่ใช้โดยแต่ละกระบวนการจะเพิ่มขึ้นเรื่อย ๆ จนกว่ามันจะเป็นตัวกำหนดคนงาน (ซึ่งจะไม่ให้บริการตามคำขออีกต่อไป) ฉันได้แก้ไขมันชั่วคราวเพื่อตรวจสอบ cpu ที่ใช้งานโดยผู้ปฏิบัติงานแต่ละคนทุกนาทีและเริ่มใหม่หากถึง 98% ดังนั้นปัญหาที่นี่ส่วนใหญ่เป็นซีพียูและไม่ใช่แรม RAM ไม่ใช่ปัญหาอีกต่อไปตั้งแต่ฉันอัพเดตเป็น socket.io 0.9.14 (เวอร์ชั่นก่อนหน้านี้มีหน่วยความจำรั่ว) ดังนั้นฉันสงสัยว่ามันจะเป็นปัญหาหน่วยความจำรั่วโดยเฉพาะอย่างยิ่งเพราะตอนนี้มันเป็นซีพียูที่เติบโตอย่างรวดเร็ว ฉันต้องรีสตาร์ตแต่ละคนประมาณ 10-12 ครั้งต่อวัน!) RAM ที่ใช้งานเพิ่มขึ้นเช่นกัน แต่ช้ามาก 1 กิ๊กทุก 2-3 วันของการใช้งานและสิ่งที่แปลกคือมันไม่ได้ถูกปล่อยออกมาแม้ว่าฉันจะรีสตาร์ทแอพพลิเคชั่นทั้งหมด มันจะเปิดตัวก็ต่อเมื่อฉันรีบูตเซิร์ฟเวอร์! นี่ฉันไม่เข้าใจจริงๆ ...
ตอนนี้ฉันได้ค้นพบnodeflyซึ่งเป็นสิ่งที่น่าอัศจรรย์ดังนั้นในที่สุดฉันก็สามารถเห็นสิ่งที่เกิดขึ้นบนเซิร์ฟเวอร์การผลิตของฉันและฉันกำลังรวบรวมข้อมูลตั้งแต่สองสามวัน หากใครต้องการดูแผนภูมิฉันสามารถให้คุณเข้าถึงได้ แต่โดยทั่วไปฉันเห็นว่าฉันมีการเชื่อมต่อระหว่าง 80 และ 200 พร้อมกัน! ฉันคาดหวังว่า node.js จะจัดการกับคำขอนับพันไม่ใช่คำขอหลายร้อยรายการ นอกจากนี้เวลาตอบสนองเฉลี่ยสำหรับปริมาณการใช้ http จะอยู่ระหว่าง 500 ถึง 1,500 มิลลิวินาทีซึ่งฉันคิดว่ามันเยอะมาก นอกจากนี้ในขณะนี้ที่มีผู้ใช้ 1,300 คนออนไลน์นี่คือผลลัพธ์ของ "ss-s":
Total: 5013 (kernel 5533)
TCP: 8047 (estab 4788, closed 3097, orphaned 139, synrecv 0, timewait 3097/0), ports 0
Transport Total IP IPv6
* 5533 - -
RAW 0 0 0
UDP 0 0 0
TCP 4950 4948 2
INET 4950 4948 2
FRAG 0 0 0
ซึ่งแสดงให้เห็นว่าฉันมีการเชื่อมต่อที่ปิดเป็นจำนวนมากใน timewait ฉันได้เพิ่มไฟล์ที่เปิดสูงสุดเป็น 999999 นี่คือผลลัพธ์ของ ulimit -a:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 63724
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 999999
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 63724
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
ดังนั้นฉันคิดว่าปัญหาอาจเกิดจากปริมาณการใช้ http ซึ่งด้วยเหตุผลบางอย่างทำให้พอร์ต / ซ็อกเก็ตที่มีอยู่ (?) มี แต่สิ่งหนึ่งที่ไม่สมเหตุสมผลสำหรับฉัน: ทำไมเมื่อฉันรีสตาร์ทพนักงานและลูกค้าทั้งหมดเชื่อมต่อใหม่ภายในไม่กี่วินาที โหลดซีพียูของผู้ปฏิบัติงานลดลงเหลือ 1% และสามารถให้บริการคำขอได้อย่างถูกต้องจนกว่ามันจะอิ่มตัวหลังจากผ่านไปประมาณ 1 ชั่วโมง (ในช่วงเวลาเร่งด่วน)?
ฉันเป็นโปรแกรมเมอร์จาวาสคริปต์ส่วนใหญ่ไม่ใช่ผู้ดูแลระบบ sys ดังนั้นฉันจึงไม่ทราบว่าฉันควรคาดหวังว่าจะรับภาระเท่าใดกับเซิร์ฟเวอร์ของฉัน แต่แน่นอนว่ามันไม่ทำงานตามที่ควร แอพพลิเคชั่นมีความเสถียรเป็นอย่างอื่นและปัญหาสุดท้ายนี้ทำให้ฉันไม่สามารถจัดส่งแอพเวอร์ชั่นมือถือที่พร้อมใช้งานได้เพราะเห็นได้ชัดว่าพวกเขาจะโหลดมากขึ้น
หวังว่าจะมีบางสิ่งที่ชัดเจนว่าฉันทำผิดและใครบางคนจะช่วยชี้ให้เห็น ... อย่าลังเลที่จะขอข้อมูลเพิ่มเติมและขออภัยในความยาวของคำถาม แต่จำเป็นฉันเชื่อว่า ... ขอบคุณล่วงหน้า!
top
เมื่อใช้ cpu ใกล้ 100%