คลังเก็บหมวดหมู่: AWS

โม้เกี่ยวกับ Amazon S3, Amazon EC2, Amazon SimpleDB และ Amazon RDS

การติดตั้ง Web Application บน Infrastructure แบบเปิด

หลายคนเขียน Web Application เป็น, หลายคนเขียนเกมแบบ Web Application ได้ และหลายคนก็เขียน Web Application ไว้ทำงานบน Facebook Platform ได้ แต่ก็ไม่น่าเชื่อว่ามีอยู่หลายคนที่กลับไม่รู้ว่าจะจัดวาง Infrastructure ให้กับ Web Application ของตนเองยังไงดี เพื่อให้ผู้ใช้งานจากทั่วทุกสารทิศในโลกกลม ๆ ใบนี้ เข้าถึง Web Application ที่ตัวเองสร้างขึ้นได้!!!

งั้นมาดูวิธีของผมกันดีกว่า เอาแบบจากประสบการณ์จริงกันไปเลย

  1. ต้องเลือกก่อนว่าจะเอา Web Application ของเราไปขับเคลื่อนที่ไหน อย่างกรณีของผม ผมใช้บริการ Cloud Computing ของ Amazon Web Services เป็นตัวจัดการเรื่องนี้ โดยเน้นใช้งานแต่บริการของ Amazon EC2 เพื่อเอามาทำเป็น Instance Server จำนวน 2 Instance ให้ Instance นึงไว้ขับเคลื่อน Application และอีก Instance นึงไว้ขับเคลื่อน Database โดยผมเลือกใช้งานโซนแคลิฟอร์เนียเหนือ และเลือกใช้ Image แบบ LAMP หมายเลข ami-1d6a3858 ซึ่งเป็น LAMPStack ที่มีระบบปฏิบัติการเป็น Ubuntu รุ่น 10.04 แบบ 32 bit สอดไส้ด้วย PHP รุ่น 5.3 มี Virtual Core 1 ECU และ RAM 1.7 GB (เล็กชิบเป๋ง)
  2. จากนั้นก็โยนโค้ดไว้ที่ Application Instance และโยนฐานข้อมูลไปไว้ที่ Database Instance โดยที่ Database Instance จะพิเศษหน่อย เพราะผมจะไม่ใช้เนื้อที่ของ Database Instance เพื่อเก็บฐานข้อมูล แต่จะใช้ Amazon Elastic Block Store ที่ผมผูกไว้กับ Database Instance เป็นตัวเก็บข้อมูลแทน
  3. พอได้ขุมพลังในการขับเคลื่อนและได้ทำการเชื่อมโยง Application Instance กับ Database Instance ผ่านการ Configure อะไรหลาย ๆ อย่างแล้ว ทีนี้ก็ต้องมาดูเรื่อง Domain บ้าง โดยผมได้จดโดเมนเอาไว้ก่อนเรียบร้อยแล้วที่ Go Daddy
  4. คราวนี้ก็ต้องเอา Domain ที่จดทะเบียนไว้ ไปผูกโยงเข้ากับ Application Instance ที่เตรียมเอาไว้ก่อนแล้ว โดยผมได้เลือกใช้บริการของ Dynamic DNS แบบ Custom DNS Package จากนั้นก็ Configure ไำอ้เจ้า CNAME กับ A-Records เพื่อเชื่อมโยงระหว่างชื่อ Domain กับเลข IP ของ Application Instance เข้าไว้ด้วยกัน
  5. และท้ายที่สุด ก็ต้องกลับไป Configure ที่ Go Daddy เพื่อบอกให้มันรู้ว่า ตกลง Domain ที่ผมจดทะเบียนไว้ มันเชื่อมโยงไปยัง Primary Name Server ใด ซึ่งในที่นี้ก็คือ Primary Name Server ของ Dynamic DNS นั่นเอง โดยผมใส่ลงไป 5 Name Server เลย ใช้มันให้คุ้ม ทำ Load Balancing แบบเว่อร์ ๆ เพราะผมเสียดายมาก เนื่องจาก Package ที่จ่ายตังค์ไป มันเปิดให้เรากำหนด DNS ได้ถึง 75+ Domain แต่ประทานโทษ ผมใช้มันสำหรับ Domain เดียว โคตรเสียดายตังค์เลย T-T

เมื่อเราทำมาถึงขั้นตอนนี้ ก็ถือว่าทุกอย่างเรียบร้อยหมดแล้ว คราวนี้เราก็จะสามารถลองใช้งาน Web Application ของเราได้ โดยการเปิด Web Browser แล้วพิมพ์ URL ของ Domain เราเข้าไป แล้วรอซักชั่วอึดใจมด จากนั้น Web Application ของเราก็จะปรากฎขึ้นมา … อย่างสวยงามเลยทีเดียวเชียว!!!

เอาเป็นว่าใครก็ตามที่ยังไม่รู้ ก็คงได้รู้แล้วเน้อะ อ้อ แล้วอีกอย่าง สิ่งที่ต้องรู้อีกอย่างหนึ่งก็คือ ไอ้ข้างบนที่ผมเล่ามา มันต้องเสียตังค์ด้วยอ่ะ T-T แพงซะด้วยสิ ดังนั้น ถ้าคิดจะขับเคลื่อน Web Application แล้วล่ะก็ อย่าลืมหาตังค์มาเลี้ยงมันด้วยเน้อ

ทำงานคนเดียว มันทำได้ แต่เสร็จช้า

ผมยังคงง่วนอยู่กับการทำเกม Beelony สำหรับเล่นบน Facebook อยู่ครับ ทำมาตั้งแต่เดือนกันยายน 2553 จนวันนี้จะหมดเดือนมิถุนายน 2554 แล้ว ก็ยังเอาขึ้นใช้จริงไม่ได้อยู่ดี เพราะช่วงที่ผ่านมาผมต้องเสียเวลาไปหลายอย่าง ไม่ว่าจะเป็น …

  • การประเมินและทดสอบ Instance บน Amazon EC2 ว่าต้องใช้กี่ตัว แล้วก็ใช้ Instance ระดับไหนดี ถึงจะตอบสนองกับตัวเกมได้โดยจ่ายตังค์น้อยที่สุด
  • การทำ Configuration Note เพื่อเอาไว้จัดการกับ Amazon EC2 ในกรณีที่ต้องเปลี่ยน Instance เพื่อควบคุมต้นทุน โดยให้การเปลี่ยน Instance และ Configure เสียเวลาน้อยที่สุด
  • การทำ Backdoor ให้กับตัวเกม เพื่อให้ข้ามขั้นตอนในการทดสอบได้ ซึ่งเดิมไม่ได้ทำเอาไว้ ทำให้ต้องทดสอบหูตาเหลือก กว่าจะไปถึงจุดที่อยากจะทดสอบจริง ๆ ได้
  • การหา Bug ทั้งหลายทั้งปวงที่ยังคงหลบซ่อนอยู่ในตัวเกม โดยเฉพาะตอนที่ผู้เล่นเข้าใช้ทรัพยากรแหล่งเดียวกัน
  • การซ่อมแซมคุณสมบัติของเกม ที่เล่นแล้วทำให้ไม่ลื่นไหล ขัดหูขัดตา ไม่อำนวยความสะดวก
  • การเปลี่ยนกลไกจาก PayPal มาเป็น Facebook Credits เพื่อหาเงินมาหล่อเลี้ยงตัวเกม
  • การเพิ่มคุณสมบัติดึงดูดใจ ที่ทำให้ผู้เล่นไม่รู้สึกว่ากำลังเล่นเกมที่เล่นสบายหรือเล่นยากจนเกินไป

ผ่านมาจะปีนึงแล้ว ผมผลิตชิ้นงานให้กับเกมนี้ไปเป็นจำนวนมาก นับได้เป็นจำนวนเกินร้อยไฟล์ ไม่ว่าจะเป็นการโค้ด PHP + jQuery + CSS, การวาดรูป, การทำเอกสาร Configuration, การทำ Mockup, การทำ Prototype, การทำ Tools เสริม, การทำเอกสารออกแบบฐานข้อมูล, การเตรียมข้อมูลหลักสำหรับบรรจุในฐานข้อมูล เป็นต้น

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

การทำเกมเป็นงานอดิเรก มันทำคนเดียวได้ แต่มันเสร็จช้าว่ะ แย่จริง ๆ นี่แหล่ะถึงเป็นเหตุผลว่าทำไมเขาต้องทำเป็นธุรกิจ เพราะมันจะได้เสร็จเร็ว ๆ ไง!!!

ใช้ Facebook Credits

ด้วยนโยบายอันเข้มงวดเด็ดขาดและโลภของ Facebook ซึ่งกำหนดให้ผู้พัฒนาเกมบน Facebook ต้องใช้ Facebook Credits เพื่อเป็น “เงินตราเสมือนจริง” หรือ “วิธีการชำระเงิน” บน Facebook แต่เพียงช่องทางเดียว จึงทำให้เกิดความเดือดร้อนเล็ก ๆ แก่ผู้พัฒนาเกมบน Facebook ที่จำต้องเปลี่ยนแปลง “วิธีการชำระเงิน” ของตัวเอง มาใช้ Facebook Credits แทน รวมทั้งความเดือดร้อนใหญ่ ๆ ที่ต้องจ่ายส่วยให้กับทาง Facebook ด้วย!!!

ผมเองก็ต้องเปลี่ยนกลไกของเกมของผมเหมือนกัน คือเปลี่ยนจาก “วิธีการชำระเงิน” ด้วย PayPal มาเป็น Facebook Credits โดยขอคงสิทธิ์ของ “เงินตราเสมือนจริง” ในเกมของตนเองเอาไว้ ไม่ใช้ Facebook Credits เพื่อเป็น “เงินตราเสมือนจริง” แต่ประการใด!!!

ทีนี้โดยทางเทคนิคต้องทำยังไงบ้างล่ะ? ก็ต้องโยนโค้ดที่ใช้เชื่อมโยงกับ Web Services ของ PayPal ทิ้งไปสินะ แล้วจากนั้นก็เชื่อมโยงกับ Facebook Credits ผ่านทาง SDK (Javascript + PHP) ที่ทาง Facebook จัดเตรียมเอาไว้ให้ พร้อมทั้งเข้าไปอ่านเอกสารของ Facebook เพื่อทำความเข้าใจว่ากลไกของ Facebook Credits อ่ะมันเป็นยังไง

Facebook เองก็ทำ Flowchart เพื่ออธิบายกลไกให้เราเข้าใจ Facebook Credits เอาไว้บ้างเหมือนกัน แต่ประทานโทษอ่ะ มันไม่เห็นจะสอดคล้องกับความเป็นจริงในทางเทคนิคของโค้ดโปรแกรมเล้ย ดังนั้น ผมก็เลยต้องวาดเพื่อทำความเข้าใจเอง แบบข้างล่างนี้

Facebook Credits

และนอกจากนี้ ผมยังได้พบจุดสังเกตในทางเทคนิค เกี่ยวกับ Facebook Credits อีกหลายอย่าง ไม่ว่าจะเป็น …

  • ไม่ว่าผู้เล่นจะซื้อหรือไม่ซื้อของ Facebook ก็จะสร้างหมายเลข Order ให้ ถ้ามีการร้องขอ Dialog จาก Facebook
  • Facebook Credits API จะส่งข้อมูลที่ไม่ถูกเข้ารหัสมาหนึ่งชุด และข้อมูลที่ถูกเข้ารหัสมาอีกหนึ่งชุด กลับมาที่ Callback ของเรา (ภายหลังจากการร้องขอ Dialog) และเมื่อนำข้อมูลชุดที่สองที่ถูกเข้ารหัสมาถอดรหัสออก เราจะพบว่าข้อมูลที่ได้มันเหมือนเป๊ะกับชุดที่หนึ่งที่ไม่ถูกเข้ารหัสเลยว่ะ ซึ่งก็หมายความว่า Facebook จะให้เราตรวจสอบนั่นเอง ว่าเรากำลังโดน Hack หรือเปล่า โดนโกงโดยการปลอม JSON หรือเปล่า อะไรประมาณนี้
  • ตอนวาง Order ผ่านมาเป็น Callback เข้า PHP แต่ตอนจบ Order ดันผ่านมาเป็น Callback ใน Javascript แหม ทำได้ยอกย้อนจริง ๆ
  • ต้องไม่เขียนโค้ดให้เว่อร์เกินกว่าที่ Facebook Credits API กำหนดไว้ ยกตัวอย่างเช่น ถ้าเขาให้กำหนด Callback เป็น Function แยกต่างหาก ก็ต้องทำตามเขา อย่าบ้าพลังไปผนวก Callback เข้ากับ Function ที่จะเรียกมัน หรือพูดง่าย ๆ ก็คือ Facebook Credits API มันยังอ่อนแออยู่ ยังมีจุกจิกปัญหาเล็ก ๆ น้อยอยู่

Beelony รุ่น Alpha แบบจัดเต็ม

ถ้าเราเล่น Beelony ไปเรื่อย ๆ ก็จะได้รวงเยอะ ๆ เหมือนในภาพข้างล่างนี้ บวกกับไอเท็มอีกเยอะแยะที่จะผลิตได้ ซึ่งมันเยอะเลยขี้เกียจจะนับ T-T

แต่ถึงมันจะเป็นรุ่น Alpha แต่มันก็มีคุณสมบัติใกล้เคียงกับตัว Production นะเอ้อ

วิธีใช้ Amazon EC2 แบบยืดหยุ่น

คิดว่าคงมีหลาย ๆ คนที่เข้าใจแนวคิดว่า Amazon EC2 เป็นบริการ Cloud Computing ซึ่งเป็นอะไรที่ยืดหยุ่น ขยายได้ หดได้ ตามการใช้งานของเรา

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

งั้นมาดูแก่นแท้ของวิธีใช้ Amazon EC2 ที่ยืดหยุ่นกันจริง ๆ กันดีกว่า …

จากภาพข้างบนจะเห็นว่า วิธีออกแบบเพื่อใช้งาน Amazon EC2 ที่ดูที่สุด คือการออกแบบให้แต่ล่ะชิ้นส่วน “แยกจากกัน”

โดยเราต้องมองว่า กระดูกสันหลังหลักที่ทำให้ Amazon EC2 ยืดหยุ่นก็คือ Instance ซึ่งเราสามารถเลือกได้หลายระบบปฏิบัติการ เช่น อาจเป็น Linux หรือ Windows, เลือกได้หลายสมรรถนะ เช่น เอา RAM เยอะ ๆ หรือเอา CPU เยอะ ๆ หรือเอาทั้งสองอย่าง

ดังนั้น ถ้าส่วนของ Instance คือส่วนที่เราต้องเปลี่ยนไปเปลี่ยนมาบ่อย ๆ ตามขนาดการใช้งานของเรา งั้นเราก็ไม่ควรจะเอา Script หรือ File อื่น ๆ หรือ Database (ซึ่งก็คือชุดของ File นั่นแหล่ะ) ไปวางไว้ใน Instance ที่จะทำเป็น Web Container หรือ RDBMS หากแต่ใช้วิธีวางไว้ใน Elastic Block Storage แล้วทำการ Mount ไอ้เจ้า Elastic Block Storage เข้ากับ Instance โดยให้มันมองเห็นเป็น Device นึงแทน (เหมือน External Hard Disk)

จากนั้นก็เข้าไปที่ Apache เพื่อ Configure ให้อ่าน Script จาก Device ที่ Mount เข้ามาใหม่ และเข้าไปที่ MySQL เพื่อ Configure ให้อ่าน/เขียน Databases จาก Device ที่ Mount เข้ามาใหม่ ซึ่งอาจจะเป็นที่เดียวกับ Script หรือคนล่ะที่ก็ได้ อันนี้แล้วแต่เราจะออกแบบ

โดยส่วนตัวผมมองว่าภาพข้างบนเป็นพื้นฐานของสิ่งที่ควรจะเป็น สำหรับระบบที่จะมีคนเข้าใช้งานประมาณซัก … 30,000 คนต่อวัน โดยมีการใช้งานพร้อมกัน 300 คนต่อช่วงเวลา!!!

อือม แต่เอาเข้าจริงแล้วก็ไม่แน่นะ อาจจะใช้ของน้อยกว่านี้ก็ได้ อันนี้แล้วแต่ความเก๋าของแต่ล่ะคน เช่น อาจจะเอา Apache, PHP และ MySQL ไว้บน Instance เดียวกัน แล้วเปิดใช้งาน Elastic Block Storage อันเดียว เพื่อเอาไว้ใส่ทั้ง Script และ Database แล้วพอวันดีคืนดีระบบรับไม่ไหว ก็ค่อยมาขยายกันอีกทีทีหลัง อะไรประมาณนี้

หุ ๆ คนเราอ่ะนะ ถ้าได้ของฟรี ๆ มาใช้ คงไม่ต้องใช้สมองคิดขนาดนี้หรอกเน้อะ?