0148 | Concept ระบบจองตั๋ว
Sunday, February 17th, 2013 Posted in Database, PHP Coding, Web Server | No Comments »จากกรณีเดี่ยวสิบระบบจองล่มอนาถ… ในหัวเลยลองร่างๆ ระบบ ticketing system ไว้อยู่พอประมาณครับ เงื่อนไขที่ร่างไว้ก็ประมาณนี้
ไม่รู้ทำจริงจะเน่ามั้ยนะ (ฮา) ออกแบบในหัวมาคร่าวๆ ยังไม่ได้ลงรายละเอียดเลยครับ ไม่รู้จะติดปัญหาอะไรยังไงบ้าง
- เร็ว : แน่นอน ระบบต้องเร็วพอที่จะไม่ต้องเสียเวลารอในแต่ละขั้นตอนมาก
- ชัวร์ : ล็อกที่นั่งระหว่างทำรายการได้ชัวร์จนกว่าจะ expire // ไม่อนุญาตให้เกิดการทำรายการจองที่นั่งซ้ำ
- ปล่อยได้ : ที่นั่งที่ล็อกไว้รอทำรายการต้องมีกำหนด expire ถ้าทำรายการไม่เสร็จตามระยะเวลาก็ให้กลับคืนมาให้ระบบ
- realtime : รายการผังที่นั่ง stream ดูกันสดๆ ได้เลยว่าที่นั่งไหนอยู่ในสถานะไหน (ajax streaming)
ส่วนประกอบของ service ก็จะได้ประมาณนี้
- WebUI : ส่วนหน้าจอติดต่อ client อาจเป็น rest api หรือ full web เลยก็ได้
- Payment Gateway Interface : ส่วนคุยกับระบบจ่ายเงิน (บัตรเครดิต, paypal, อื่นๆ)
- Locking Services : เป็น In-memory service ที่ทำหน้าที่เก็บสถานะที่นั่งไว้ในแรม
- Database : เอาไว้เก็บตัว transaction และ state จริงๆ ของที่นั่ง
ที่คิดไว้… ฝั่ง WebUI กับ Payment Gateway Interface นี่เขียนภาษาอะไรก็ได้ครับ ไม่ strict ส่วน locking service เป็น nodejs เนื่องจากต้อง listen http สำหรับ streaming ข้อมูลการ lock ที่นั่งส่งไปให้ client ด้วย … ส่วน database อยากใช้อะไรก็ใช้ไปฮะ
- locking service สามารถรัน 1 zone ต่อ 1 หรือหลายรอบการแสดงได้ (แต่ไม่สามารถรันหลาย zone ต่อ 1 รอบการแสดงได้ เพราะจะทำให้มีโอกาสที่จะ lock ชนกัน) ทันทีที่รันให้โหลดข้อมูลผังที่นั่งและสถานะที่นั่งแต่ละที่จาก database มา map ไว้รอเลย
- webui จะให้เลือกรอบการแสดง (ข้อมูลนี้ cache ได้ เพราะงั้นเข้าไม่ถึง database) แล้วจะไป fetch ข้อมูลผังที่นั่งจาก locking service พร้อมเปิด ajax streaming connection ทิ้งไว้เพื่อ update ผังที่นั่งสดๆ
- พอ client คลิกยืนยันที่นั่งที่เลือก webui จะยิงคำสั่ง lock ไปให้ locking service
- locking service จะ mark ที่นั่งนั้นเป็น pending payment ทันที พร้อมระบุเวลาที่ทำการ mark ด้วย โดยทำการ async save ลง database ด้วย พร้อม broadcast หา client ทุกตัวที่เชื่อมต่ออยู่ให้รู้ว่าที่นั่งนั้นๆ ไม่ว่างแล้ว
- ถ้า locking service mark ที่นั่งไม่ผ่าน (update ชน หรือมี client ยิงคำสั่งที่นั่งมาชนกันพอดี) ให้แจ้งคนที่มาทีหลังว่าที่นั่งไม่ว่าง แล้วยิงให้ webui refresh ที่นั่งใหม่
- webui เก็บข้อมูลอื่นๆ ของผู้ซื้อบัตร แล้ว redirect เข้า payment gateway ที่เจ้าตัวเลือก
- ถ้าเป็น offline payment อย่าง counter service / atm / bill paymetn ก็ให้ยิงคำสั่งไปบอก locking service อีกรอบเพื่อแก้ไขสถานะเป็น offline payment required เพื่อไม่ให้ที่นั่งหลุด
- ส่วน online payment ก็ทำรายการต่อไปจนจ่ายเงินสำเร็จ ยืนยันยอดเสร็จ webui ก็ update transaction ลง database ไปเลย แล้วยิงคำสั่งบอก locking service ว่าที่นั่งจองเรียบร้อยแล้ว ขึ้นสถานะเป็น complete ได้ หรือถ้า transaction fail ก็ยิงไปบอกให้ unlock ที่นั่ง
- locking service ต้องทำ timer รอไว้ (setTimeout) สำหรับที่นั่งที่เพิ่ง mark pending payment ว่าภายใน X นาทีถ้ายังไม่เปลี่ยนสถานะให้ unlock ที่นั่ง <– อันนี้ต้องการความสามารถของ node.js เต็มๆ
สรุปแล้ว ทั้งระบบจะมี query database ประมาณนี้
- ตอน start locking service ครั้งแรก query หาผังที่นั่ง + สถานะที่นั่ง
- ตอนคนเลือกรอบการแสดงครั้งแรกๆ ที่ยังไม่ติด cache
- locking service update สถานะที่นั่งเข้าฐานข้อมูล (free, pending payment, offline payment, completed)
- webui update ข้อมูลลูกค้า
- webui update ข้อมูล transaction
ต่อ 1 การจองก็จะมี query สามอันหลัง ประมาณ 7-8 query โดยไม่จำเป็นต้องทำ lock ที่ฝั่ง database ให้ระบบค้างเลย
จุดอ่อนใหญ่สุดของระบบนี้อยู่ที่ตัว locking service ที่ถ้ามันล่มก็จะจองตั๋วในรอบนั้นไม่ได้เลย รองลงมาก็การที่ยังต้อง query เข้า database เกือบสิบครั้งต่อ 1 การทำรายการจองซึ่งอาจเกิดคอขวดที่ database ได้ อาจแก้ได้ด้วยการแยก database ข้อมูลลูกค้ากับข้อมูลการจองออกจากกัน (สิ้นคิดมาก 555)
0109 | Cloud Web Hosting
Saturday, August 28th, 2010 Posted in Database, IP Network, Linux, Web Server | 3 Comments »บทความต่อไปนี้เป็นเพียงการทดสอบทฤษฎี หรือ Proof of Concept เท่านั้น ยังทดสอบใช้งานจริงไม่ผ่านด้วยสาเหตุทั้งปวง
เป้าหมายคือสร้างโฮสติ้งที่ล่มยากๆ และรองรับงานได้ปริมาณมากครับ
(โลภมากเนาะมึงนี่)
ฝั่ง web server ตรงนี้เป็น cluster ย่อมๆ เลย network ใช้ Virtual IP แต่ทำงานแบบ Dual Mode คือทุกเครื่องจะมีทั้ง Active VIP และ Standby VIP
โดยที่ Active VIP ของเครื่อง 1 จะเป็น Standby VIP ของเครื่อง 2 อย่างนี้ไปเรื่อยๆ
แล้วใช้ glusterfs ทำ replicate เก็บข้อมูล สามารถยัด node เพิ่มได้เรื่อยๆ ถ้าต้องการพื้นที่เพิ่ม
ปัญหาอย่างเดียวที่เจอตอนนี้คือ database ครับ … มัน… ทำงานพร้อมกันแบบ active-active ไม่ได้ T_T
ไม่สามารถใช้ master-master replication ได้ด้วยสาเหตุบางประการ เวลา master ล่ม จะ promote slave ขึ้นมาเป็น master แทนทันที
สามารถสลับเครื่องไปมาตลอด แต่ใช้ ip เดียว วิ่งผ่าน Virtual IP อันนึงครับ
อันนี้เขียน script ช่วยสลับเครื่องเพิ่มเติมไว้ด้วย ยังไม่รู้ว่าใช้งานจริงแล้วจะเน่าอนาถขนาดไหน
สรุป software ที่ใช้ (ในชุดทดสอบ)
– Linux CentOS 5.5 x86_64
– Apache 2.2 / PHP 5.2 / MySQL 5.0
– UCARP (Redundant Network Protocol)
– GlusterFS 3.0.5 (Distributed Storage Engine)
– Plesk 9.5 (Web Hosting Control Panel) ==> Concept ยังไม่ได้ทดสอบใช้งานจริง
จำนวนเครื่องในระบบขั้นต่ำ 4 เครื่อง แบ่งเป็น
– Web Server + Storage 2
– Database 2
ถ้าให้ดีขึ้นก็จับแยก storage ออกมาหน่อยจะดีมาก ด้านล่างเป็น diagram คร่าวๆ ครับ
Tags: carp, cluster, glusterfs, high availability