Photo by Nicolas J Leclercq on Unsplash

ช่วงสองปีที่ผ่านมา แนวคิดหนึ่งที่ผมจับตาดูอยู่คือเรื่องของ Serverless

ตามชื่อเลย Serverless คือไม่มีเซอร์เวอร์ ซึ่งจริงๆแล้วเซอร์เวอร์ก็ไม่ได้หายไปไหน เพียงแต่ทีมพัฒนาไม่ต้องสนใจมันเหมือนแต่ก่อนแล้ว

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

ผ่านมาสองปี รู้สึกว่าเริ่มเข้าที่เข้าทางมากขึ้น จึงพึ่งได้เอามาใช้ทำโปรเจ็คจริง เลยเอามาเล่าสู่กันฟังครับ เผื่อใครอยากจะลองเอาไปใช้กัน

ก่อนจะมี Serverless

ก่อนจะคุยเรื่อง Serverless ผมขอเล่าความเป็นมาก่อน

ในโลกของ Software Engineering เราทำการ Abstraction กันอยู่ตลอดเวลา ตัวอย่างเช่นเวลาเราเรียกใช้ฟังก์ชั่นใน API เราไม่รู้ว่าข้างในมันทำงานอย่างไร

ในฝั่งของ Infrastructure ก็คล้ายๆกัน

สมัยก่อน ถ้าบริษัทใหญ่ๆจะมี Data Center เป็นของตัวเอง จัดการระบบ Hardware, Network, Power Supply, Cooling System, ควบคุมเรื่องความปลอดภัยของสถานที่

แค่สร้าง Data Center แห่งเดียวก็ใช้ต้นทุนและความรู้มหาศาลแล้ว

แต่หากบริษัทต้องการระบบที่มี High Availability ก็จะต้องคิดถึงกรณีที่ Data Center เกิดมีปัญหาขึ้นมา (ไฟดับ แผ่นดินไหว ไฟไหม้ ฯลฯ) กรณีนี้ บริษัทต้องมีมีี Data Center มากกว่าหนึ่งที่ในระยะที่ห่างกันพอประมาณ หากเกิดเหตุไม่คาดฝันขึ้น อีก Data Center ก็ต้องสามารถทำงานได้

รายละเอียดพวกนี้ ทำให้เวลาทีมพัฒนาขอเครื่อง กินเวลาเป็นหลายเดือนกว่าจะจัดซื้อ และติดตั้งใน Data Center เสร็จให้ทีมได้ใช้งานจริงๆ

บางบริษัทก็จะวางแผนไว้ล่วงหน้า (Capacity Planning) มีการเผื่อเครื่องไว้ แต่ก็เป็นค่าใช้จ่ายที่ต้องมีเครื่องที่ไม่ได้ใช้งานไว้พร้อมอยู่เสมอ

พอเกิดการทำ Virtualization ขึ้น ชีวิตก็สะดวกขึ้นสำหรับทั้งสองฝ่ายอีกนิด ฝั่งที่ดูแล Data Center ก็สามารถ"หั่น"เครื่องคอมพิวเตอร์เครื่องหนึ่ง มาเป็นเครื่องย่อยๆมาให้ทีมพัฒนาใช้ได้ มาเป็น Virtual Machine ไม่ต้องจัดการเป็นเครื่องๆเหมือนแต่ก่อน

ทีมพัฒนาเองก็ไม่ต้องสนใจแล้วว่ามีเครื่องจริงๆรึเปล่า แค่ทดสอบดูว่าซอฟต์แวร์และ Configuration ต่างๆทำงานถูกต้องใน Virtual Machine ก็พอแล้ว

แต่ก็ยังหนีการจัดการเครื่องและ Data Center ไม่ได้อยู่ดี

ราว 10 ปีที่แล้ว เราเลยเริ่มมี Cloud Computing ขึ้น แทนที่จะต้องจัดการ Data Center เอง ก็โยนให้บริษัทที่เชี่ยวชาญทำไป บริษัทสามารถใช้ทรัพยากรไปกับงานอื่นๆแทน

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

ตอนแรกๆแนวคิดนี้คนก็กลัวกัน ว่าการฝากระบบคอมพิวเตอร์ไว้กับบริษัทอื่นมันเป็นความเสี่ยงมากเกินไปรึเปล่า แต่พอผ่านไปหลายปีก็ค้นพบว่า ถ้าเราไม่ได้มีทีมที่เชี่ยวชาญด้านนี้จริงๆ การบริหาร Data Center เองนี่มีโอกาสผิดพลาดมากกว่าให้คนอื่นบริหารอีก

Cloud Computing ก็เริ่มกลายเป็น New Normal

ถึงจุดนี้ เราอาจจะเซอร์เวอร์กลายสภาพไปใกล้เคียงกับ Commodity มากขึ้น

หลังจากนั้น Cloud Computing ก็เริ่มขยายไปถึงพวก Managed Services ด้วย นอกจากไม่ต้องดูแลเครื่องจริงๆแล้ว พวก Storage, Database, Messaging queue, in-memory database หรือ Authentication System ที่ทุกระบบต้องใช้เหมือนกัน เราก็สามารถซื้อเอาได้ ถ้าใช้ค่า Default แล้วกดไม่กี่ปุ่ม สิบนาทีก็ได้มาใช้แล้ว

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

จะเห็นได้ว่า Abstraction ในแต่ละขั้น มีประโยชน์ต่อทีมพัฒนามาก ทำให้ทีมสามารถทำงานได้เร็วขึ้น เพราะ

  1. ความรู้ที่ต้องใช้น้อยลง ไม่ต้องรู้ละเอียดทุกเรื่อง
  2. ปริมาณคนที่เกี่ยวข้องเพื่อจะสร้าง/ดูแลเซอร์เวอร์หรือพวกซอฟต์แวร์พื้นฐานลดลง พอปริมาณคนที่เกี่ยวข้องน้อย Overhead ในการสื่อสารและกระบวนการก็น้อยลง (ลองนึกว่าขอซื้อเครื่องทีต้องไปขอผ่านแผนกจัดซื้อ รออนุมัติกันยาวนาน)

Abstraction ขั้นถัดไปคือ Serverless

กลับมาที่เรื่องของ Serverless กัน

ถ้าหากเราใช้ Cloud Computing เราก็ยังมี Virtual Machine อยู่ เรายังต้อง Monitor CPU, I/O หรือต้องมานั่ง Patch ตัวระบบ Operating System อยู่ดี

หากต้องการให้ระบบของเรามี High Availability (ถ้ามีเครื่องพังไปบางเครื่อง ระบบยังทำงานได้) เราก็จะต้องมีเครื่องมือที่ใช้ในการทำ Self Healing หรือออกแบบ Architecture ให้มี Redundancy ในระดับหนึ่ง

ถ้าต้องการให้ระบบเรามี Scalability เราก็ต้องมีเครื่องมือหรือสคริปต์ที่่ใช้ในการปรับจำนวนเครื่องขึ้นลง ตามปริมาณ Load ในระบบในขณะนั้นๆ

จะเห็นได้ว่า ถึงแม้เราไม่ต้องกับยุ่งกับเครื่องที่จับต้องได้จริงๆ ทีมพัฒนายังต้องมีความเข้าใจในระดับที่ต่ำกว่า Application Layer ที่ค่อนข้างลึกอยู่

ต้องรู้ว่า “มันมีเครื่องจริงๆ” อยู่ที่ไหนสักแห่ง และต้องจัดการกับมันให้ดี

แต่ทว่า…

แท่น แทน แท๊น

เรามีตัวเลือกของ Serverless แล้ว !!

Serverless เป็นอีกขั้นหนึ่งของ Abstraction ที่จะมาช่วย"ซ่อน"เรื่องพวกนี้จากทีมพัฒนา

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

แต่แทนที่จะต้องคิดเรื่องต่างๆข้างบน ทีมพัฒนาแค่อัพโหลดโค้ดขึ้นไป ไม่ต้องสนใจว่ามันจะไปรันที่ไหน จะเสกลยังไง เรื่องพวกนี้ให้ Provider จัดการให้หมด

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

อะไรที่ลงจากเลเยอร์ของโค้ดลงไป ผมเคยทำพังมาหมด ไม่ใช่แค่คอนฟิค รัน rm -rf / ก็เคยพลาดมาแล้ว

ส่วน Provider ก็คิดเงินตาม “ปริมาณการคำนวน” ซึ่งอาจจะเป็นปริมาณ RAM, CPU, และเวลาที่ใช้ในการทำงานของโปรแกรม แล้วแต่ Provider ที่ใช้

ข้างใน Serverless

ส่วนประกอบหลักๆของ Serverless Architecture มีอยู่สองส่วน

  1. Function-as-a-Services (FaaS) ส่วนนี้ทำหน้าที่รันโค้ดที่เราเขียนและอัพโหลดขึ้น ทาง Provider ก็จะจัดการดูแลเรื่อง Provision, Availability, Scaling ให้หมด
  2. Backend-as-a-Services (Baas) ส่วนนี้คือ Managed Services ต่างๆที่เราใช้จาก Provider เช่น Database, User Management System, API system, Storage, Synchronization services ที่ผมเล่าให้ฟังก่อนหน้านี้

สมมติว่าเราทำ Mobile เป็นเว็บบอร์ดให้คนถามตอบ เราอาจจะใช้

  • User Management System (BaaS) สำหรับการสมัครสมาชิกและการยืนยันตัวตน
  • API System (BaaS) สำหรับให้ Mobile Client ติดต่อ และส่ง Request ไปยัง FaaS ที่เราอัพโหลดไว้
  • FaaS ที่ใช้ในการประมวลข้อมูลจากผู้ใช้
  • Database System (BaaS) สำหรับเก็บข้อมูลในเว็บบอร์ด

กรณีนี้ Architecture ก็ไม่ได้ต่างไปจากปกติมาก แค่เราไม่ต้องดูแลเรื่องเซอร์เวอร์แล้ว ไม่ต้องมานั่งกังวลว่าโหลด CPU จะสูงไปรึเปล่า, Disk จะเต็มรึยัง, ถ้าคนใช้เยอะๆจะเสกลยังไง, แปะ Security Patch ใน OS ยัง, แล้วถ้าเครื่องที่รันอยู่เกิดพังไปสักเครื่องสองเครื่อง เราจะเรียกเครื่องใหม่ขึ้นมายังไง

BaaS เองนี่มีหรือไม่มีเซอร์เวอร์ก็ใช้กันได้ ถ้าเทียบกัน Architecture ทั่วไปส่วนที่ใหม่ๆมากๆก็คือ FaaS

นิยามของ Serverless

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

  1. Requires no management of Server hosts or Server processes - อันนี้เป็นแก่นหลักเลย คือทีมพัฒนาไม่ต้องสนใจว่าโค้ดหรือเซอร์วิซจะรันอยู่บน Virtual Machine, Physical Machine ตัวไหน
  2. Self auto-scales and auto-provisions, based on Load - นอกจากไม่ต้องคิดถึงเซอร์เวอร์แล้ว เราก็ไม่ต้องสนด้วยว่าเซอร์เวอร์จะถูกสร้างขึ้นมาอย่างไร เวลาที่คนใช้เยอะๆ ปริมาณเซอร์เวอร์จะปรับเปลี่ยนเพื่อรองรับ Load ได้เองโดยอัตโนมัติ
  3. Offers costs based on precise usage - หากเราเช่าเครื่อง เราก็จะจ่ายตามเวลาที่ใช้งานกับชนิดของเครื่อง แม้เครื่องจะไม่มีการทำงานใดๆหรือทำงานน้อยมาก (เช่น Web Server ตอนตี3-ตี4) เราก็ต้องจ่ายเต็มจำนวน กรณีของ Serverless เราจ่ายตามการใช้งานจริง ถ้าไม่มีใครเรียกใช้งานระบบของเรา เราก็ไม่ต้องจ่ายค่่าใช้บริการ
  4. Has performance capabilities defined in terms other than host size/count - เวลาที่ต้องการใช้งานมากขึ้น เราไม่ได้ใช้วิธีการเพิ่มจำนวนเครื่อง แต่กำหนดเป็น “ปริมาณการคำนวน” แทน ในกรณีของ Managed Services ก็จะมีหน่วยอื่นที่ใช้วัดคำนวณการใช้งานแทน
  5. Has implicit High Availability - โดยส่วนใหญ่ FaaS กับ BaaS จะมีการทำ Redundancy เพื่อให้ระบบมี High Availability โดยอัตโนมัติอยู่แล้ว พอเราใช้บริการเหล่านี้ เราก็จะได้คุณสมบัติเหล่านี้โดยอัตโนมัติ

ประโยชน์หลักๆ

หลังจากทำความเข้าใจแล้ว ก็มาดูกันว่ามีประโยชน์อะไรบ้าง

1. เพิ่มความเร็วในการพัฒนา

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

แต่แทนที่เราจะได้ลงมือโค้ดเพื่อทำแอพนี้ทันที เราต้องใช้เวลาไปกับการสร้างเซอร์เวอร์ เซ็ตอัพพวก Middleware, Database และอะไรต่อมิอะไร สิ่งเหล่านี้กินเวลามาก หลังเซ็ตอัพเสร็จแล้วก็ต้องมาดูแล (maintain) ด้วย ดีไม่ดีต้องจ้างคนมาเพิ่มอีกคนเพื่อดูแลเรื่องพวกนี้โดยเฉพาะ

แม้ใน Layer ของ Application ทีมก็ไม่ต้องโค้ดอะไรที่ไม่ได้เป็นคุณสมบัติหลัก เช่น User Management System, Data syncing พวกนี้ก็ใช้วิธีหันไปใช้ Managed Services (BaaS) เอาแทน นอกจากจะลดเวลาในการพัฒนาแล้ว ยังลดเวลาในการดูแล(เก็บบั้ค)ไปได้มากด้วย (User Management System ดีๆ ปลอดภัยๆ เขียนยากมาก)

2. ลดค่าใช้จ่าย

Serverless ได้ข้อดีของ Cloud Computing มาในด้านของการลด Upfront cost

และเนื่องด้วยค่าใช้จ่ายคิดตามการใช้จริง เราก็ไม่ต้องเสียเงินตลอดเวลาที่มีการเปิดเครื่อง จ่ายเฉพาะตอนที่เครื่องมีการทำงานจริงเท่านั้น (นึกภาพพวกเซอร์เวอร์ที่เราใช้ใน Dev กับ Test Environment, หรือระบบที่คนใช้จะใช้เยอะมากแค่ในบางช่วงเวลา อันนี้ประหยัดเงินเยอะมาก)

ในกรณีของ Managed Services ส่วนใหญ่ ค่าใช้จ่ายก็จะคิดตามการใช้งาน เช่น User Management System ก็อาจจะคิดตามจำนวนผู้ใช้หรือจำนวน API Call ทำให้ค่าใช้จ่ายช่วงแรกๆที่ยังมีผู้ใช้จำนวนน้อยๆนั้นต่ำกว่า

อย่างไรก็ตาม ข้อนี้ไม่ได้เป็นจริง 100% ทุกกรณี ต้องคำนวนให้ดีๆว่าจะคุ้มจริงหรือเปล่า เพราะถ้าแอพพลิเคชั่นของเรามีการใช้งานสม่ำเสมอตลอดเวลา 24 ชั่วโมง ค่าใช้จ่ายอาจจะไม่ต่างกัน หรืออาจจะมากกว่าก็ได้ ถ้าเรากะจำนวนผู้ใช้คร่าวๆได้ (หรือมีระบบที่มีผู้ใช้อยู่แล้ว) การคำนวนค่าใช้จ่ายฝั่ง Serverless จะง่ายกว่ามาก ไม่ต้องมานั่งทำ Load Test ดูว่าเครื่องนึงรับได้เท่าไร ต้องใช้กี่เครื่อง

แต่อีกมุมนึง ก็ต้องคำนวนด้วยว่า เราลดใช้จ่ายในด้านของจำนวนคนที่จะต้องดูแลเซอร์เวอร์พวกนี้

3. ลดความรู้กับทรัพยากรมนุษย์ที่จำเป็น

ในชีวิตการทำงาน เคยเห็นคนที่เซ็ต Nginx เป็น, เซ็ต Database เป็น, เซ็ต RabbitMQ เป็น, ใช้ Docker กับ k8s เป็น, แล้วยังเขียนโค้ดได้ด้วยกี่คนครับ?

เรื่องพวกนี้ไม่ใช่เรื่องที่ยากสุดๆ ด้วยเซิร์ชเอ็นจินและ StackOverflow ถ้าใช้เวลาก็สามารถเรียนรู้และทำได้ แต่ก็ต้องเสียเวลาตามข้อที่ 1

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

การลดความรู้ที่จำเป็นลง จึงเป็นปัจจัยที่สำคัญมาก

แต่ Serverless ไม่ใช่ยาวิเศษสำหรับทุกปัญหา

ปัจจุบัน Serverless เองก็ยังมีข้อจำกัดอยู่ แต่ละ Provider ก็จะมีข้อจำกัดไม่เหมือนกัน

ในวงการก็มีการถกเถียงกันมากว่ากรณีไหนที่ใช้ Serverless แล้วเหมาะ อันไหนไม่เหมาะ กรณีที่เห็นพ้องกันก็มี

งานจำพวก Asynchronous คือ ทำแล้วเสร็จเมื่อไรก็ได้ มีการ Trigger งานให้ทำครั้งเดียวแล้วก็รองานจบไป Trigger งานถัดไปอีกที พวกนี้เหมาะกับ Serverless มาก โดยเฉพาะงานที่นานๆทีทำที เราไม่ต้องมาเปิด Server ทิ้งไว้ตลอดเวลาให้เปลืองเงิน

พวก Startup ที่มีคนน้อย ต้องการลดเวลากับเรื่อง Infrastructure ให้น้อยที่สุดก็ดูจะเหมาะกับการใช้ Serverless

แต่อย่างกรณีของงานที่ต้องรันนานๆ เช่นต้องมีการทำ Web Socket อยู่ตลอดเวลา หรือ Batch Job ที่ต้องรันหลายชั่วโมง อันนี้พวก FaaS ก็จะมีข้อจำกัดว่ามันไม่สามารถรันได้นาน กรณีนั้นสู้รันเซอร์เวอร์กับคอนเทนเนอร์เอง ก็คงเหมาะกว่า

หรืองานที่ต้องการ Latency ต่ำมากๆ เพราะข้างในของ Serverless ก็เป็น Container อยู่เบื้องหลัง หากไม่มีการเรียกใช้นานๆ ทาง Provider ก็จะแช่แข็ง Container พวกนี้ไว้ พอมี Request เข้ามาก็ต้องเสียเวลาปลุก Container ขึ้นมาใหม่ ศัพท์เทคนิคเรียกว่า Cold Start ซึ่งทำให้ Latency ในจังหวะนั้นสูงผิดปกติ

และการเขียนโค้ดก็อาจจะเปลี่ยนไป

อีกเรื่องหนึ่งที่ผมรู้สึกว่าสำคัญมาก คือการออกแบบโค้ดให้อยู่ในลักษณะที่ Maintain ได้ง่าย

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

ในทางตรงกันข้าม ถ้าเรายัดทุกอย่างเข้าไปใน FaaS ฟังก์ชั่นเดียว (แล้วใส่ Switch Case เพื่อทำทุกอย่าง) เวลาที่ใช้ในการโหลดฟังก์ชั่นนั้นๆก็จะนาน ทำให้ Latency สูง และเสียเงินเพิ่มขึ้นไปด้วย

และเนื่องด้วย Serverless ไม่มีเซอร์เวอร์ เราไม่มีหน่วย Storage ที่เก็บค้างไว้ได้ (Stateless) การเก็บ State ในการทางานต่างๆก็จะต้องไปอยู่ที่อื่นแทน

แล้วอนาคตล่ะ?

ถ้าผมต้องแทงพนัน ผมแทงข้าง Serverless นะ แต่ก็คงไม่ได้ออกมาในรูปแบบว่าทุกอย่างจะเป็น Serverless 100%

ผมคิดว่า Serverless จะเป็น Abstraction ใน Layer ถัดไปในอนาคต เพราะการตัดเซอร์เวอร์ออกไปทำให้ทำงานได้เร็ว

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

เทคโนโลยีต่างๆของ Serverless เองนั้นถือว่าใหม่ ข้อจำกัดที่มีอยู่ในปัจจุบันก็ยังมีโอกาสถูกพัฒนาไปได้อีก

แต่ก็ไม่ใช่ว่า Serverless จะแก้ปัญหาได้ทุกอย่าง ผมคิดว่าในอนาคต อะไรที่เป็น Serverless ได้ก็จะเป็นไป ส่วนที่ไม่ได้ก็จะอยู่บนฝั่ง Container ที่จัดการกันด้วย Orchestrator กัน (ซึ่งก็ k8s ก็เข้ายึดพื้นที่สำเร็จแล้ว)