โหลดบาลานซ์เว็บซ็อกเก็ต


105

ฉันมีคำถามเกี่ยวกับวิธีโหลดซ็อกเก็ตเว็บบาลานซ์

ฉันมีเซิร์ฟเวอร์ที่รองรับเว็บซ็อกเก็ต www.mydomain.comเบราว์เซอร์เชื่อมต่อไปยังเว็บไซต์ของฉันและแต่ละคนเปิดเว็บเพื่อซ็อกเก็ต ด้วยวิธีนี้แอปโซเชียลเน็ตเวิร์กของฉันสามารถส่งข้อความไปยังลูกค้าได้

ตามเนื้อผ้าโดยใช้คำขอ HTTP เพียงอย่างเดียวฉันจะขยายขนาดโดยการเพิ่มเซิร์ฟเวอร์ที่สองและตัวโหลดบาลานเซอร์หน้าเว็บเซิร์ฟเวอร์ทั้งสอง

ด้วยซ็อกเก็ตเว็บการเชื่อมต่อจะต้องเชื่อมต่อโดยตรงกับเว็บเซิร์ฟเวอร์ไม่ใช่ตัวโหลดบาลานเซอร์เพราะหากเครื่องมีขีด จำกัด ทางกายภาพของพอร์ตที่เปิด 64k และไคลเอนต์กำลังเชื่อมต่อกับตัวโหลดบาลานเซอร์ฉันก็จะไม่รองรับ ผู้ใช้งานพร้อมกันมากกว่า 64k

แล้วฉันจะทำอย่างไร -

  1. รับไคลเอ็นต์เพื่อเชื่อมต่อโดยตรงกับเว็บเซิร์ฟเวอร์ (แทนที่จะเป็นตัวโหลดบาลานเซอร์) เมื่อโหลดหน้า? ฉันเพียงแค่โหลด JavaScript จากโหนดหรือไม่และตัวจัดสรรภาระงาน (หรืออะไรก็ตาม) จะปรับเปลี่ยน URL ของสคริปต์แบบสุ่มทุกครั้งที่มีการร้องขอหน้าแรกหรือไม่

  2. จัดการเริ่มระลอก? เบราว์เซอร์จะสังเกตว่าการเชื่อมต่อถูกปิดเมื่อเว็บเซิร์ฟเวอร์ปิดตัวลง ฉันสามารถเขียนโค้ด JavaScript เพื่อพยายามเปิดการเชื่อมต่ออีกครั้ง แต่โหนดจะหายไปชั่วขณะ ดังนั้นฉันเดาว่าฉันจะต้องกลับไปที่ตัวจัดสรรภาระงานเพื่อสอบถามที่อยู่ของโหนดถัดไปที่จะใช้?

  3. ฉันสงสัยเกี่ยวกับตัวจัดสรรภาระงานที่ส่งการเปลี่ยนเส้นทางในคำขอเริ่มต้นเพื่อให้เบราว์เซอร์ร้องขอwww.mydomain.comและเปลี่ยนเส้นทางไปยังwww34.mydomain.comไฟล์. ซึ่งทำงานได้ค่อนข้างดีจนกว่าโหนดจะหยุดทำงานและเว็บไซต์เช่น Facebook จะไม่ทำเช่นนั้น พวกเขาทำมันได้อย่างไร?


1
คุณสามารถโหลดยอดคงเหลือได้ที่เลเยอร์เครือข่ายตามที่แนะนำที่นี่
Chris Snow

1
นอกจากนี้ยังมีแนวทางอื่น ๆ เช่นการปรับสมดุลการโหลดตาม DNS หรือการใช้เซิร์ฟเวอร์การจัดระเบียบที่ใช้ http ฉันได้พยายามสรุปขึ้นและลงของแต่ละแนวทางที่deepstream.io/blog/load-balancing-websocket-connections
wolframhempel

@wolframhempel ลิงค์ตายแล้ว :-(
Emile Cormier

คำตอบ:


96

ใส่ตัวโหลดบาลานเซอร์ L3 ที่กระจายแพ็กเก็ต IP ตามแฮชพอร์ตต้นทางไปยังฟาร์มเซิร์ฟเวอร์ WebSocket ของคุณ เนื่องจากตัวปรับสมดุล L3 ไม่มีสถานะใด ๆ (โดยใช้พอร์ต IP ต้นทางที่แฮช) จึงปรับขนาดเป็นความเร็วในการต่อสายบนฮาร์ดแวร์ระดับล่าง (พูดว่า 10GbE) เนื่องจากการกระจายเป็นแบบกำหนด (โดยใช้พอร์ตที่มา - IP ที่แฮช) จึงทำงานร่วมกับ TCP (และด้วยเหตุนี้ WebSocket)

นอกจากนี้โปรดทราบว่าขีด จำกัด ฮาร์ด 64k ใช้กับTCP / IP ขาออกสำหรับที่อยู่ IP (ต้นทาง) ที่กำหนดเท่านั้น ใช้ไม่ได้กับ TCP / IP ขาเข้า เราได้ทดสอบAutobahn (เซิร์ฟเวอร์ WebSocket ประสิทธิภาพสูง) ด้วยการเชื่อมต่อที่ใช้งานอยู่ 200k บน 2 คอร์, 4GB RAM VM

นอกจากนี้โปรดทราบว่าคุณสามารถทำ L7 load-balancing บนเส้นทาง HTTP ที่ประกาศในระหว่างการจับมือ WebSocket ครั้งแรก ในกรณีนี้ตัวจัดสรรภาระงานต้องรักษาสถานะ (คู่พอร์ต IP ต้นทางใดจะไปที่โหนดแบ็กเอนด์) อาจขยายเป็นล้านการเชื่อมต่ออย่างไรก็ตามในการตั้งค่าที่เหมาะสม

คำเตือน: ฉันเป็นผู้เขียนต้นฉบับของ Autobahn และทำงานให้กับ Tavendo


ดังนั้นฉันจะโหลดไลบรารี javascript ของฉันจาก URL ตัวจัดสรรภาระงานและให้ URL ตัวจัดสรรภาระงานเมื่อฉันสร้างเว็บซ็อกเก็ตในจาวาสคริปต์ - คุณหมายความว่าเบราว์เซอร์โปร่งใสหรือไม่? มันเจ๋งมาก!
John Smith

1
ใช่มี URL เพียง 1 รายการและชื่อโฮสต์หลังควรแก้ไขเป็นตัวจัดสรรภาระงานของคุณ เซิร์ฟเวอร์แบ็กเอนด์ WebSocket มี IP ภายใน (ไม่ใช่แบบสาธารณะ) และสามารถเลือกรันบนพอร์ตที่แตกต่างจากเซิร์ฟเวอร์สาธารณะได้เช่นกัน ข้อแม้เดียวคือคุณอาจต้องบอกเซิร์ฟเวอร์ WebSocket ว่าชื่อโฮสต์, IP, พอร์ตสาธารณะที่มองเห็นได้คืออะไรเนื่องจากเซิร์ฟเวอร์ WebSocket ที่สอดคล้องกันจะตรวจสอบว่า URL ที่ให้มาในส่วนหัว HTTP ของการจับมือ WS ตรงกับชื่อโฮสต์ / ip / พอร์ต กำลังฟังอยู่
oberstet

ฉันไม่มีการเชื่อมต่อ websocket จำนวนมากเพื่อความสมดุล แต่ฉันมีปริมาณการใช้งานจำนวนมากในหนึ่งเดียวหรือพูดถึงการเชื่อมต่อน้อยมาก เพื่อความเรียบง่ายพูดว่าการเชื่อมต่อเดียวตอนนี้ฉันจะสร้างสมดุลให้กับคำขอผ่านการเชื่อมต่อเว็บซ็อกเก็ตเดียวได้อย่างไร
user1870400

เมื่อฉันทำการเชื่อมต่อมากกว่า 5,000+ ใน websocket java มันจะไม่ปล่อยหน่วยความจำ .... มีวิธีแก้ไขหรือไม่?
Poonam Patel

3

โปรดทราบว่าหากตรรกะเซิร์ฟเวอร์ websocket ของคุณทำงานบน nodejs ด้วย socket.io คุณสามารถบอกให้ socket.io ใช้ที่เก็บคีย์ / ค่า redis ที่แบ่งใช้สำหรับการซิงโครไนซ์ วิธีนี้ทำให้คุณไม่ต้องสนใจตัวโหลดบาลานเซอร์ด้วยซ้ำเหตุการณ์ต่างๆจะแพร่กระจายไปตามอินสแตนซ์ของเซิร์ฟเวอร์

var io = require('socket.io')(3000);
var redis = require('socket.io-redis'); 
io.adapter(redis({ host: 'localhost', port: 6379 }));

ดู: http://socket.io/docs/using-multiple-nodes/

แต่ในบางจุดฉันเดาว่า redis อาจกลายเป็นคอขวด ...


2

นอกจากนี้คุณยังสามารถทำโหลดบาลานซ์เลเยอร์ 7 ด้วยการตรวจสอบและ "ฟังก์ชันการกำหนดเส้นทาง"

ดู "วิธีตรวจสอบและปรับสมดุลการรับส่งข้อมูล WebSockets โดยใช้ Stingray Traffic Manager และเมื่อจำเป็นวิธีจัดการการรับส่งข้อมูล WebSockets และ HTTP ที่ได้รับบนที่อยู่ IP และพอร์ตเดียวกัน" https://splash.riverbed.com/docs/DOC-1451


2
ฉันต้องทำการตรวจสอบเพื่อหาข้อมูลที่คุณเชื่อมโยง เครื่อง wayback ช่วยฉันค้นหาสำเนาสดของบทความนั้น: community.pulsesecure.net/t5/Pulse-Secure-vADC/…
Wyck
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.