การทำโหลดบาลานซ์ทำได้ใน MMO อย่างไร


26

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

คำถามของฉันคือการทำ load balancing ให้ประสบความสำเร็จใน MMO ได้อย่างไร?

ลิงค์ใด ๆ หนังสือหรือข้อมูลทั่วไปเกี่ยวกับวิธีการพัฒนาความรู้ของฉันในเรื่องนี้ก็ชื่นชม

คำตอบ:


30

พยายามทำให้สิ่งนี้เรียบง่ายที่สุดเท่าที่จะเป็นไปได้และอินเทอร์เฟซที่กำหนดไว้อย่างดีและจัดทำเป็นเอกสาร การบำรุงรักษาและแก้ไขข้อบกพร่องของระบบที่ซับซ้อนในการผลิตกลายเป็นนรกได้ง่าย ดังนั้นหากมีวิธีการที่ง่ายและซับซ้อนให้คิดสองครั้งก่อนที่คุณจะไปกับวิธีที่ซับซ้อน

การกำหนดบริการ

ฉันคิดว่าขั้นตอนแรกคือการระบุบริการและการอ้างอิงของพวกเขา : เนื้อหาคงที่, การรับรองความถูกต้อง, แชทท้องถิ่น, แชททั่วโลก, แชทระดับภูมิภาค, แชทภูมิภาค, รายชื่อเพื่อน, กิลด์, กระเป๋า / สินค้าคงคลัง, ประมูลบ้าน, แผนที่โลก, ...

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

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

เซิร์ฟเวอร์โลก

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

วิธีง่ายๆคือการแบ่งโลกออกเป็นภูมิภาคที่เป็นอิสระ ด้วยภูมิภาคที่เป็นอิสระฉันหมายความว่าผู้เล่นไม่สามารถมองจากส่วนหนึ่งไปยังอีกส่วนหนึ่งและมอนสเตอร์ไม่สามารถข้ามส่วนได้ ภูมิภาคเหล่านั้นแตกต่างจากภูมิภาคที่ผู้เล่นเห็นตามภูมิทัศน์และเรื่องราวของโลกภายนอก โดยปกติแล้วสัตว์ประหลาดส่วนใหญ่จะอยู่ในคุกใต้ดินและผู้เล่นมักจะยอมรับว่าพวกเขาต้องเดินผ่านประตูเพื่อเข้าสู่ดันเจี้ยน โดยเฉพาะอย่างยิ่งถ้าดันเจี้ยนเหล่านั้นมีการยกตัวอย่างในแต่ละกลุ่มผู้เล่น ตัวอย่างอื่น ๆ ในโลกภายนอกเป็นทวีปและหุบเขาที่ล้อมรอบด้วยภูเขาสูง

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

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

ขึ้นอยู่กับความซับซ้อนของรุ่นเครื่องเล่นของคุณอาจใช้เวลาสองสามวินาทีในการถ่ายโอนไปยังเซิร์ฟเวอร์อื่น (Second Life มีปัญหาใหญ่ในเรื่องนี้) ปัญหานี้สามารถบรรเทาได้ด้วยการเตรียมการโอนล่วงหน้าเมื่อผู้เล่นเข้าใกล้ชายแดนเสมือนจริง เพื่อให้ข้อมูลเครื่องเล่นส่วนใหญ่ถูกแคชไว้แล้วบนเซิร์ฟเวอร์ปลายทางเมื่อมีการส่งมอบจริง

สรุป

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

PS: เทคนิคเหล่านี้บางอย่างสามารถนำมาใช้เพื่อปรับปรุงความน่าเชื่อถือ และคุณควรระลึกไว้เสมอว่าการใช้เซิร์ฟเวอร์หลายเครื่องมีความเสี่ยงต่อการแตกหักที่สูงกว่ามาก ไม่เพียง แต่ในซอฟต์แวร์ แต่ยังอยู่ในระดับฮาร์ดแวร์


แต่จริงๆแล้วคุณจะทำการสื่อสารระหว่างกระบวนการนี้ได้อย่างไร IPC ประเภทใดที่ควรใช้
majidarif

10

โดยทั่วไปโลกถูกแบ่งออกเป็นภูมิภาคเล็ก ๆ จำนวนหนึ่ง แต่ละภูมิภาคเหล่านี้มักจะเป็นกระบวนการเซิร์ฟเวอร์อิสระ (เซิร์ฟเวอร์โลกของ WoW หรือโหนด Sol ของ Eve) และสามารถทำงานกับเครื่องจำนวนหนึ่ง ในบางเกมมีประตูที่ชัดเจนระหว่างแผนที่ (Eve, STO, Guild Wars) ในขณะที่บางเกมพยายามปกปิดมากกว่านี้ (WAR, Free Realms) ผู้ที่เลือกใช้วิธีการที่ราบรื่นยิ่งขึ้นโดยทั่วไปจะตรวจพบเมื่อคุณใกล้ขอบระหว่างเซิร์ฟเวอร์สองเครื่องและกระบวนการทั้งสองเจรจาต่อรองแฮนด์ออฟ สถานที่ที่ดีที่สุดที่จะมองหาคำอธิบายในที่นี้คือเสาสัญญาณของโทรศัพท์เคลื่อนที่ หากการโหลดแผนที่เดียว (Jita, Ironforge, Earth Space Dock) มีขนาดใหญ่มากบางครั้งคุณสามารถถ่ายโอนแต่ละฟังก์ชั่นไปยังเซิร์ฟเวอร์อื่น (AI, การจัดการผู้เล่นบางส่วน) แต่สิ่งนี้จะต้องมีมาพร้อมกับตัวเครื่องตั้งแต่เริ่มต้นหรืออาจจะต้องทำการดัดแปลงเพิ่มเติม เกือบจะคุ้มค่ากว่าที่จะซื้อฮาร์ดแวร์ที่ดีกว่าเพื่ออุทิศให้กับแผนที่เหล่านั้น


9

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

อาจไม่เหมือนที่คุณคิด อย่างน้อยไม่ใช่ถ้าคุณคิดว่าโลกที่ไร้รอยต่อจะได้รับการจัดการโดยเซิร์ฟเวอร์หลายเครื่องพร้อมกัน

ไม่นับเศษที่แยกออกจากกันโดยสิ้นเชิงมี 2 ทิศทางที่คุณสามารถแยกเกมออนไลน์ซึ่งอาจพิจารณาเป็น "แนวนอน" และ "แนวตั้ง":

  • แบ่งเกมออกเป็นหลายพื้นที่ทางภูมิศาสตร์แยก ฟังก์ชั่นทั้งหมดสำหรับพื้นที่ทางภูมิศาสตร์ที่กำหนดจะได้รับการจัดการโดยเซิร์ฟเวอร์เดียวและไม่มีการโต้ตอบกันระหว่างพวกเขา (โปรดทราบว่าไม่จำเป็นต้องมีเพียง 1 โซนต่อเซิร์ฟเวอร์ - เซิร์ฟเวอร์อาจจัดการหลายโซนพร้อมกันและโซนสามารถโอนระหว่างเซิร์ฟเวอร์เพื่อจัดการกับการเปลี่ยนแปลงโหลด)
  • แบ่งเกมออกเป็นบริการหลายประเภทเช่น การเข้าสู่ระบบ / การอนุญาตกฎการเล่นเกมและฟิสิกส์การแชท + ประมูลการคงอยู่เป็นต้นบริการเหล่านี้สามารถจัดการได้โดยเซิร์ฟเวอร์ที่แตกต่างกัน คำตอบของ nhnb ได้ระบุบริการที่มีศักยภาพอื่น ๆ ที่ผู้พัฒนาสามารถแบ่งเกมของพวกเขาเป็น

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

แต่โดยรวมแล้วเมื่อมีการแบ่งส่วนทางภูมิศาสตร์เกมส่วนใหญ่จะหลีกเลี่ยงไม่ให้คุณโต้ตอบข้ามขอบเขตเหล่านั้นเพราะมันเป็นการยากที่จะทำได้ดี แต่พวกเขาหันไปใช้วิธีอื่นในการทำให้ดูเหมือนว่าคุณยังคงอยู่ในชาร์ตเดียวกันและบนเซิร์ฟเวอร์เดียวกันเมื่อจริง ๆ แล้วคุณไม่ได้ เช่น. - หน้าจอการโหลดหรือภาพเคลื่อนไหวอื่น ๆ ที่ครอบคลุมการเปลี่ยนแปลงเซิร์ฟเวอร์เมื่อทำการเปลี่ยนระหว่างโซนหรือจากทวีปหนึ่งไปอีกทวีปหนึ่ง - แยกดันเจี้ยนหรืออินสแตนซ์การจู่โจมแยกจากคนอื่น สิ่งเหล่านี้เปรียบเสมือนเศษที่อยู่ภายในเศษและสามารถเรียกใช้บนเซิร์ฟเวอร์แยกต่างหากได้อย่างง่ายดายช่วยในการปรับสมดุลโหลด

ฉันไม่สามารถพูดคุยกับผู้มีอำนาจใน WoW แต่ฉันเดาว่าพวกเขากำลังทำสิ่งต่าง ๆ ข้างต้นทั้งหมด: instancing, พื้นที่ทางภูมิศาสตร์ที่แยกจากกันซึ่งไม่สามารถโต้ตอบกับพอร์ทัลบางประเภทแยกหลังและเซิร์ฟเวอร์รับรองความถูกต้อง ฉันได้ยินมาว่าอาณาจักร WoW มีบางสิ่งระหว่าง 1,000 ถึง 10,000 ผู้เล่นออนไลน์ในขอบเขตที่กำหนดในครั้งเดียวซึ่งสามารถจัดการได้อย่างง่ายดายด้วยแผนการข้างต้น

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

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

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


3

มีวิธีการมากมายในการโหลดบาลานซ์เซิร์ฟเวอร์ MMO เนื่องจากมีข้อมูลมากมายที่ต้องดำเนินการ ฉันชอบวิธี bin ต้นไม้กระบวนการ

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

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


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

รุ่นนี้ทำงานได้ดีในระบบข้อมูลที่ธุรกรรมส่วนใหญ่ถูกแยกออก ฉันหมายความว่าพวกเขามักจะไม่ทำงานกับข้อมูลเดียวกันและในกรณีที่ไม่ค่อยพบการล็อคหรือย้อนกลับถูกนำมาใช้ แต่ในเกมที่การต่อสู้รวมถึงผู้เล่นหลายคนและ / หรือสิ่งมีชีวิตและผลกระทบของการโจมตีนั้นได้รับอิทธิพลจากคุณลักษณะของทั้งผู้โจมตีและผู้พิทักษ์วิธีการนี้อาจเป็นเรื่องยาก
Hendrik Brummermann

คุณสามารถใช้วิธีที่ง่ายและพิจารณาการโต้ตอบที่มีผู้ใช้หลายคนว่ามีความเกี่ยวข้องกันทั่วโลกหรือคุณสามารถสร้างวิธีการที่ง่ายสำหรับถังขยะในกระบวนการเพื่อให้ทราบกันและสื่อสารกัน ถังขยะแต่ละกระบวนการควรสามารถรองรับผู้ใช้ประมาณหมื่นคนในคราวเดียวดังนั้นการสื่อสารระหว่างผู้ใช้ไม่ควรเป็นปัญหามากเกินไป วิธีการในภูมิภาคนั้นง่ายขึ้นเล็กน้อย แต่ไม่สมดุลเท่ากันและอาจผิดพลาดได้ง่ายหากผู้ใช้จำนวนมากเข้าสู่ภูมิภาคเดียวกัน ใน MMORPG ที่มีฐานผู้ใช้ที่สมดุลการโหลดอย่างสม่ำเสมอมีความสำคัญมาก
Stephen Belanger

ฉันชอบที่จะรู้ว่า "วิธีการง่ายๆ" สำหรับ 2 ถังขยะกระบวนการเพื่อให้สามารถเจรจาระบบเช่นการต่อสู้ ปัญหาไม่ใช่ระดับต่ำ comms แต่อัลกอริทึมการเล่นเกมโดยทั่วไปมีความซับซ้อนมากกับผู้เข้าร่วมกระจาย
Kylotan

ในการปรับใช้ของฉันเซิร์ฟเวอร์ทั่วโลกของฉันจะเก็บรักษารายการของไคลเอนต์ที่เชื่อมต่อทั้งหมดและติดตามกระบวนการที่พวกเขาเชื่อมต่อกับถังขยะ ถ้า bin กระบวนการจำเป็นต้องเข้าถึงผู้ใช้อื่นก่อนอื่นตรวจสอบรายชื่อผู้ใช้ของมันเอง หากล้มเหลวระบบจะตรวจสอบรายการส่วนกลางและระบุว่ากระบวนการใดที่ผู้ใช้รายอื่นเชื่อมต่อ กระบวนการ bins จะเชื่อมต่อโดยตรงเพื่อแชร์สถานะผู้ใช้ขณะทำการประมวลผลแบบรวม
Stephen Belanger
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.