สวัสดีครับ ผมนเรศ หรือว่า เรียกสั้น ๆ ว่า นเรศ เฉย ๆ ก็ได้
วันนี้ ผมจะมาวิเคราะห์ระบบลงทะเบียน สำหรับการฉีดวัคซีนฟรี เพื่อเป็นกรณีศึกษาครับ เนื่องจาก DomeCloud ได้เสนอตัวเพื่อทำระบบการลงทะเบียน เพื่อฉีดวัคซีนซิโนฟาร์มฟรี ให้กับจังหวัดชลบุรี โดยเป็นหนึ่งในการทำระบบเพื่อสังคม ไม่ต้องเสียค่าใช้จ่ายใด ๆ ให้ DomeCloud (ถ้ามีใครสนใจอยากสอบถาม ถามไปที่ Inbox page DomeCloud Facebook ได้เลย)
โดยส่วนตัวผมเอง ผมมักจะพูดถึงการทำระบบลงทะเบียนต่าง ๆ ที่ไม่สามารถรองรับผู้ใช้งานได้ว่า "ทำเว็บสวย ๆ แล้วใช้ไม่ได้ ทำทำไม" ซึ่งกรณีนี้อยากจะสื่อความว่า เว็บสวย ๆ ทำงาน มันก็แค่ Static file ทำให้มันล่ม ยากกว่าอีก
แต่...
แต่ การทำเว็บแบบ Static มันก็ไม่ได้ตอบโจทย์ของระบบการลงทะเบียนอะไรเหล่านี้ มันก็จริงอยู่ว่า ทำเป็น SPA (Single Page Application) มันก็ Static file นี่ ?
ใช่ แต่...
แต่อีกแล้ว คือหน้าเว็บเอง มัน Static แหละ แต่ข้อมูลมันไม่ Static โดยธรรมชาติของระบบลงทะเบียน ข้อมูลต่างๆ มันจะเก็บลงฐานข้อมูล
เข้าเรื่องเลย การออกแบบระบบนี้ อาศัยความขี้เกียจ ออกแบบระบบไว้ประมาณนี้
เราเลือกใช้ Firebase สำหรับงาน Backend เพราะว่าทำให้สามารถสร้างระบบการลงทะเบียนขึ้นมาได้ง่าย แบบ ง่ายมาก ไม่ต้องดูแล Backend ของตัวเอง มีแค่ Static file ที่เราคิดว่า ดูแลเองง่ายกว่า (เพราะว่า เคยเจอปัญหาตอนฝากไฟล์ไว้ที่ Cloudflare)
แต่พอใช้งานจริง มันไม่ง่ายอย่างที่คิด
หลังจากที่ออกแบบและสร้างมันขึ้นมาแล้ว ผมก็ได้ทำการโหลดเทสระบบ โดยเทสไปที่แค่ส่วนของ Static file หรือหน้าเว็บที่เราสร้างมา เพื่อดูว่าเราสามารถรองรับการใช้งานได้ที่เท่าไหร่
ผลโหลดเทสแรกๆเลย ตามภาพข้างบน เราใช้ Cloudflare + Proxy ที่ Cloudflare เลย ผลโหลดเทส ออกมา กระจอกมาก ได้ที่ประมาณ 2,000 Request per sec. อันนี้ ผมคิดว่าอาจจะเป็น Limit ฝั่ง Cloudflare จากนั้นนำเสนอข้อมูลการโหลดเทส ไปยังที่ประชุมว่า ได้ที่ 2,000 RPS เพราะ Cloudflare มัน Limit ไว้
แต่ที่ประชุมบอกว่ามันน้อยเกินไป ผมเลยปลด Cloudflare Proxy ให้ใช้เป็น DNS Only แล้วยิงโหลดเทสใหม่ ผลคือ ได้ประมาณ 50,000 RPS อันนี้เป็นอีกโดเมนหนึ่ง ซึ่งเป็นของ เทศบาลตำบลเสม็ด จังหวัดชลบุรี ที่ยิงไปตรง ๆ แบบ HTTP
ผลทดสอบแบบ HTTPS
จากผลการทดสอบ ทั้งของจังหวัด และเทศบาล พอจะสรุปได้คร่าวๆว่า HTTP เรารับได้มากกว่า 50,000 Request per sec. แน่ๆ และ ถ้าเรา Terminate HTTPS เอง จะได้ราวๆ 20,000 Request per sec.
ตัวเลขทั้งสองค่า ทั้ง HTTP, HTTPS ผมค่อนข้างพอใจกับตัวเลขนี้ คิดว่า คนจังหวัดชลบุรี ไม่น่าจะใช้เกินนี้ เลยสรุปกันกับทีมว่า จะใช้ Cloudflare เป็น DNS Only เท่านั้น เพราะที่ประชุมเห็นตัวเลขว่ารับได้มากกว่า
การโหลดเทส ทีมไม่ได้โหลดเทสไปยัง Firebase เพราะเราเชื่อว่า Google จะสามารถรองรับผู้ใช้งานให้เราได้ เราใช้ Firebase Realtime Database ในการเก็บข้อมูล และเช็คว่ามีการลงทะเบียนครบหรือยัง ถ้าครบแล้วจะปิดการลงทะเบียนอัตโนมัติ
จากการออกแบบ ที่ความไว้ใจ Firebase เราก็ชะล่าใจไประดับหนึ่ง แต่ก็คิดว่า ยังไงมันก็อาจจะเกินโควต้าฟรีของ Firebase ก็เลยไปเพิ่มแพลนของ Firebase เป็น Pay as you go...
วันที่ระบบขึ้นใช้งานจริง ตอนวันที่ 12 สิงหาคม 2564 เวลาท้องถิ่น 09:00 น. ผมซึ่งคืนก่อนหน้า นั่งทำระบบ Logging Server ไปนอนตอนตีห้า ป่าน น้องในทีมแชทมาว่า ระบบเริ่มหน่วง ผมก็คิดว่า ไม่น่าจะมีปัญหาอะไร เลยตอบแชทไปและนอนต่อ
ผ่านไปไม่ถึงห้านาที ป่านโทรมา บอกว่า ล่มแล้ว หน่วงมาก ใช้งานไม่ได้ ผมลุกจากที่นอนทันที จากนั้นสิ่งแรกที่ทำคือ ให้ Cloudflare Proxy และแคชให้ด้วยเลย
แต่ว่าเจอปัญหาต่อมา
เราเชื่อใน Cloudflare มากว่า มันเก่ง แต่ลืมคิดไปว่า มันก็มี Limit ของมัน พอผมเจอปัญหานี้ เลยกดจ่ายเงินไป (ตัดบัตรพี่โดม 5555) สำหรับ Pro Plan ราคา $20 ต่อเดือน แต่ว่า เกิดปัญหาขึ้นว่า ตัว Cloudflare เอง มันแคช Dashboard มันเองด้วย (สัส คิดในใจ) ผมคิดว่า แย่ละ Pro Plan ไม่เพียงพอ เลยกดเพิ่มเป็น Biz Plan บวกเพิ่มไปอีก $200 ต่อเดือน (รวม $220 ที่กดไป)
หลังจากกดไปแล้ว มันเหมือนเดิม... เอ๊ะ...
เอ๊ะะะะะ ?
อีหยังวะ ทำไม Cloudflare มันไม่อัปเกรดให้
ระหว่างนี้คือ ผ่านไปราวๆครึ่งชั่วโมง (ณ 09:30) ผมยังคงเห็น Cloudflare return 503 กลับมาว่า ติด Rate Limit อยู่เลย จากนั้นก็ได้รับแจ้งมาว่า คนลงทะเบียนครบแล้ว คือ รอบแรก จะให้ลงทะเบียนราวๆ 25,000 คน มั้ง ประมาณนั้น แต่ พอคงลงเต็มไปแล้ว ระบบยังได้รับข้อมูลเข้ามาเรื่อยๆ จบที่ราวๆ 30,000 คน
จากกราฟ จะเห็นว่าตอนช่วงเริ่มเปิดให้ลงทะเบียน จะมี Request พุ่งไปที่ประมาณ 150,000 Request per sec. ซึ่งมากกว่าที่เราโหลดเทสราวๆ 3 เท่า (โหลดเทสที่ 50,000 request per sec)
ผลก็คือ หน้าเว็บมันไม่แสดงผลแบบสมบูรณ์ แต่ว่า ใช้ cURL ทดสอบเรียกหน้าเว็บจะได้ 200 OK นะ แต่ว่า เราออกแบบหน้าเว็บไว้ให้เช็คว่า ลงทะเบียนครบหรือยัง ทำให้ยังมี Request ไปที Firebase Realtime Database อยู่
ซึ่งตัว Firebase เอง มันคิดค่า Data Transfer ด้วย!
เหี้ย! แล้วเรา! โดน Data Transfer ไปราวๆ 3.5 TB คิดเป็นเงินราวๆ $3,500 หรือ ราวๆ 115,000 บาท โดยประมาณ จากการเปิดใช้งานระบบ 1 ชั่วโมง
ข้อมูลจาก Cloudflare
ปัญหา
ปัญหาที่เราเจอคือ จาก Cloudflare มาหา Origin Server ของเรา Bandwidth เต็ม... เราเลยให้ Cloudflare Cache ให้ แต่ว่า ปัญหามันไม่ได้จบที่ตรงนั้น หลังจากโหลดไฟล์ไปครบจากฝั่ง Cloudflare แล้ว ปัญหาต่อมาคือ Firebase Realtime Database มัน Response ช้า ทำให้หน้าแรกโหลดไม่สมบูรณ์เพราะ รอข้อมูลจาก Firebase ซึ่งเราทำอะไรไม่ได้เลย ณ เวลานั้น
สรุป
Firebase ใช้งานได้ดี ถ้าไม่ได้ใช้มากจนเกินไป แต่การเขียน Query ฝั่ง Firebase ต้องคำนึงถึง Data Transfer ด้วย เพื่อลดค่าใช้จ่ายที่จะเกิดขึ้น
แผนต่อไปของการลงทะเบียนผมได้ออกแบบแนวทางไว้แล้ว 2 ทาง ไว้จะมาเล่าต่อรอบหน้า
Top comments (1)
คำถามครับ
ทำไมไม่ใช้ firebase authentication + fire store