กฎ "ห้ามทำลาย Userspace" ของ Linux จุดประกายการถ่ายเทเรื่องเสถียรภาพ API เทียบกับนวัตกรรม

ทีมชุมชน BigGo
กฎ "ห้ามทำลาย Userspace" ของ Linux จุดประกายการถ่ายเทเรื่องเสถียรภาพ API เทียบกับนวัตกรรม

ชุมชนนักพัฒนาซอฟต์แวร์กำลังหารือกันอย่างกระตือรือร้นเกี่ยวกับหนึ่งในหลักการพื้นฐานที่สำคัญที่สุดในการออกแบบ API นั่นคือกฎศักดิ์สิทธิ์ของการไม่ทำลาย userspace หลักการนี้ซึ่งได้รับการสนับสนุนอย่างมีชื่อเสียงจาก Linus Torvalds ผู้สร้าง Linux ได้กลายเป็นหัวใจสำคัญของเสถียรภาพ API แต่ก็ยังทำให้เกิดคำถามเกี่ยวกับความสมดุลระหว่างความน่าเชื่อถือและนวัตกรรม

ธรรมชาติสองด้านของเสถียรภาพ API

แม้ว่าหลักการไม่ทำลาย userspace จะปกป้องผู้ใช้งานจากซอฟต์แวรที่เสียหาย นักพัฒนาชี้ให้เห็นว่ามันเล่าเพียงครึ่งหนึ่งของเรื่องราว เคอร์เนล Linux รักษาความเข้ากันได้แบบย้อนหลังอย่างเข้มงวดสำหรับอินเทอร์เฟซที่หันหน้าสู่ผู้ใช้ แต่ทำลาย API ภายในเคอร์เนลได้อย่างอิสระโดยไม่มีการเตือนล่วงหน้า แนวทางนี้เน้นย้ำถึงความแตกต่างที่สำคัญในการออกแบบ API นั่นคือไม่ใช่ทุกอินเทอร์เฟซที่ต้องการการรับประกันเสถียรภาพในระดับเดียวกัน

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

ปรัชญา API ของ Linux Kernel

  • Userspace APIs: ไม่เคยถูกทำลาย รักษาไว้อย่างไม่มีกำหนดเพื่อความเข้ากันได้แบบย้อนหลัง
  • Kernel APIs: สามารถถูกทำลายได้โดยไม่ต้องแจ้งเตือน ทำให้เกิดนวัตกรรมภายในได้
  • หลักการสำคัญ: ประกาศสิ่งที่มีเสถียรภาพล่วงหน้า รักษาการรับประกันเหล่านั้นอย่างเข้มงวด

ความท้าทายด้านความเข้ากันได้ของ GNU libc

แม้จะมีความมุ่งมั่นของเคอร์เนลต่อเสถียรภาพ userspace แต่ไลบรารี C ของ GNU (glibc) ยังคงนำเสนอความท้าทายด้านความเข้ากันได้อย่างต่อเนื่อง โปรแกรมที่คอมไพล์กับ glibc เวอร์ชันใหม่กว่ามักจะไม่สามารถทำงานบนระบบเก่าได้ ทำให้ต้องอัปเกรดทุกอย่างพร้อมกัน สิ่งนี้สร้างอุปสรรคในทางปฏิบัติต่อความพยายามด้านเสถียรภาพของเคอร์เนล

แม้ว่าเคอร์เนลจะไม่ทำลาย userspace แต่ GNU libc ทำอยู่ตลอดเวลา ดังนั้นผลลัพธ์สุทธิคือ userspace ของ Linux เสียหายโดยไม่คำนึงถึงความพยายามของผู้ดูแลเคอร์เนล

การลิงก์แบบสแตติกเสนอทางออกหนึ่ง โดยให้เสถียรภาพที่น่าทึ่งสำหรับไฟล์ปฏิบัติการ อย่างไรก็ตาม ข้อจำกัดด้านใบอนุญาตกับ GNU libc ทำให้แนวทางนี้มีปัญหาสำหรับแอปพลิเคชันเชิงพาณิชย์จำนวนมาก ทำให้นักพัฒนาบางคนสำรวจทางเลือกอื่น เช่น musl libc หรือโครงการ LLVM libc ที่กำลังเกิดขึ้น

ปัญหาความเข้ากันได้ของ GNU libc

  • โปรแกรมที่คอมไพล์บน libc เวอร์ชันใหม่กว่าจะไม่สามารถทำงานบนระบบเก่าได้
  • ต้องการการอัปเกรดแบบ lockstep ทั่วทั้งระบบ
  • การ static linking กับ GNU libc มีข้อจำกัดด้านลิขสิทธิ์ LGPL สำหรับซอฟต์แวร์เชิงพาณิชย์
  • ทางเลือกอื่น: musl libc (ลิขสิทธิ์ที่ยืดหยุ่นกว่า), LLVM libc (อยู่ระหว่างการพัฒนา)

การกำหนดเวอร์ชัน API: ความชั่วร้ายที่จำเป็นหรือข้อบกพร่องในการออกแบบ?

การถกเถียงขยายไปถึงกลยุทธ์การกำหนดเวอร์ชัน API โดยนักพัฒนาแบ่งปันประสบการณ์ที่หลากหลายเกี่ยวกับรูปแบบการกำหนดเวอร์ชันแบบ URL หลายคนรายงานว่า API ส่วนใหญ่ไม่เคยก้าวหน้าเกินเวอร์ชัน 1 ทำให้คำนำหน้า /v1 เป็นเพียงพิธีกรรม เมื่อเกิดการเปลี่ยนแปลงที่ทำลายขึ้น ทีมงานมักจะสร้าง endpoint ใหม่ทั้งหมดด้วยชื่อที่แตกต่างกันแทนที่จะเพิ่มหมายเลขเวอร์ชัน

นักพัฒนาบางคนสนับสนุนการรวมหมายเลขเวอร์ชันตั้งแต่เริ่มต้นเพื่อให้การเปลี่ยนผ่านในอนาคตง่ายขึ้น ในขณะที่คนอื่นโต้แย้งว่าสิ่งนี้ส่งเสริมการเปลี่ยนแปลงที่ทำลายโดยไม่จำเป็น การอภิปรายเผยให้เห็นว่าการกำหนดเวอร์ชันที่ประสบความสำเร็จต้องการการวางแผนอย่างรอบคอบและค่าใช้จ่ายในการบำรุงรักษาที่สำคัญ เนื่องจากแต่ละเวอร์ชันจะเพิ่มภาระการทดสอบและการสนับสนุนเป็นหลายเท่า

รูปแบบการกำหนดเวอร์ชันของ API ที่พบเห็น

  • v1: เวอร์ชันที่พบมากที่สุด มักจะเป็นเวอร์ชันเดียวที่เคยปล่อยออกมา
  • v2: หายาก มักจะเป็นตัวแทนของการออกแบบใหม่แบบ "ตอนนี้เราเข้าใจแล้วว่าเราทำอะไรอยู่"
  • v3: พบเห็นได้บ่อยกว่า v2 มักจะตามมาหลังจาก v2 อย่างรวดเร็ว
  • v4+: หายากมากในทางปฏิบัติ
  • วิธีการทางเลือก: ใช้ endpoint ใหม่ที่มีชื่อบรรยายลักษณะแทนการใช้หมายเลขเวอร์ชัน

ความเรียบง่ายของการรับรองความถูกต้องเทียบกับความปลอดภัย

หัวข้อที่ถกเถียงกันเป็นพิเศษเกิดขึ้นรอบวิธีการรับรองความถูกต้องของ API แม้ว่า OAuth และรูปแบบการรับรองความถูกต้องที่ซับซ้อนอื่น ๆ จะให้ความปลอดภัยที่ดีกว่า นักพัฒนาหลายคนโต้แย้งเพื่อสนับสนุน API key ธรรมดาเพื่อลดอุปสรรคในการเข้าถึง สิ่งนี้สะท้อนถึงความตึงเครียดที่กว้างขึ้นระหว่างแนวปฏิบัติที่ดีด้านความปลอดภัยและประสบการณ์ของนักพัฒนา

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

ต้นทุนของการเปลี่ยนแปลงที่ทำลาย

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

สิ่งนี้เสริมเหตุผลว่าทำไมหลักการไม่ทำลาย userspace จึงมีอยู่ ธรรมชาติที่เชื่อมโยงกันของซอฟต์แวรสมัยใหม่หมายความว่าผู้ดูแล API มีความรับผิดชอบต่อระบบนิเวศทั้งหมดของพวกเขา ไม่ใช่เพียงผู้ใช้โดยตรงเท่านั้น

อ้างอิง: Everything I know about good API design