The Monolith (Monolith)

เราได้พูดถึง microservices ไปแล้ว แต่ microservices มักถูกพูดถึงในฐานะแนวทางสถาปัตยกรรมที่เป็นทางเลือกแทน สถาปัตยกรรมแบบ monolithic เพื่อแยกความแตกต่างของสถาปัตยกรรม microservice ให้ชัดเจนขึ้น และเพื่อช่วยให้คุณ เข้าใจดีขึ้นว่า microservices คุ้มค่าที่จะพิจารณาหรือไม่ ผมควรพูดถึงด้วยว่าผมหมายถึงอะไรเมื่อพูดถึง monolith

เมื่อผมพูดถึง monolith ตลอดทั้งเล่มนี้ ผมหมายถึง unit of deployment เป็นหลัก เมื่อฟังก์ชันการทำงานทั้งหมด ในระบบต้อง deploy ร่วมกัน ผม ถือว่า มันเป็น monolith อาจกล่าวได้ว่าสถาปัตยกรรมหลายแบบตรงกับนิยามนี้ แต่ผมจะพูดถึงแบบที่ผมเห็นบ่อยที่สุด ได้แก่ single-process monolith, modular monolith และ distributed monolith

The Single-Process Monolith (Single-Process Monolith)

ตัวอย่างที่พบบ่อยที่สุดที่นึกถึงเมื่อพูดถึง monolith คือระบบที่โค้ดทั้งหมดถูก deploy เป็น process เดียว ดังใน Figure 1-6 คุณอาจมี instance ของ process นี้หลายตัวเพื่อความทนทานหรือเหตุผลด้านการ scale แต่โดยพื้นฐานแล้วโค้ด ทั้งหมดถูกอัดแน่นอยู่ใน process เดียว ในความเป็นจริง ระบบ single-process เหล่านี้สามารถเป็นระบบแบบกระจาย อย่างง่ายในตัวมันเองได้ เพราะแทบจะเสมอที่พวกมันจบลงด้วยการอ่านข้อมูลจากหรือเก็บข้อมูลลงในฐานข้อมูล หรือ นำเสนอข้อมูลให้กับแอปพลิเคชันเว็บหรือมือถือ

bms2 0106

Figure 1-6. In a single-process monolith, all code is packaged into a single process (ใน single-process monolith โค้ดทั้งหมดถูกบรรจุไว้ใน process เดียว)

แม้สิ่งนี้จะตรงกับความเข้าใจของคนส่วนใหญ่เกี่ยวกับ monolith แบบคลาสสิก แต่ระบบส่วนใหญ่ที่ผมพบเจอมักจะ ซับซ้อนกว่านี้อยู่บ้าง คุณอาจมี monolith สองตัวหรือมากกว่าที่ tightly coupled กัน และอาจมีซอฟต์แวร์จาก vendor เข้ามาผสมด้วย

การ deploy แบบ single-process monolithic คลาสสิกอาจสมเหตุสมผลสำหรับหลายองค์กร David Heinemeier Hansson ผู้สร้าง Ruby on Rails ได้อธิบายอย่างมีประสิทธิภาพว่าสถาปัตยกรรมแบบนี้สมเหตุสมผลสำหรับองค์กรขนาดเล็ก 5 แม้เมื่อองค์กรเติบโตขึ้น monolith ก็อาจเติบโตไปพร้อมกันได้ ซึ่งนำเราไปสู่ modular monolith

The Modular Monolith (Modular Monolith)

ในฐานะ subset ของ single-process monolith modular monolith เป็นรูปแบบหนึ่งที่ process เดียวประกอบด้วย module ที่แยกจากกัน แต่ละ module สามารถถูกพัฒนาแยกกันได้ แต่ ทั้งหมดยังคงต้องรวมเข้าด้วยกันเพื่อ deploy ดังแสดงใน Figure 1-7 แนวคิดการแบ่งซอฟต์แวร์ออกเป็น module ไม่ใช่เรื่องใหม่ ซอฟต์แวร์แบบ modular มีรากฐานมาจากงานด้าน structured programming ในทศวรรษ 1970 และย้อนไปไกลกว่านั้นอีก ถึงกระนั้น นี่ก็เป็นแนวทางที่ผมยังเห็น องค์กรจำนวนไม่มากพอที่จะนำมาใช้อย่างจริงจัง

bms2 0107

Figure 1-7. In a modular monolith, the code inside the process is divided into modules (ใน modular monolith โค้ดภายใน process ถูกแบ่งออกเป็น module)

สำหรับหลายองค์กร modular monolith อาจเป็นตัวเลือกที่ยอดเยี่ยม หากขอบเขตของ module ถูกกำหนดไว้อย่างดี มันสามารถให้ระดับการทำงานคู่ขนานที่สูง ในขณะที่หลีกเลี่ยงความท้าทายของสถาปัตยกรรม microservice ที่กระจาย มากกว่า ด้วยการมี topology การ deploy ที่ง่ายกว่ามาก Shopify เป็นตัวอย่างที่ดีของ องค์กร ที่ใช้เทคนิคนี้ เป็นทางเลือกแทนการแยกส่วนแบบ microservice และดูเหมือนจะได้ผลดีมากสำหรับบริษัทนั้น 6

หนึ่งในความท้าทายของ modular monolith คือฐานข้อมูลมักขาดการแยกส่วนที่เราพบในระดับโค้ด ซึ่งนำไปสู่ความ ท้าทายอย่างมากหากคุณต้องการแยก monolith ออกในอนาคต ผมเคยเห็นบางทีมพยายามผลักดันแนวคิด modular monolith ไปไกลกว่านั้น โดยแยกฐานข้อมูลตามแนวเดียวกับ module ดังแสดงใน Figure 1-8

bms2 0108

Figure 1-8. A modular monolith with a decomposed database (modular monolith ที่มีฐานข้อมูลถูกแยกส่วน)

The Distributed Monolith (Distributed Monolith)

ระบบแบบกระจายคือระบบที่ความล้มเหลวของคอมพิวเตอร์เครื่องหนึ่งที่คุณไม่รู้ด้วยซ้ำว่ามีอยู่ สามารถทำให้ คอมพิวเตอร์ของคุณเองใช้งานไม่ได้ 7

Leslie Lamport

distributed monolith คือระบบที่ประกอบด้วย service หลายตัว แต่ไม่ว่าด้วยเหตุผลใดก็ตาม ทั้งระบบต้อง deploy ร่วมกัน distributed monolith อาจตรงกับนิยามของ SOA ได้ดี แต่บ่อยครั้งมันล้มเหลวที่จะส่งมอบตามคำมั่นสัญญาของ SOA จากประสบการณ์ของผม distributed monolith มีข้อเสียทั้งหมดของระบบแบบกระจาย และ ข้อเสียของ single-process monolith โดยไม่มีข้อดีที่มากพอของทั้งสองแบบ การเจอ distributed monolith หลาย ครั้งในงานของผมมีส่วนอย่างมากที่ทำให้ผมสนใจสถาปัตยกรรม microservice

Distributed monolith มักเกิดขึ้นในสภาพแวดล้อมที่ไม่ได้ให้ความสำคัญเพียงพอกับแนวคิดอย่าง information hiding และ cohesion ของฟังก์ชันการทำงานทางธุรกิจ เพียงพอ แทนที่จะเป็นแบบนั้น สถาปัตยกรรมที่ coupled กันสูงกลับทำให้การเปลี่ยนแปลงกระเพื่อมข้ามขอบเขต service และ การเปลี่ยนแปลงที่ดูเหมือนไม่มีพิษภัยและมีขอบเขตจำกัดในท้องถิ่นกลับไปทำลายส่วนอื่นของระบบ

Monoliths and Delivery Contention (Monolith และ Delivery Contention)

เมื่อมีคนทำงานในที่เดียวกันมากขึ้นเรื่อยๆ พวกเขาก็ขวางทางกันเอง—ตัวอย่างเช่น นักพัฒนาต่างคนต่างอยากเปลี่ยน โค้ดชิ้นเดียวกัน ทีมต่างๆ อยากปล่อยฟังก์ชันการทำงานให้ใช้งานจริงในเวลาต่างกัน (หรืออยากเลื่อนการ deploy) และความสับสนว่าใครเป็นเจ้าของอะไรและใครเป็นคนตัดสินใจ งานวิจัยจำนวนมากแสดงให้เห็นความท้าทายของความ เป็นเจ้าของที่สับสน 8 ผมเรียกปัญหานี้ว่า delivery contention

การมี monolith ไม่ได้หมายความว่าคุณจะต้องเจอความท้าทายของ delivery contention อย่างแน่นอน เช่นเดียวกับ การมีสถาปัตยกรรม microservice ก็ไม่ได้หมายความว่าคุณจะไม่มีวันเจอปัญหานี้ แต่สถาปัตยกรรม microservice ให้ขอบเขตที่เป็นรูปธรรมมากกว่าที่เส้นแบ่งความเป็นเจ้าของสามารถถูกวาดขึ้นได้ในระบบ ทำให้คุณมีความยืดหยุ่น มากขึ้นมากในการลดปัญหานี้

Advantages of Monoliths (ข้อดีของ Monolith)

monolith บางแบบ เช่น single-process หรือ modular monolith ก็มีข้อดีมากมายเช่นกัน topology การ deploy ที่ ง่ายกว่ามากช่วยหลีกเลี่ยงกับดักหลายอย่างที่เกี่ยวข้องกับระบบแบบกระจาย สิ่งนี้สามารถทำให้ workflow ของ นักพัฒนาง่ายขึ้นมาก และการ monitoring การแก้ปัญหา และกิจกรรมอย่าง end-to-end testing ก็สามารถถูกทำให้ง่าย ขึ้นได้มากเช่นกัน

Monolith ยังช่วยให้การนำโค้ดกลับมาใช้ซ้ำภายใน monolith เองง่ายขึ้นด้วย หากเราต้องการนำโค้ดกลับมาใช้ซ้ำใน ระบบแบบกระจาย เราต้องตัดสินใจว่าจะคัดลอกโค้ด แยกออกเป็น library หรือผลักฟังก์ชันการทำงานที่ใช้ร่วมกันเข้า ไปเป็น service ด้วย monolith ตัวเลือกของเราง่ายกว่ามาก และหลายคนชอบความง่ายนั้น—โค้ดทั้งหมดอยู่ตรงนั้น ใช้มันได้เลย!

น่าเสียดายที่ผู้คน มองว่า monolith เป็นสิ่งที่ควรหลีกเลี่ยง—เป็นสิ่งที่มีปัญหาในตัวมันเอง ผมเคยพบหลายคนที่มองว่าคำว่า monolith เป็นคำพ้องกับ legacy นี่คือปัญหา สถาปัตยกรรมแบบ monolithic เป็นทางเลือกหนึ่ง และเป็นทางเลือกที่ใช้ได้จริง ผมขอไปไกลกว่านั้นอีก และบอกว่าในความเห็นของผมมันคือทางเลือกเริ่มต้นที่สมเหตุสมผลในฐานะสไตล์สถาปัตยกรรม กล่าวอีกนัยหนึ่ง ผมกำลัง มองหาเหตุผลที่จะถูกโน้มน้าวให้ใช้ microservices มากกว่าที่จะมองหาเหตุผลที่จะไม่ใช้มัน

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