HTML WebSockets รักษาการเชื่อมต่อแบบเปิดสำหรับลูกค้าแต่ละรายหรือไม่ ขนาดนี้หรือไม่


159

ฉันอยากรู้ว่าใครมีข้อมูลเกี่ยวกับ scalability ของ HTML WebSockets สำหรับทุกสิ่งที่ฉันได้อ่านปรากฏว่าลูกค้าทุกคนจะยังคงเปิดบรรทัดการสื่อสารกับเซิร์ฟเวอร์ ฉันแค่สงสัยว่าขนาดนั้นและจำนวนการเชื่อมต่อ WebSocket แบบเปิดที่เซิร์ฟเวอร์สามารถจัดการได้อย่างไร บางทีการเปิดการเชื่อมต่อเหล่านั้นอาจไม่ใช่ปัญหาในความเป็นจริง แต่มันให้ความรู้สึกเหมือนเป็น


1
ไม่มีสิ่งเช่น HTML WebSocket คุณหมายถึง HTTP WebSocket
มาร์ควิสแห่งลอร์น

คำตอบ:


209

WebSockets ส่วนใหญ่น่าจะปรับขนาดได้ดีกว่าคำขอ AJAX / HTML อย่างไรก็ตามนั่นไม่ได้หมายความว่า WebSockets เป็นการทดแทนสำหรับการใช้ AJAX / HTML ทั้งหมด

การเชื่อมต่อ TCP แต่ละตัวนั้นสิ้นเปลืองทรัพยากรเซิร์ฟเวอร์เพียงเล็กน้อย บ่อยครั้งที่การตั้งค่าการเชื่อมต่ออาจมีราคาแพง แต่การรักษาการเชื่อมต่อที่ไม่ได้ใช้งานนั้นเกือบจะฟรี ข้อ จำกัด แรกที่มักพบคือจำนวนตัวอธิบายไฟล์สูงสุด (ซ็อกเก็ตใช้ตัวอธิบายไฟล์) ที่สามารถเปิดได้พร้อมกัน ซึ่งมักจะมีค่าเริ่มต้นที่ 1024 แต่สามารถกำหนดค่าได้ง่ายขึ้น

เคยลองกำหนดค่าเว็บเซิร์ฟเวอร์เพื่อรองรับไคลเอนต์ AJAX พร้อมกันนับหมื่นหรือไม่ เปลี่ยนไคลเอนต์เหล่านั้นเป็นไคลเอนต์ WebSockets และมันอาจเป็นไปได้

การเชื่อมต่อ HTTP ในขณะที่พวกเขาไม่ได้สร้างไฟล์ที่เปิดหรือใช้หมายเลขพอร์ตเป็นเวลานานจะมีราคาแพงกว่าในทุก ๆ ทาง:

  • การเชื่อมต่อ HTTP แต่ละครั้งจะมีสัมภาระจำนวนมากที่ไม่ได้ใช้งานเป็นส่วนใหญ่: คุกกี้, ประเภทเนื้อหา, ความยาวคอนเซ็นต์, เอเจนต์ผู้ใช้, รหัสเซิร์ฟเวอร์, วันที่, การแก้ไขครั้งล่าสุดเป็นต้นเมื่อการเชื่อมต่อ WebSockets เสร็จสิ้น ข้อมูลที่ต้องการโดยแอปพลิเคชันจะต้องส่งกลับไปกลับมา

  • โดยทั่วไปแล้วเซิร์ฟเวอร์ HTTP จะได้รับการกำหนดค่าให้บันทึกการเริ่มต้นและการดำเนินการตามคำขอ HTTP ทุกครั้งเพื่อให้ได้ดิสก์และเวลา CPU มันจะกลายเป็นมาตรฐานในการบันทึกการเริ่มต้นและเสร็จสิ้นข้อมูล WebSockets แต่ในขณะที่การเชื่อมต่อ WebSockets ที่ทำการถ่ายโอนดูเพล็กซ์จะไม่มีการบันทึกค่าใช้จ่ายเพิ่มเติมใด ๆ (ยกเว้นโดยแอปพลิเคชัน / บริการถ้ามันถูกออกแบบให้ทำ)

  • โดยทั่วไปแอปพลิเคชันแบบโต้ตอบที่ใช้ AJAX จะทำการสำรวจความคิดเห็นอย่างต่อเนื่องหรือใช้กลไกการสำรวจความคิดเห็นระยะยาว WebSockets เป็นวิธีที่สะอาดกว่า (และทรัพยากรต่ำกว่า) ในการทำแบบจำลองเหตุการณ์ที่เซิร์ฟเวอร์และไคลเอนต์แจ้งเตือนซึ่งกันและกันเมื่อมีสิ่งที่ต้องรายงานผ่านการเชื่อมต่อที่มีอยู่

  • เว็บเซิร์ฟเวอร์ยอดนิยมส่วนใหญ่ในการผลิตมีพูลของกระบวนการ (หรือเธรด) สำหรับการจัดการคำขอ HTTP เมื่อความดันเพิ่มขนาดของพูลจะเพิ่มขึ้นเนื่องจากแต่ละกระบวนการ / เธรดจัดการคำขอ HTTP ครั้งละหนึ่งรายการ แต่ละกระบวนการ / เธรดเพิ่มเติมใช้หน่วยความจำมากขึ้นและการสร้างกระบวนการ / เธรดใหม่นั้นค่อนข้างแพงกว่าการสร้างการเชื่อมต่อซ็อกเก็ตใหม่ (ซึ่งกระบวนการ / เธรดเหล่านั้นยังคงต้องทำ) เฟรมเวิร์กเซิร์ฟเวอร์ WebSockets ที่เป็นที่นิยมส่วนใหญ่กำลังไปตามเส้นทางที่ต้องการซึ่งมีแนวโน้มที่จะขยายและทำงานได้ดีขึ้น

ประโยชน์หลักของ WebSockets คือการเชื่อมต่อเวลาแฝงที่ต่ำลงสำหรับเว็บแอปพลิเคชันแบบโต้ตอบ มันจะขยายขนาดได้ดีขึ้นและใช้ทรัพยากรเซิร์ฟเวอร์น้อยกว่า HTTP AJAX / Long-Poll (สมมติว่าแอปพลิเคชัน / เซิร์ฟเวอร์ได้รับการออกแบบอย่างเหมาะสม) แต่ IMO ที่ต่ำกว่า latency เป็นประโยชน์หลักของ WebSockets เพราะจะเปิดใช้งานเว็บคลาสใหม่ ด้วยค่าใช้จ่ายในปัจจุบันและเวลาแฝงของ AJAX / แบบสำรวจความยาว

เมื่อมาตรฐาน WebSockets ได้รับการสรุปแล้วและมีการสนับสนุนที่กว้างขึ้นก็จะเหมาะสมที่จะใช้กับเว็บแอปพลิเคชั่นโต้ตอบใหม่ที่ต้องการสื่อสารบ่อยครั้งกับเซิร์ฟเวอร์ สำหรับแอปพลิเคชั่นเว็บเชิงโต้ตอบที่มีอยู่มันจะขึ้นอยู่กับว่า AJAX / แบบสำรวจความคิดเห็นระยะยาวใช้งานได้ดีเพียงใด ความพยายามในการแปลงจะไม่ไร้สาระดังนั้นในหลายกรณีค่าใช้จ่ายจะไม่คุ้มกับผลประโยชน์

อัปเดต :

ลิงค์ที่มีประโยชน์: การเชื่อมต่อ websocket พร้อมกัน 600k บน AWS โดยใช้ Node.js


4
Anser ที่น่ากลัว ขอบคุณที่สละเวลาตอบ
Ryan Montgomery

7
แต่ฉันก็ยังไม่รู้วิธีการไต่ระดับเมื่อคุณชนกำแพง เป็นความจริงที่ WebSockets ใช้ทรัพยากรน้อยลง (ปรับขยายตามแนวตั้ง) แต่ HTTP นั้นยอดเยี่ยมสำหรับการปรับขนาดในแนวนอน ในทางทฤษฎีฉันสามารถเพิ่มเซิร์ฟเวอร์ให้ขยายได้ไม่ จำกัด ฉันมักจะสับสนเกี่ยวกับวิธีการปรับขนาดเมื่อคุณใช้ความจุของกล่องเดียว คิด?
Sean Clark Hess

6
@Sean WebSockets ไม่จำเป็นต้องปรับขนาดในแนวนอน มันเพิ่งเปิดแอพพลิเคชั่นใหม่ที่ไม่จำเป็นต้องปรับขนาดได้อย่างง่ายดาย ตัวอย่างเช่นสำหรับการให้บริการข้อมูลคงที่กลุ่มของเซิร์ฟเวอร์ WebSocket จะปรับขนาดด้วย (หรือดีกว่า) มากกว่าเซิร์ฟเวอร์ HTTP จำนวนมาก เกมเรียลไทม์ที่มีความหน่วงแฝงต่ำยากต่อการปรับขนาดโดยไม่คำนึงถึงการขนส่ง (และเป็นไปไม่ได้เลยที่จะใช้ HTTP) คำถามจริงก็คือข้อมูล / แอปพลิเคชันของคุณปรับขนาดได้ดีแค่ไหน หากมีขนาดดังกล่าวแสดงว่าตัวเลือก HTTP vs WebSockets ของคุณควรขึ้นอยู่กับปัจจัยอื่น ๆ : ความหน่วงแฝงตัวเลือกการปรับใช้การสนับสนุนเบราว์เซอร์ ฯลฯ
kanaka

2
One correction - การเชื่อมต่อ TCP ประกอบด้วย IP ปลายทางและพอร์ตปลายทาง ซึ่งหมายความว่าขีด จำกัด ของพอร์ต± 64k นั้นแท้จริงแล้วสำหรับไคลเอ็นต์เดียวเท่านั้น ในทางทฤษฎีเซิร์ฟเวอร์สามารถมีการเชื่อมต่อแบบเปิดจำนวนเท่าใดก็ได้ จำกัด โดยฮาร์ดแวร์เท่านั้น
Rizon

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

36

เพียงชี้แจง: จำนวนการเชื่อมต่อไคลเอนต์ที่เซิร์ฟเวอร์สามารถรองรับไม่มีอะไรเกี่ยวข้องกับพอร์ตในสถานการณ์นี้เนื่องจากเซิร์ฟเวอร์ [ปกติ] ฟังเฉพาะการเชื่อมต่อ WS / WSS บนพอร์ตเดียว ฉันคิดว่าสิ่งที่ผู้วิจารณ์คนอื่นหมายถึงคือตัวอธิบายไฟล์ คุณสามารถกำหนดจำนวนตัวอธิบายไฟล์สูงสุดได้ค่อนข้างสูง แต่จากนั้นคุณต้องระวังขนาดซ็อกเก็ตบัฟเฟอร์ที่เพิ่มขึ้นสำหรับซ็อกเก็ต TCP / IP ที่เปิดอยู่แต่ละตัว นี่คือข้อมูลเพิ่มเติมบางส่วน: /server/48717/practical-maximum-open-file-descriptors-ulimit-n-for-a-high-volume-system

สำหรับเวลาแฝงที่ลดลงผ่าน WS กับ HTTP มันเป็นความจริงเนื่องจากไม่มีการแยกวิเคราะห์ส่วนหัว HTTP เพิ่มเติมนอกเหนือจาก WS Handshake เริ่มต้น ยิ่งไปกว่านั้นเมื่อแพ็กเก็ตจำนวนมากถูกส่งสำเร็จหน้าต่างความแออัด TCP ก็กว้างขึ้นซึ่งจะช่วยลด RTT ได้อย่างมีประสิทธิภาพ


AFAIR มีพอร์ตขาเข้าหนึ่งพอร์ต แต่จะเปิดพอร์ตขาออกหนึ่งพอร์ตสำหรับการเชื่อมต่อแต่ละครั้งเสมอ นี้อยู่ในโฉนดเพียงส่วนหนึ่งของปัญหา C10k
Arnaud Bouchez

14

เซิร์ฟเวอร์เดี่ยวสมัยใหม่ใด ๆ ก็สามารถใช้เซิร์ฟเวอร์ได้ ลูกค้าหลายพันรายในครั้งเดียว ซอฟต์แวร์เซิร์ฟเวอร์ HTTP นั้นต้องเป็นแบบ Event-Driven (IOCP) (เราไม่ได้อยู่ใน Apache หนึ่งการเชื่อมต่อเก่า = หนึ่งเธรด / สมการกระบวนการอีกต่อไป) แม้แต่เซิร์ฟเวอร์ HTTP ที่สร้างขึ้นใน Windows (http.sys) นั้นเป็น IOCP ที่มุ่งเน้นและมีประสิทธิภาพมาก (ทำงานในโหมดเคอร์เนล) จากมุมมองนี้จะไม่มีความแตกต่างอย่างมากระหว่างการปรับขนาดระหว่าง WebSockets และการเชื่อมต่อ HTTP ปกติ การเชื่อมต่อ TCP / IP หนึ่งครั้งใช้ทรัพยากรเพียงเล็กน้อย (น้อยกว่าเธรดมาก) และระบบปฏิบัติการที่ทันสมัยได้รับการปรับให้เหมาะสมสำหรับการจัดการการเชื่อมต่อที่เกิดขึ้นพร้อมกันจำนวนมาก: WebSockets และ HTTP เป็นเพียงโปรโตคอลชั้นแอปพลิเคชัน OSI 7

แต่จากการทดสอบฉันเห็นปัญหาหลักสองประการเกี่ยวกับ WebSockets:

  1. พวกเขาไม่สนับสนุน CDN
  2. พวกเขามีปัญหาด้านความปลอดภัยที่อาจเกิดขึ้น

ดังนั้นฉันขอแนะนำสิ่งต่อไปนี้สำหรับโครงการใด ๆ :

  • ใช้ WebSockets สำหรับการแจ้งเตือนลูกค้าเท่านั้น (ด้วยกลไกทางเลือกในการโพลแบบยาว - มีไลบรารีอยู่มากมาย)
  • ใช้ RESTful / JSON สำหรับข้อมูลอื่นทั้งหมดโดยใช้ CDN หรือพร็อกซีสำหรับแคช

ในทางปฏิบัติแอปพลิเคชัน WebSockets เต็มรูปแบบมีขนาดไม่ดี เพียงใช้ WebSockets สำหรับสิ่งที่พวกเขาออกแบบมาเพื่อ: แจ้งเตือนผลักดันจากเซิร์ฟเวอร์ไปยังลูกค้า

เกี่ยวกับปัญหาที่อาจเกิดขึ้นจากการใช้ WebSockets:

1. พิจารณาการใช้ CDN

วันนี้ (เกือบ 4 ปีต่อมา) การปรับขนาดเว็บเกี่ยวข้องกับการใช้ส่วนหน้าของเครือข่ายการจัดส่งเนื้อหา (CDN) ไม่เพียง แต่สำหรับเนื้อหาแบบคงที่ (html, css, js) แต่ยังข้อมูลแอปพลิเคชัน (JSON) ของคุณคุณ

แน่นอนคุณจะไม่ใส่ข้อมูลทั้งหมดในแคช CDN ของคุณ แต่ในทางปฏิบัติเนื้อหาทั่วไปจำนวนมากจะไม่เปลี่ยนแปลงบ่อยนัก ฉันสงสัยว่า 80% ของทรัพยากร REST ของคุณอาจถูกแคช ... แม้แต่หนึ่งนาที (หรือ 30 วินาที) การหมดเวลาหมดอายุของ CDN อาจเพียงพอที่จะทำให้เซิร์ฟเวอร์ส่วนกลางของคุณมีชีวิตใหม่และปรับปรุงการตอบสนองของแอปพลิเคชันได้มากเนื่องจาก CDN ปรับทางภูมิศาสตร์ ...

สำหรับความรู้ของฉันยังไม่มีการสนับสนุน WebSockets ใน CDN และฉันสงสัยว่ามันจะไม่เป็นเช่นนั้น WebSockets เป็น statefull ในขณะที่ HTTP ไร้สัญชาติดังนั้นแคชจะง่ายกว่ามาก ในความเป็นจริงเพื่อให้ WebSockets เป็นมิตรกับ CDN คุณอาจต้องเปลี่ยนไปใช้วิธี RESTful แบบไร้สัญชาติ ... ซึ่งจะไม่เป็น WebSockets อีกต่อไป

2. ปัญหาด้านความปลอดภัย

WebSockets มีปัญหาด้านความปลอดภัยที่อาจเกิดขึ้นโดยเฉพาะเกี่ยวกับการโจมตีของ DOS สำหรับภาพประกอบเกี่ยวกับช่องโหว่ด้านความปลอดภัยใหม่ให้ดูชุดสไลด์และตั๋ว webkitนี้

WebSockets หลีกเลี่ยงโอกาสในการตรวจสอบแพ็คเก็ตที่ระดับเลเยอร์แอปพลิเคชัน OSI 7 ซึ่งมาเป็นมาตรฐานในทุกวันนี้ในด้านความปลอดภัยทางธุรกิจ ในความเป็นจริง WebSockets ทำให้การส่งข้อมูลสับสนดังนั้นอาจเป็นการละเมิดความปลอดภัยที่สำคัญ


2
@ArnaudBouchez - +1 สำหรับการแสดงออกที่ดีใน CDN คำถามติดตามอย่างรวดเร็ว - คุณคิดอย่างไรกับความเป็นไปได้ของเครือข่ายการจัดส่งกิจกรรม สร้างขึ้นหลังจาก CDNs แต่มุ่งไปที่การส่งข้อมูลสตรีมมิ่ง ฯลฯ ผ่าน websockets หรืออื่น ๆ ซึ่งเป็นเทคโนโลยีที่มองไม่เห็น
quixver

8

ลองใช้วิธีนี้: ราคาถูกกว่า, รักษาการเชื่อมต่อแบบเปิดหรือเปิดการเชื่อมต่อใหม่สำหรับทุกคำขอ (ด้วยค่าใช้จ่ายในการเจรจาต่อรองในการทำเช่นนั้นให้จำไว้ว่าเป็น TCP)

แน่นอนว่ามันขึ้นอยู่กับแอพพลิเคชั่น แต่สำหรับการเชื่อมต่อแบบเรียลไทม์ในระยะยาว (เช่นการแชท AJAX) มันจะดีกว่ามากหากเปิดการเชื่อมต่อไว้

จำนวนสูงสุดของการเชื่อมต่อจะถูก จำกัด โดยจำนวนพอร์ตว่างสูงสุดสำหรับซ็อกเก็ต


คุณสามารถเปิดการเชื่อมต่อโดยไม่ใช้ WebSocket (ขอบคุณตัวเลือก keep alive ของ HTTP / 1.1) ฉันไม่แน่ใจว่าฉันเข้าใจประเด็นของคุณที่นี่
Arnaud Bouchez

1
+1 คนมักจะลืมตั้งค่าการเชื่อมต่อ TCP เกี่ยวข้องกับการซิงค์ / ack / ack และ TLS ต้องการการเดินทางไปกลับที่มากกว่าสำหรับการแลกเปลี่ยนคีย์
quixver

1
@ArnaudBouchez ตรวจสอบen.wikipedia.org/wiki/HTTP_persistent_connection#HTTP_1.1 WebSockets เปิดอยู่ตราบเท่าที่คุณต้องการและไม่แฮ็ก (เช่นการสำรวจระยะยาวและทางเลือกอื่น ๆ )
kaoD

-5

ไม่มีการปรับขนาดให้การทำงานอย่างมากกับสวิตช์เส้นทางกลาง จากนั้นทางฝั่งเซิร์ฟเวอร์ข้อผิดพลาดของหน้า (คุณต้องให้ตัวอธิบายเหล่านั้นทั้งหมด) ถึงค่าสูงและเวลาที่จะนำทรัพยากรเข้ามาในพื้นที่ทำงานเพิ่มขึ้น เซิร์ฟเวอร์เหล่านี้ส่วนใหญ่เป็น JAVA ที่เขียนขึ้นและอาจเร็วกว่าที่จะเก็บไว้ในช่อง gazilions ของซ็อกเก็ตเหล่านั้นเพื่อทำลาย / สร้าง เมื่อคุณเรียกใช้เซิร์ฟเวอร์บนเครื่องกระบวนการอื่น ๆ ไม่สามารถย้ายได้อีกต่อไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.