วันนี้เราจะมาเจาะลึก Service แรกของ Vultureprime นั่นก็คือ ImageXYZ ( Resize as a Service ) ขอเรียกแบบนี้เลยแล้วกัน 😆 Website สำหรับการ Resize รูปภาพจาก format ต่างๆให้เป็น Webp format เพื่อให้เหมาะแก่การพัฒนา web application ที่เราเปิดให้ทุกคนได้ใช้งานได้ฟรี บทความนี้เราจะมาพูดถึง Tech- Stack ที่เราหยิบมาใช้พัฒนาตัว ImageXYZ ว่าใช้ Tools อะไรบ้าง มีการออกแบบ Architect อย่างไร และเราสามารถรองรับ Workload ที่เข้ามาได้ระดับไหน วันนี้เราจะพาทุกคนไปสอดส่องและเจาะลึกในแต่ละจุด
Architecture Overall ก่อนอื่นจะขอเล่าถึงแนวคิดและความตั้งใจการออกแบบตัว ImageXYZ ของเราก่อนว่ามีสิ่งที่เราอยากได้ออกมาอย่างไรบ้าง และมันจะตอบโจทย์ทั้งผู้การงาน และการดูแลของเราอย่างไร
Light weight — “เบาและเข้าถึงได้เร็ว” ให้ผู้ใช้งานโหลดหน้าเว็บได้อย่างรวดเร็ว และเมื่อไฟล์เราเล็กก็จะทำให้เข้าถึงได้ในทุกความเร็ว internet Save Cost — ประหยัดการใช้งาน Data ของลูกค้ารวมไปถึงประหยัดค่าใช้จ่ายในการ Hosting ของเราด้วย All time Availability — ความตั้งใจของเราคือลูกค้าต้องใช้งานได้ตลอดเวลาไม่ว่าจะอยู่ที่ไหนในโลก และ Service ของเราต้องไม่ล่ม Easy to take care — ดูแลผู้ใช้งานได้อย่างเต็มที่ รวมไปถึงดูแลระบบได้อย่างง่าย Response Quickly — ได้ผลลัพท์อย่างรวดเร็ว Infrastructure — “ที่ตั้งรกราก” Cloud ☁️
AWS — เป็น Cloud ที่เราเลือกใช้งาน โดย service ที่เรานำมาใช้เป็น infrastructure ของ ImageXYZ นั้น เป็น service ที่เป็น serverless ทั้งหมด ทำให้เราประหยัดค่าใช้จ่ายไปได้อย่างมากเลยทีเดียว Frontend — “หน้าบ้านของเรา” User Facing
NextJs — เราเลือกใช้งาน Nextjs (React-Framework) ในการพัฒนา Website ทั้งหมด และใช้ความสามารถในการ Build และ Export Static File ไปเพื่อนำไปใช้ในการ Hosting ต่อ Languages
TypeScript/Javascript — เป็นภาษาหลักที่เราใช้ในการพัฒนาตัว Website ของเรา HTML, CSS — อีกภาษาหนึ่งที่ขาดไม่ได้ในการพัฒนา frontend Serve Static Content
Amazon S3 — ใช้สำหรับ Serve static content ที่เราได้ทำการ Build ออกมา เพื่อให้บริการผู้ใช้งานของเรา ซึ่งความสามารถในการทำ Static Hosting ของ S3 เป็นส่วนที่ช่วยให้ความตั้งใจของเราประสบความสำเร็จอย่างมาก Edge Network
Cloudflare — ใช้เป็น CDN รวมถึงเป็น Domain management ของ Web Application ของเรา แล้วก็ยังช่วยจัดการเรื่องการทำ caching ทำให้ web ของเราเข้าถึงได้อย่างรวดเร็ว Backend — “The only 1 function” Languages
Python — เป็นภาษาที่เราเลือกใช้ใน backend เนื่องการเราต้องการความสามารถในการทำ image processing เป็นซึ่ง Python จะตอบโจทย์ในจุดนี้มากที่สุด และ Library ที่ใช้เป็นหลักคือ OpenCV นั้นเอง Function as a Service
Lambda Function — เราเลือก lambda function เป็น service ในการ deploy function backend ของเราที่มีหน้าที่ในการ process รูปภาพที่ได้รับเข้า ซึ่ง ImageXYZ มีเพียงแค่ function นี้ตัวเดียวเท่านั้น Gateway
Amazon API Gateway — เป็น API Gateway ที่เราใช้สำหรับเป็น api endpoint ในการ communicate ไปยัง lambda function ที่เป็น backend A lot of tools — “ตัวช่วยที่แสนดี” CI/CD Tools
Amazon CodeBuild — เราทำมาทำ pipeline ในการ build และ deploy fontend อย่างอัตโนมัติ ที่เรานำมาทดลองใช้แบบไม่ถูก Practice เท่าไหร่แต่ก็ทำงานได้ดีนะ Jenkins — Tools หลักที่จะนำมาเป็นตัวทำ pipeline สำหรับการ build และ deploy service ต่างๆของเราในอนาคต Collaborate
figma — Prototype collaborate tools เอาไว้ทำงานร่วมกันกับ UX/UI Designer User Feedback Tools
Sleekplan — pluging ที่เอามาช่วยในการเก็บ user feedback ที่ implement กับ Frontent ได้ง่ายมาก Logging and Monitoring
AWS Cloudwatch — Cloudwatch เป็น service ที่เราหยิบใช้ในการเก็บ Logs และ Monitor การทำงานของ service ของเรา เป็น centralize logs ที่ใช้ในการเก็บข้อมูลและยังมี tools ที่นำ logs กลับมาวิเคราะห์ได้ง่ายอีกด้วย ImageXYZ ทำงานอย่างไร สิ่งที่เราต้องการอย่างแรกเลยก็คือเราอยากทำ resize image service แต่ว่าเราไม่อยากเก็บรูปภาพ ซึ่งจะเห็นว่าการออกแบบ architech ของเรา ไม่มี service ไหนที่เอาไว้เก็บ input ของผู้ใช้งานเลย หลักการทำงานของ service เราคือ
เมื่อผู้ใช้งาน Upload รูปภาพเข้ามาจะถูกแปลง Data ให้กลายเป็น binary โดยทันที เราจัดเก็บ data ไว้ใน temp ของ Lambda Function เพื่อเตรียมสำหรับ process เท่านั้น ทำการ Process data ให้เป็นไปตาม Output ที่ผู้ใช้งานต้องการ ทำการ Compress และคืนออกไปเป็น .zip และ Download ให้อัตโนมัติ ทั้งหมดจบภายใน 1 function โดยที่เราไม่ต้องการ storage อื่นๆเลย ไม่จำเป็นต้องเก็บ data ไว้และมา clear ทิ้งทีหลัง เมื่อ Lambda จบการทำงาน data ก็จะถูกลบไปทันที
ข้อดี — “สิ่งที่เราได้จากการ desgin ระบบในรูปแบบนี้” ทางเราไม่ต้องจัดเก็บข้อมูลของผู้ใช้งานทำให้ประหยัด Storage ผู้ใช้งานสบายใจได้ว่าจะไม่มีข้อมูลถูกบันทึกไว้ที่ service ของเรา (เพราะเราก็ไม่อยากเก็บเหมือนกัน 😅) งานต่อการดูแลมากๆเพราะทุก service นั้นเป็น serverless ทั้งหมด ใช้ service ในการทำงานน้อย แต่ได้คุณภาพสูง ค่าใช้จ่ายจะเกิดขึ้นก็ต่อเมื่อมีการใช้งาน ซึ่งในแต่ Service ที่เราเลือกใช้งานล้วนแต่มี free-tier ในแต่ละเดือนตลอด เรายิ่งเหมือนเป็นการ Host ไว้ฟรีๆ เลยด้วยซ้ำ เพราะอย่างนี้แล้ว “ใช้เถอะครับ CEO อยากจ่ายตัง” Cloud Cost คำนวนได้ง่ายและตรงไปตรงมา ข้อจำกัด — “ถึงทุกอย่างจะดี แต่ก็ไม่เสมอไป” เมื่อเราเลือกใช้ serverless service สิ่งที่ตามมาคือ limit ที่บางอย่างเราไม่สามารถปรับแต่งได้ ที่เราพบหลักๆตอนนี้ก็คือ size ของ Payload ที่สามารถอัพโหลดเข้ามาได้อย่างจำกัด cost ของ lambda ถึงแม้จะเป็นแบบ pay-per-use แต่ถ้าเรามีผู้ใช้งานที่เยอะขึ้นมากๆ ค่าใช้จ่ายที่ตามมาอาจจะไม่ตอบโจทย์อีกต่อไป ซึ่งราคาโดยประมาณจะอยู่ที่ 120USD per 1 Million Process ปัญหาที่เราพบ การติดตั้ง Python Dependency บน Lambda นั้น ต้องการประสบการณ์ในการใช้งาน Lambda มาก่อนระดับปานกลาง ถ้าหากไม่เคยมีประสบการณ์มาก่อน รับรองได้ว่าปวดหัว ซึ่งทางรอดสำหรับทุกคนก็คือ Lambda Layer และ Layer ARN repo [https://github.com/keithrozario/Klayers ] ถัดมาเราใช้การ Store image ลงใน /tmp ของ Lambda ก่อนจะเอาขึ้นมา Zip อีกครั้งหนึ่ง ซึ่งตรงนี้ถ้าใครไม่เคยใช้ Lambda มาก่อนจะไม่รู้ว่า Lambda สามารถ Write file ลงใน /tmp ได้ และปัญหาอีกข้อคือ /tmp ของ Lambda ไม่ได้แยกต่อ 1 request บาง request จะสามารถเข้าถึง /tmp ก่อนหน้าได้ ทางแก้คือเวลา Write file ลง /tmp ให้แยกเป็น Request ผ่าน uuid ไปเลย บทความนี้เป็นเพียงบทความแรกที่เรานำประสบการณ์ในการคิดและออกแบบ ImageXYZ มาแชร์เพื่อเป็นแนวทางสำหรับผู้พัฒนาที่อยาก hosting web applicatoin ของตัวเองในช่วงเริ่มต้นแล้วยังไม่รู้ว่าจะเริ่มจากตรงไหน และเป็นการแชร์ประสบการณ์จากการใช้งาน Cloud computing ที่ในปัจจุบันนี้มีบทบาทอย่างมากในการทำงานของชาว IT อย่างเราๆ บอกได้เลยว่าอันนี้เป็นเพียงจุดเริ่มต้นเท่านั้น เรายังมีเรื่องราวอีกมากมายไว้พูดคุยกัน แล้วพบกันใหม่ในบทความหน้า สำหรับ Service ถัดไปของเรา 😘