3 คะแนน โดย GN⁺ 2023-12-08 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

แพตเทิร์น FLAME: แนวทางใหม่สำหรับการขยายแอปพลิเคชันแบบยืดหยุ่น

  • Serverless/FaaS (Function as a Service) มอบข้อดีด้านการขยายแบบยืดหยุ่นและการจ่ายตามการใช้งาน แต่ในทางปฏิบัติมักก่อให้เกิดความซับซ้อนมากขึ้น
  • หากสามารถห่อโค้ดแอปที่มีอยู่ให้เป็นฟังก์ชันแล้วรันบนสำเนาแอปชั่วคราวได้ ก็จะทำให้การขยายแบบอัตโนมัติเป็นไปได้
  • แพตเทิร์น FLAME (Fleeting Lambda Application for Modular Execution) ปฏิบัติต่อทั้งแอปพลิเคชันเสมือนเป็น Lambda และรันเฉพาะส่วนที่เป็นโมดูลบนโครงสร้างพื้นฐานระยะสั้น

แพตเทิร์น FLAME

  • แพตเทิร์น FLAME ต้องการการขยายแบบยืดหยุ่นอย่างละเอียดตามความต้องการสำหรับบางส่วนของโค้ดแอป โดยไม่ต้องดูแลเซิร์ฟเวอร์
  • ไม่จำเป็นต้องเขียนแอปพลิเคชันเดิมใหม่ หรือเขียนบางส่วนใหม่บนรันไทม์แบบปิดเฉพาะราย
  • ไลบรารี flame ของ Elixir นำแพตเทิร์น FLAME ไปใช้งานจริง และมี backend adapter สำหรับ Fly.io รวมอยู่ด้วย แต่ก็สามารถใช้ได้บนทุกคลาวด์ที่มี API สำหรับรันโค้ดแอป

FLAME backend

  • บนโครงสร้างพื้นฐานของ Fly.io, FLAME.FlyBackend สามารถบูต Machine ใหม่และเชื่อมต่อเข้ากับงานแม่ได้ภายในประมาณ 3 วินาที
  • FLAME มี LocalBackend และ FlyBackend มาให้โดยค่าเริ่มต้น แต่โฮสต์ใดก็ตามที่มี API สำหรับ provision เซิร์ฟเวอร์และรันโค้ดแอป ก็สามารถทำงานเป็น FLAME backend ได้
  • เนื่องจาก Fly.io รันแอปพลิเคชันโดยแพ็กเป็น Docker image จึงเพียงแค่บูต Machine ใหม่ด้วย image เดียวกัน

Elixir นอกเหนือจาก FLAME

  • Elixir เหมาะกับโมเดล FLAME มาก เพราะมีความสามารถอย่างการกำกับดูแล process และ distributed messaging มาให้โดยไม่ต้องทำเพิ่ม
  • หากภาษานั้นมี primitive ด้าน concurrency ที่เหมาะสม ก็สามารถใช้ประโยชน์จากแพตเทิร์นนี้ได้
  • ยังมีตัวอย่างการนำแพตเทิร์น FLAME ไปใช้กับแอปพลิเคชัน JavaScript โดยย้ายการทำงานแบบโมดูลไปไว้ในไฟล์ใหม่แล้วรัน

เกี่ยวกับ background job processor

  • FLAME ทำงานได้ดีภายใน background job processor แต่เป็นคนละประเด็นกับการที่ไลบรารีงานจะขยาย job pool
  • สิ่งสำคัญคือการแยกงานที่ต้องรับประกันความคงทนออกจากการรันแบบยืดหยุ่น

การทำพูลเพื่อการขยายแบบยืดหยุ่น

  • ผ่านการใช้งาน FLAME ใน Elixir สามารถกำหนด runner ของ elastic pool ได้ ทำให้สามารถสเกลลงสู่ศูนย์และขยาย FLAME server อย่างยืดหยุ่นภายใต้ข้อจำกัด concurrency สูงสุด

การจัดวาง process

  • ใน Elixir ส่วนของแอปพลิเคชันที่มี state จะถูกสร้างขึ้นโดยยึด primitive ของ process เป็นแกนกลาง และทำงานได้ดีเมื่อห่อด้วย FLAME.call หรือ FLAME.cast

การมอนิเตอร์ระยะไกล

  • เมื่อ parent สปินอัป runner, runner ควรจัดการสถานะ idle ของตัวเองเมื่อไม่มีงาน และต้องปิดตัวเองอย่างปลอดภัยเมื่อการเชื่อมต่อกับ parent node หลุด

ความเห็นของ GN⁺

ประเด็นสำคัญที่สุดของบทความนี้คือ แพตเทิร์น FLAME สามารถลดความซับซ้อนของแนวทาง serverless/FaaS แบบเดิม พร้อมทั้งทำให้การขยายแอปพลิเคชันแบบยืดหยุ่นเรียบง่ายขึ้น รูปแบบนี้ช่วยให้นักพัฒนาสามารถขยายเฉพาะส่วนที่ต้องการได้อย่างรวดเร็ว โดยแทบไม่ต้องเปลี่ยนแปลงโค้ดเดิมมากนัก ซึ่งอาจเป็นโซลูชันที่น่าสนใจสำหรับวิศวกรซอฟต์แวร์จำนวนมากที่ใช้งานโครงสร้างพื้นฐานคลาวด์ แพตเทิร์น FLAME ยังอาจเป็นเครื่องมือทรงพลังอย่างยิ่งโดยเฉพาะในภาษาอย่าง Elixir และเมื่อมีการสำรวจความเป็นไปได้ในการนำไปใช้กับภาษาอื่น ๆ ก็ยิ่งน่าคาดหวังต่อการประยุกต์ใช้ในสภาพแวดล้อมการพัฒนาที่หลากหลาย

1 ความคิดเห็น

 
GN⁺ 2023-12-08
ความคิดเห็นจาก Hacker News
  • บทความนี้ชี้ให้เห็นข้อเสียของสถาปัตยกรรม serverless แบบ FaaS ได้ดี จากประสบการณ์ความเจ็บปวดและความซับซ้อนที่เกิดขึ้นหลังจากดูแลแอปพลิเคชันที่ประกอบด้วยฟังก์ชัน Lambda มากกว่า 100 ตัวตลอด 4 ปี

    • ในช่วงแรก ข้อเสียเหล่านี้ยังมองไม่ค่อยเห็น และก็มีข้อดีชัดเจน เช่น ใช้ฟรีเมื่อปริมาณการใช้งานน้อย และแทบไม่ต้องดูแลรักษา
    • แต่เมื่อเวลาผ่านไป ก็ต้องเจอกับความยุ่งเหยิงของเวิร์กโฟลว์ Lambda ที่แข็งตัวขึ้นเรื่อย ๆ เพราะการพึ่งพากันเอง จนทำให้รู้สึกว่าการเลือกแนวทางแบบ monolithic ที่จัดการเองและยอมจ่ายเพิ่มอีกเล็กน้อยน่าจะดีกว่า
  • ในฐานะผู้เขียนบทความ ผู้เขียนหวังว่าจะจุดความสนใจให้คนที่อยากนำแพตเทิร์น FLAME ไปทำในภาษาอื่นอย่าง JavaScript, Go เป็นต้น และพร้อมตอบคำถาม

  • บริการ PiCloud เคยใช้โมเดลที่ส่งงานไปยัง worker อย่างโปร่งใส ซึ่งบ่งชี้ว่าสามารถนำแนวคิดคล้ายกันไปใช้กับภาษาอื่นนอกเหนือจาก Elixir ได้เช่นกัน

  • เมื่อใช้ FLAME สามารถห่อโค้ดแอปที่มีอยู่เดิมไว้ในฟังก์ชันแล้วไปรันในสำเนาแอปชั่วคราวได้ ซึ่งคล้ายกับการ fork โปรเซสในสภาพแวดล้อม serverless

  • Windmill.dev พิจารณาหน่วยของการแยกนามธรรมในระดับซอร์สโค้ด โดยพาร์สฟังก์ชันหลักและ import เพื่อดึงอาร์กิวเมนต์กับ dependency ออกมา แล้วรันโค้ดบนรันไทม์ที่ต้องการ

  • FLAME มอบประสบการณ์พัฒนาแบบโลคัลที่ดีในสภาพแวดล้อม serverless เพราะตัวรันสำหรับพัฒนาและทดสอบจะทำงานบนแบ็กเอนด์โลคัล

  • ทุกครั้งที่ใช้ Flame.call จะมีการเริ่มโปรเซสแอปใหม่และคัดลอก execution context ซึ่งเป็นวิธีแก้ปัญหาการสเกลที่เรียบง่าย แต่ก็ต้องคำนึงถึง latency ที่เพิ่มเข้ามาในเวลาเริ่มแอป และการใช้หน่วยความจำ

  • มีการวิจารณ์การใช้ตัวพิมพ์ใหญ่ในพาดหัวของ Hacker News พร้อมแสดงความหวังว่าจะเป็นการทบทวนเรื่องหุ้นของบริษัท serverless.com ไม่ใช่หลักการ serverless

  • Inngest.com ก็มีแนวทางคล้ายกันในการทำให้โค้ดเดิมใช้งานเป็นฟังก์ชัน serverless ได้ โดยจัดการสถานะของโค้ดจากภายนอก และเน้นย้ำความสำคัญของการมอนิเตอร์และ observability

  • มีการสร้างระบบชื่อ "Long Lambda" โดยมีแนวคิดว่าถ้า Lambda รันได้นานเกิน 15 นาทีได้ ก็จะสามารถจัดการงานทั้งหมดบน Lambda ได้ และยังรันกับดีบักบนเครื่องโลคัลได้

สรุปนี้ถ่ายทอดประเด็นสำคัญของแต่ละความเห็นอย่างกระชับ และเขียนในระดับที่วิศวกรซอฟต์แวร์มือใหม่เข้าใจได้ง่าย โดยอธิบายเฉพาะส่วนที่จำเป็นต่อการเข้าใจบริบทให้น้อยที่สุด และรักษาน้ำเสียงที่เป็นกลางโดยไม่ออกนอกประเด็น