13

ARCHITECT FOR LOW-RISK RELEASES (ออกแบบสถาปัตยกรรมเพื่อการปล่อยซอฟต์แวร์ที่มีความเสี่ยงต่ำ)

O rganizations อย่าง LinkedIn, Google, eBay, Amazon และ Etsy ต่างก็เคยเผชิญสถานการณ์เกือบวิกฤตจากปัญหาด้านสถาปัตยกรรมมาก่อน ในแต่ละกรณี พวกเขาสามารถโยกย้ายไปสู่สถาปัตยกรรมที่เหมาะสมกว่า ซึ่งตอบโจทย์ปัญหาปัจจุบันและความต้องการขององค์กรได้สำเร็จ

นี่คือหลักการของ evolutionary architecture — Jez Humble กล่าวว่าสถาปัตยกรรมของ "ผลิตภัณฑ์หรือองค์กรที่ประสบความสำเร็จใดๆ ก็ตามย่อมต้องวิวัฒนาการไปตลอดวงจรชีวิตของมันอย่างหลีกเลี่ยงไม่ได้" 1 ก่อนที่จะมาร่วมงานกับ Google นั้น Randy Shoup เคยดำรงตำแหน่ง Chief Engineer และ Distinguished Architect ที่ eBay ตั้งแต่ปี 2004 ถึง 2011 เขาสังเกตว่า "ทั้ง eBay และ Google ต่างก็เขียนสถาปัตยกรรมของตัวเองใหม่ทั้งหมดเป็นครั้งที่ห้าแล้ว" 2

เขาสะท้อนว่า "เมื่อมองย้อนกลับไปด้วย hindsight 20/20 เทคโนโลยี [และตัวเลือกทางสถาปัตยกรรม] บางอย่างดูเฉียบคม แต่บางอย่างก็ดูขาดวิสัยทัศน์ การตัดสินใจแต่ละครั้งน่าจะตอบสนองเป้าหมายขององค์กรในเวลานั้นได้ดีที่สุด ถ้าเราพยายามทำสิ่งที่เทียบเท่ากับ microservices ในปี 1995 ตั้งแต่แรกเริ่ม เราคงล้มเหลว พังทลายลงภายใต้น้ำหนักของตัวเราเอง และอาจลากทั้งบริษัทลงไปด้วย" 3 *

ความท้าทายคือเราจะโยกย้ายจากสถาปัตยกรรมที่เรามีอยู่ไปสู่สถาปัตยกรรมที่เราต้องการได้อย่างไร ในกรณีของ eBay เมื่อพวกเขาจำเป็นต้อง re-architect พวกเขาจะเริ่มจากโปรเจกต์ pilot เล็กๆ ก่อนเพื่อพิสูจน์ให้ตัวเองเห็นว่าพวกเขาเข้าใจปัญหาดีพอที่จะลงมือทำ ตัวอย่างเช่น เมื่อทีมของ Shoup วางแผนจะย้ายบางส่วนของไซต์ไปใช้ full-stack Java ในปี 2006 พวกเขามองหาส่วนที่ให้ผลตอบแทนสูงที่สุด โดยจัดเรียงหน้าไซต์ตามรายได้ที่สร้าง พวกเขาเลือกส่วนที่สร้างรายได้สูงสุด และหยุดเมื่อผลตอบแทนทางธุรกิจไม่คุ้มกับความพยายามอีกต่อไป 5

สิ่งที่ทีมของ Shoup ทำที่ eBay คือตัวอย่างของ evolutionary design โดยใช้เทคนิคที่เรียกว่า strangler fig application pattern —แทนที่จะ "ถอนรากถอนโคนและแทนที่" service เก่าด้วยสถาปัตยกรรมที่ไม่ตอบโจทย์เป้าหมายขององค์กรอีกต่อไป เราจะนำฟังก์ชันการทำงานที่มีอยู่ไปไว้เบื้องหลัง API และหยุดแก้ไขเพิ่มเติม จากนั้นฟังก์ชันใหม่ทั้งหมดจะถูก implement ใน service ใหม่ที่ใช้สถาปัตยกรรมที่ต้องการ และเรียกใช้งานระบบเก่าเมื่อจำเป็นเท่านั้น

Strangler fig application pattern มีประโยชน์อย่างยิ่งในการช่วยย้ายบางส่วนของ monolithic application หรือ service ที่ coupled กันแน่นเกินไปไปสู่สถาปัตยกรรมที่ loosely coupled มากขึ้น บ่อยครั้งที่เราพบว่าตัวเองต้องทำงานภายในสถาปัตยกรรมที่ coupled และ interconnected กันมากเกินไป ซึ่งมักถูกสร้างขึ้นเมื่อหลายปี (หรือหลายทศวรรษ) ที่แล้ว

ผลที่ตามมาของสถาปัตยกรรมที่ tight เกินไปนั้นสังเกตได้ไม่ยาก: ทุกครั้งที่เราพยายาม commit โค้ดเข้า trunk หรือ release โค้ดขึ้น production เราก็เสี่ยงที่จะสร้าง global failures (เช่น เราไปทำลาย test หรือฟังก์ชันการทำงานของคนอื่นทั้งหมด หรือทั้งไซต์ล่ม) เพื่อหลีกเลี่ยงปัญหานี้ การเปลี่ยนแปลงเล็กๆ น้อยๆ ทุกครั้งจึงต้องใช้การสื่อสารและการประสานงานจำนวนมหาศาลกินเวลาหลายวันหรือหลายสัปดาห์ รวมถึงต้องขออนุมัติจากทุกกลุ่มที่อาจได้รับผลกระทบ

การ deploy ก็กลายเป็นปัญหาตามไปด้วย—จำนวนการเปลี่ยนแปลงที่ถูกรวมเข้าด้วยกันในแต่ละ deployment เพิ่มมากขึ้น ทำให้ความพยายามในการ integration และ test ซับซ้อนยิ่งขึ้น และเพิ่มโอกาสที่สิ่งผิดพลาดจะเกิดขึ้นซึ่งสูงอยู่แล้วให้สูงขึ้นไปอีก

แม้แต่การ deploy การเปลี่ยนแปลงเล็กๆ ก็อาจต้องประสานงานกับนักพัฒนาหลายร้อยคน (หรือหลายพันคน) โดยที่ใครก็ตามในนั้นสามารถสร้างความเสียหายร้ายแรงที่อาจต้องใช้เวลาหลายสัปดาห์ในการค้นหาและแก้ไข (ซึ่งนำไปสู่อีกอาการหนึ่ง: "นักพัฒนาของผมใช้เวลาเขียนโค้ดแค่ 15% เท่านั้น—เวลาที่เหลือหมดไปกับการประชุม")

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

จากมุมมองของ enterprise architecture วงจรขาลงนี้เป็นผลมาจาก Second Law of Architectural Thermodynamics โดยเฉพาะในองค์กรขนาดใหญ่และซับซ้อน Charles Betz ผู้เขียน Architecture and Patterns for IT: Service Management, Resource Planning, and Governance: Making Shoes for the Cobbler's Children กล่าวว่า "[เจ้าของโปรเจกต์ IT] ไม่ถูกทำให้รับผิดชอบต่อการเพิ่ม entropy ของระบบโดยรวม" 6 กล่าวอีกนัยหนึ่ง การลดความซับซ้อนโดยรวมและเพิ่ม productivity ของทีมพัฒนาทั้งหมดนั้นแทบจะไม่เคยเป็นเป้าหมายของโปรเจกต์ใดโปรเจกต์หนึ่งเลย

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

An Architecture that Enables Productivity, Testability, and Safety (สถาปัตยกรรมที่ขับเคลื่อน Productivity, Testability และความปลอดภัย)

ในทางตรงกันข้ามกับสถาปัตยกรรมแบบ tightly coupled ที่ขัดขวาง productivity และความสามารถในการเปลี่ยนแปลงอย่างปลอดภัยของทุกคน สถาปัตยกรรมแบบ loosely coupled ที่มี interface ที่ชัดเจนซึ่งกำหนดวิธีการเชื่อมต่อระหว่าง module กลับช่วยส่งเสริม productivity และความปลอดภัย มันช่วยให้ทีมขนาดเล็กที่มีประสิทธิภาพสามารถทำการเปลี่ยนแปลงเล็กๆ น้อยๆ ที่สามารถ deploy ได้อย่างปลอดภัยและเป็นอิสระต่อกัน และเนื่องจากแต่ละ service มี API ที่ชัดเจน มันจึงช่วยให้การทดสอบ service และการสร้าง contract รวมถึง SLA ระหว่างทีมทำได้ง่ายขึ้น

Figure 13.1: Google Cloud Datastore

ที่มา: Shoup, "From the Monolith to Micro-services."

Randy Shoup อธิบายว่า

สถาปัตยกรรมแบบนี้ใช้ได้ผลดีอย่างมากกับ Google — สำหรับ service อย่าง Gmail นั้นมี service อีกห้าหรือหกชั้นอยู่ข้างใต้ แต่ละชั้น focus ไปที่ฟังก์ชันเฉพาะเจาะจงมากๆ แต่ละ service ได้รับการสนับสนุนโดยทีมขนาดเล็กที่สร้างและดูแลฟังก์ชันการทำงานของตนเอง โดยแต่ละกลุ่มสามารถเลือกเทคโนโลยีที่แตกต่างกันได้ อีกตัวอย่างคือ Google Cloud Datastore service ซึ่งเป็นหนึ่งใน NoSQL service ที่ใหญ่ที่สุดในโลก — และยังคงได้รับการดูแลโดยทีมที่มีเพียงประมาณแปดคน สาเหตุหลักก็เพราะมันสร้างขึ้นบน layer ซ้อน layer ของ service ที่เชื่อถือได้ซึ่งสร้างต่อกันขึ้นมา 7

สถาปัตยกรรมแนว service-oriented แบบนี้ช่วยให้ทีมเล็กๆ สามารถทำงานกับหน่วยพัฒนาที่เล็กลงและเรียบง่ายขึ้น ซึ่งแต่ละทีมสามารถ deploy ได้อย่างอิสระ รวดเร็ว และปลอดภัย Shoup กล่าวว่า "องค์กรที่มีสถาปัตยกรรมแบบนี้ เช่น Google และ Amazon แสดงให้เห็นว่ามันส่งผลต่อโครงสร้างองค์กรได้อย่างไร [สร้าง] ความยืดหยุ่นและ scalability ที่ยอดเยี่ยม ทั้งสององค์กรนี้มีนักพัฒนาหลายหมื่นคน แต่ทีมเล็กๆ ก็ยังคงทำงานได้อย่างมีประสิทธิภาพอย่างเหลือเชื่อ" 8

Architectural Archetypes: Monoliths vs. Microservices (Archetype ทางสถาปัตยกรรม: Monoliths vs. Microservices)

ในช่วงเวลาหนึ่งของประวัติศาสตร์ องค์กร DevOps ส่วนใหญ่เคยถูกจำกัดด้วยสถาปัตยกรรมแบบ tightly coupled และ monolithic ที่—แม้จะประสบความสำเร็จอย่างมากในการช่วยให้พวกเขาบรรลุ product/market fit—กลับทำให้พวกเขาเสี่ยงต่อความล้มเหลวขององค์กรเมื่อต้องดำเนินการใน scale ที่ใหญ่ขึ้น (เช่น monolithic C++ application ของ eBay ในปี 2001, monolithic Obidos application ของ Amazon ในปี 2001, monolithic Rails front end ของ Twitter ในปี 2009, และ monolithic Leo application ของ LinkedIn ในปี 2011) ในแต่ละกรณี องค์กรเหล่านี้สามารถ re-architect ระบบของตน และไม่เพียงแต่ตั้งหลักรอดเท่านั้น แต่ยังเติบโตและชนะในตลาดได้อีกด้วย

สถาปัตยกรรมแบบ monolithic ไม่ได้แย่ในตัวของมันเอง—อันที่จริงแล้ว มันมักเป็นตัวเลือกที่ดีที่สุดสำหรับองค์กรในช่วงต้นของวงจรชีวิตผลิตภัณฑ์ ดังที่ Randy Shoup กล่าวไว้ว่า

ไม่มีสถาปัตยกรรมใดที่สมบูรณ์แบบสำหรับทุกผลิตภัณฑ์และทุก scale สถาปัตยกรรมแต่ละแบบตอบสนองชุดเป้าหมายหรือช่วงของ requirements และ constraints ที่เฉพาะเจาะจง เช่น time to market, ความง่ายในการพัฒนาฟังก์ชันการทำงาน, scaling ฯลฯ ฟังก์ชันการทำงานของผลิตภัณฑ์หรือ service ใดๆ ก็ตามแทบจะแน่นอนว่าจะวิวัฒนาการไปตามกาลเวลา—จึงไม่ควรแปลกใจที่ความต้องการทางสถาปัตยกรรมของเราก็จะเปลี่ยนไปเช่นกัน สิ่งที่ใช้ได้ดีที่ scale 1x แทบจะไม่เคยใช้ได้ดีที่ scale 10x หรือ 100x 9

archetype หลักของสถาปัตยกรรมแสดงอยู่ใน Table 13.1 แต่ละแถวบ่งบอกถึงความต้องการเชิงวิวัฒนาการที่แตกต่างกันขององค์กร โดยแต่ละคอลัมน์ให้ข้อดีและข้อเสียของแต่ละ archetype ดังที่ตารางแสดงให้เห็น สถาปัตยกรรมแบบ monolithic ที่รองรับ startup (เช่น การ prototyping ฟีเจอร์ใหม่อย่างรวดเร็วและการ pivot หรือการเปลี่ยนแปลงกลยุทธ์ครั้งใหญ่) นั้นแตกต่างอย่างมากจากสถาปัตยกรรมที่ต้องรองรับนักพัฒนาหลายร้อยทีม ซึ่งแต่ละทีมต้องสามารถส่งมอบคุณค่าให้ลูกค้าได้อย่างอิสระ การสนับสนุน evolutionary architectures ทำให้เรามั่นใจได้ว่าสถาปัตยกรรมของเราจะตอบสนองความต้องการปัจจุบันขององค์กรได้เสมอ

Table 13.1: Architectural Archetypes (Archetype ทางสถาปัตยกรรม)

Pros (ข้อดี)

Cons (ข้อเสีย)

Monolithic v1 (ฟังก์ชันทั้งหมดอยู่ใน application เดียวกัน)

• เรียบง่ายในตอนแรก

• latency ระหว่าง process ต่ำ

• code base เดียว; หน่วย deployment เดียว

• ใช้ทรัพยากรอย่างมีประสิทธิภาพใน scale เล็ก

• ค่าใช้จ่ายในการประสานงานเพิ่มขึ้นเมื่อทีมโตขึ้น

• การบังคับใช้ modularity ไม่ดี

• scaling ไม่ดี

• deploy แบบได้ทั้งหมดหรือไม่ได้เลย (downtime, failures)

• build time นาน

Monolithic v2 (ชุดของ monolithic tiers: "front end presentation," "application server," "database layer")

เรียบง่ายในตอนแรก

join query ทำได้ง่าย

schema และ deployment เดียว

ใช้ทรัพยากรอย่างมีประสิทธิภาพใน scale เล็ก

แนวโน้มที่จะเกิด coupling เพิ่มขึ้นเมื่อเวลาผ่านไป

scaling และ redundancy ไม่ดี (all-or-nothing, แนวตั้งเท่านั้น)

ปรับแต่งให้เหมาะสมได้ยาก

การจัดการ schema แบบ all-or-nothing

Microservice (โมดูลาร์, อิสระ, ความสัมพันธ์แบบกราฟ vs. tier, การจัดเก็บแยกอิสระ)

แต่ละหน่วยเรียบง่าย

scaling และ performance เป็นอิสระต่อกัน

testing และ deployment เป็นอิสระต่อกัน

สามารถปรับแต่ง performance ได้อย่างเหมาะสมที่สุด (caching, replication ฯลฯ)

ต้องมีหลายหน่วยที่ทำงานร่วมกัน

มี repo ขนาดเล็กจำนวนมาก

ต้องใช้ tooling และ dependency management ที่ซับซ้อนขึ้น

network latency

ที่มา: Shoup, "From the Monolith to Micro-services."

CASE STUDY (กรณีศึกษา)

Evolutionary Architecture at Amazon (2002) (สถาปัตยกรรมเชิงวิวัฒนาการที่ Amazon ปี 2002)

หนึ่งในตัวอย่างการเปลี่ยนแปลงสถาปัตยกรรมที่มีการศึกษากันมากที่สุดเกิดขึ้นที่ Amazon ในการสัมภาษณ์กับ Jim Gray ผู้ได้รับรางวัล ACM Turing Award และ Microsoft Technical Fellow นั้น Werner Vogels CTO ของ Amazon อธิบายว่า Amazon.com เริ่มต้นในปี 1996 ในฐานะ "monolithic application ที่รันบน web server และคุยกับ database ด้านหลัง โดย application นี้มีชื่อว่า Obidos วิวัฒนาการมาเพื่อรองรับ business logic ทั้งหมด display logic ทั้งหมด และฟังก์ชันการทำงานทั้งหมดที่ทำให้ Amazon กลายเป็นที่รู้จักในที่สุด: similarities, recommendations, Listmania, reviews ฯลฯ" 10

เมื่อเวลาผ่านไป Obidos ก็พันกันยุ่งเหยิงมากขึ้นเรื่อยๆ โดยมีความสัมพันธ์แบบ sharing ที่ซับซ้อน ซึ่งหมายความว่าชิ้นส่วนแต่ละชิ้นไม่สามารถ scale ได้ตามต้องการ Vogels บอกกับ Gray ว่าสิ่งนี้หมายถึง "หลายสิ่งที่คุณอยากให้เกิดขึ้นในสภาพแวดล้อมซอฟต์แวร์ที่ดีไม่สามารถทำได้อีกต่อไปแล้ว มีซอฟต์แวร์ที่ซับซ้อนมากมายถูกรวมเข้าไว้ในระบบเดียว มันไม่สามารถวิวัฒนาการต่อไปได้อีกแล้ว" 11

เมื่ออธิบายถึงแนวคิดเบื้องหลังสถาปัตยกรรมใหม่ที่ต้องการ เขาบอกกับ Gray ว่า "เราผ่านช่วงเวลาของการ introspection อย่างจริงจัง และสรุปได้ว่า service-oriented architecture จะให้ระดับของการแยกส่วน (isolation) ที่จะช่วยให้เราสร้าง component ซอฟต์แวร์ได้มากมายอย่างรวดเร็วและเป็นอิสระ" 12

Vogels กล่าวว่า "การเปลี่ยนแปลงสถาปัตยกรรมครั้งใหญ่ที่ Amazon ผ่านในช่วงห้าปีที่ผ่านมา [ตั้งแต่ปี 2001–2005] คือการย้ายจาก two-tier monolith ไปเป็น fully distributed, decentralized services platform ที่ให้บริการ application ต่างๆ มากมาย จำเป็นต้องมีนวัตกรรมมากมายเพื่อทำให้สิ่งนี้เกิดขึ้น เนื่องจากเราเป็นหนึ่งในกลุ่มแรกๆ ที่ใช้แนวทางนี้" 13 บทเรียนจากประสบการณ์ของ Vogels ที่ Amazon ซึ่งสำคัญต่อความเข้าใจของเราเกี่ยวกับการเปลี่ยนแปลงสถาปัตยกรรม ได้แก่:

• Lesson 1 (บทเรียนที่ 1): เมื่อนำไปใช้อย่างเคร่งครัด strict service orientation เป็นเทคนิคที่ยอดเยี่ยมในการบรรลุการแยกส่วน (isolation) คุณจะได้ระดับของ ownership และ control ที่ไม่เคยเห็นมาก่อน

• Lesson 2 (บทเรียนที่ 2): การห้าม client เข้าถึง database โดยตรงทำให้สามารถทำการปรับปรุง scaling และ reliability ให้กับ service state ของคุณได้โดยไม่ต้องเกี่ยวข้องกับ client

• Lesson 3 (บทเรียนที่ 3): กระบวนการพัฒนาและปฏิบัติการได้รับประโยชน์อย่างมากจากการเปลี่ยนมาใช้ service orientation โมเดล service เป็นปัจจัยสำคัญในการสร้างทีมที่สามารถสร้างนวัตกรรมได้อย่างรวดเร็วโดย focus ที่ลูกค้าอย่างเข้มแข็ง แต่ละ service จะมีทีมที่เกี่ยวข้อง และทีมนั้นจะรับผิดชอบ service อย่างสมบูรณ์—ตั้งแต่การกำหนดขอบเขตฟังก์ชันการทำงานไปจนถึงการออกแบบสถาปัตยกรรม การสร้าง และการดำเนินการ

ขอบเขตที่การนำบทเรียนเหล่านี้ไปใช้ช่วยเพิ่ม productivity และความน่าเชื่อถือของนักพัฒนานั้นน่าทึ่งมาก ในปี 2011 Amazon ทำการ deploy ประมาณหนึ่งหมื่นห้าพันครั้งต่อวัน 14 ภายในปี 2015 พวกเขาทำการ deploy เกือบ 136,000 ครั้งต่อวัน 15

กรณีศึกษานี้แสดงให้เห็นว่าการวิวัฒนาการจากโครงสร้าง monolithic ไปสู่ microservices ช่วยลดการผูกติดของสถาปัตยกรรม (decouple) ทำให้สามารถตอบสนองความต้องการขององค์กรได้ดียิ่งขึ้น

Use the Strangler Fig Application Pattern to Safely Evolve Our Enterprise Architecture (ใช้ Strangler Fig Application Pattern เพื่อวิวัฒนาการ Enterprise Architecture อย่างปลอดภัย)

คำว่า strangler fig application ถูกบัญญัติโดย Martin Fowler ในปี 2004 หลังจากที่เขาได้รับแรงบันดาลใจจากการเห็นเถาวัลย์ strangler มหึมาระหว่างการเดินทางไปออสเตรเลีย เขาเขียนว่า "พวกมันงอกบนกิ่งบนของต้นมะเดื่อ แล้วค่อยๆ เลื้อยลงมาตามต้นจนกระทั่งหยั่งรากลงดิน หลายปีผ่านไป พวกมันเติบโตเป็นรูปร่างที่มหัศจรรย์และสวยงาม ขณะเดียวกันก็รัดและฆ่าต้นไม้ที่เป็นเจ้าบ้าน" 16

ถ้าเราพิจารณาแล้วว่าสถาปัตยกรรมปัจจุบันของเรา coupled กันแน่นเกินไป เราก็สามารถเริ่มแยกส่วน (decouple) บางส่วนของฟังก์ชันการทำงานออกจากสถาปัตยกรรมที่มีอยู่ได้อย่างปลอดภัย การทำเช่นนี้ช่วยให้ทีมที่ดูแลฟังก์ชันการทำงานที่ถูกแยกออกมาสามารถพัฒนา ทดสอบ และ deploy โค้ดของตนขึ้น production ได้อย่างอิสระ ปลอดภัย และลด architectural entropy

ดังที่อธิบายไว้ก่อนหน้านี้ strangler fig application pattern คือการนำฟังก์ชันการทำงานที่มีอยู่ไปไว้เบื้องหลัง API โดยที่มันยังคงไม่เปลี่ยนแปลง และ implement ฟังก์ชันใหม่โดยใช้สถาปัตยกรรมที่ต้องการ พร้อมเรียกใช้ระบบเก่าเมื่อจำเป็น เมื่อเรา implement strangler fig application เราจะพยายามเข้าถึง service ทั้งหมดผ่าน versioned APIs หรือที่เรียกว่า versioned services หรือ immutable services 17

Versioned APIs ช่วยให้เราสามารถแก้ไข service ได้โดยไม่กระทบต่อผู้เรียกใช้งาน ซึ่งทำให้ระบบ loosely coupled มากขึ้น—ถ้าเราต้องการเปลี่ยน argument เราก็สร้าง API version ใหม่และย้ายทีมที่พึ่งพา service ของเราไปยัง version ใหม่ ท้ายที่สุดแล้ว เราจะไม่บรรลุเป้าหมายในการ re-architect ถ้าเราปล่อยให้ strangler fig application ใหม่ของเราไป coupled แน่นกับ service อื่นๆ (เช่น การเชื่อมต่อไปยัง database ของ service อื่นโดยตรง)

ถ้า service ที่เราเรียกใช้งานไม่มี API ที่กำหนดไว้อย่างชัดเจน เราควรสร้างมันขึ้นมา หรืออย่างน้อยก็ซ่อนความซับซ้อนในการสื่อสารกับระบบเหล่านั้นไว้ใน client library ที่มี API ที่กำหนดไว้อย่างชัดเจน

ด้วยการแยกส่วน (decouple) ฟังก์ชันการทำงานออกจากระบบที่ coupled กันแน่นเดิมซ้ำๆ เราจะย้ายงานของเราไปสู่ ecosystem ที่ปลอดภัยและมีชีวิตชีวา ซึ่งนักพัฒนาสามารถทำงานได้อย่างมีประสิทธิภาพมากขึ้น ส่งผลให้ legacy application มีฟังก์ชันการทำงานลดลงเรื่อยๆ และอาจหายไปโดยสิ้นเชิงเมื่อฟังก์ชันที่จำเป็นทั้งหมดถูกย้ายไปยังสถาปัตยกรรมใหม่

การสร้าง strangler fig application ช่วยให้เราหลีกเลี่ยงการทำซ้ำฟังก์ชันการทำงานที่มีอยู่เดิมในสถาปัตยกรรมหรือเทคโนโลยีใหม่—บ่อยครั้งที่กระบวนการทางธุรกิจของเราซับซ้อนเกินความจำเป็นเนื่องจากลักษณะเฉพาะของระบบที่มีอยู่ ซึ่งเราจะเผลอไปทำซ้ำอีก (โดยการวิจัยผู้ใช้ เราสามารถ re-engineer กระบวนการเพื่อออกแบบวิธีที่เรียบง่ายและมีประสิทธิภาพมากขึ้นในการบรรลุเป้าหมายทางธุรกิจ) †

ข้อสังเกตจาก Martin Fowler ชี้ให้เห็นถึงความเสี่ยงนี้

อาชีพส่วนใหญ่ของฉันเกี่ยวข้องกับการเขียนระบบที่สำคัญใหม่ คุณคงคิดว่างานแบบนี้ง่าย—แค่ทำให้ระบบใหม่ทำในสิ่งที่ระบบเก่าทำ แต่ความจริงแล้วมันซับซ้อนกว่าที่คิดเสมอ และเต็มไปด้วยความเสี่ยง วันตัด over-date ครั้งใหญ่ใกล้เข้ามาพร้อมกับแรงกดดันที่เพิ่มขึ้น ในขณะที่ฟีเจอร์ใหม่ (ซึ่งมีมาเสมอ) เป็นที่ชื่นชอบ สิ่งเดิมๆ ก็ยังคงต้องคงอยู่ แม้แต่ bug เก่าๆ ก็มักจะต้องถูกนำเข้ามาในระบบที่เขียนใหม่ 19

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

CASE STUDY (กรณีศึกษา)

Strangler Fig Pattern at Blackboard Learn (2011) (Strangler Fig Pattern ที่ Blackboard Learn ปี 2011)

Blackboard Inc. เป็นหนึ่งในผู้บุกเบิกการให้บริการเทคโนโลยีสำหรับสถาบันการศึกษา โดยมีรายได้ต่อปีประมาณ 650 ล้านดอลลาร์ในปี 2011 ในเวลานั้น ทีมพัฒนาสำหรับผลิตภัณฑ์เรือธง Learn ซึ่งเป็น packaged software ที่ติดตั้งและทำงานบนสถานที่ของลูกค้า กำลังเผชิญกับผลกระทบในชีวิตประจำวันของ legacy J2EE codebase ที่ย้อนกลับไปถึงปี 1997 20 ดังที่ David Ashman หัวหน้าสถาปนิกของพวกเขากล่าวว่า "เรายังมีเศษของ Perl code ที่ฝังอยู่ทั่ว codebase ของเรา" 21

ในปี 2010 Ashman focus ไปที่ความซับซ้อนและ lead time ที่เพิ่มขึ้นของระบบเก่า โดยสังเกตว่า "กระบวนการ build, integration และ testing ของเราเริ่มซับซ้อนและมีข้อผิดพลาดมากขึ้นเรื่อยๆ และยิ่งผลิตภัณฑ์ใหญ่ขึ้นเท่าไหร่ lead time ก็ยิ่งนานขึ้นและผลลัพธ์สำหรับลูกค้าก็ยิ่งแย่ลงเท่านั้น เพื่อให้ได้ feedback จากกระบวนการ integration ของเรา ต้องใช้เวลายี่สิบสี่ถึงสามสิบหกชั่วโมง" 22

ผลกระทบที่เริ่มมีต่อ productivity ของนักพัฒนาเริ่มปรากฏชัดเจนในกราฟที่สร้างจาก repository ซอร์สโค้ดของพวกเขาที่มีข้อมูลย้อนหลังไปถึงปี 2005

ใน Figure 13.2 กราฟด้านบนแสดงจำนวนบรรทัดโค้ดใน monolithic Blackboard Learn code repository ส่วนกราฟด้านล่างแสดงจำนวน code commits ปัญหาที่ชัดเจนสำหรับ Ashman คือจำนวน code commits เริ่มลดลง ซึ่งแสดงให้เห็นถึงความยากที่เพิ่มขึ้นในการนำการเปลี่ยนแปลงโค้ดเข้าไป ในขณะที่จำนวนบรรทัดโค้ดยังคงเพิ่มขึ้นอย่างต่อเนื่อง Ashman กล่าวว่า "สำหรับผม นั่นหมายความว่าเราต้องทำอะไรสักอย่าง ไม่เช่นนั้นปัญหาก็จะยิ่งแย่ลงไปเรื่อยๆ โดยไม่มีที่สิ้นสุด" 23

Figure 13.2: Blackboard Learn Code Repository: ก่อน Building Blocks

ที่มา: "DOES14—David Ashman—Blackboard Learn—Keep Your Head in the Clouds," วิดีโอ YouTube, 30:43, โพสต์โดย DevOps Enterprise Summit 2014, 28 ตุลาคม 2014, https://www.youtube.com/watch?v=SSmixnMpsI4 .

ด้วยเหตุนี้ ในปี 2012 Ashman จึง focus ไปที่การดำเนินโปรเจกต์ re-architecting โค้ดโดยใช้ strangler fig pattern ทีมงานทำสิ่งนี้โดยสร้างสิ่งที่พวกเขาเรียกภายในว่า Building Blocks ซึ่งช่วยให้นักพัฒนาสามารถทำงานใน module ที่แยกออกจากกัน ซึ่ง decoupled จาก monolithic codebase และเข้าถึงผ่าน fixed APIs สิ่งนี้ช่วยให้พวกเขาทำงานได้อย่างอิสระมากขึ้น โดยไม่ต้องสื่อสารและประสานงานกับทีมพัฒนาอื่นๆ ตลอดเวลา

เมื่อ Building Blocks พร้อมให้บริการแก่นักพัฒนา ขนาดของ monolith source code repository เริ่มลดลง (วัดจากจำนวนบรรทัดโค้ด) Ashman อธิบายว่าสาเหตุเป็นเพราะนักพัฒนากำลังย้ายโค้ดของตนไปยัง Building Block modules source code repository "อันที่จริงแล้ว" Ashman รายงานว่า "นักพัฒนาทุกคนถ้าเลือกได้ก็จะทำงานใน Building Block codebase ซึ่งพวกเขาสามารถทำงานได้อย่างอิสระ มีอิสระมากขึ้น และปลอดภัยมากขึ้น" 24

Figure 13.3 แสดงความสัมพันธ์ระหว่างการเติบโตแบบ exponential ของจำนวนบรรทัดโค้ดและการเติบโตแบบ exponential ของจำนวน code commits สำหรับ Building Blocks code repositories Building Blocks codebase ใหม่ช่วยให้นักพัฒนาทำงานได้อย่างมีประสิทธิภาพมากขึ้น และทำให้งานปลอดภัยขึ้นเพราะข้อผิดพลาดส่งผลให้เกิดความล้มเหลวเล็กๆ ในพื้นที่ แทนที่จะเป็นภัยพิบัติใหญ่ที่กระทบต่อระบบโดยรวม

Figure 13.3: Blackboard Learn Code Repository: หลัง Building Blocks

ที่มา: "DOES14—David Ashman—Blackboard Learn—Keep Your Head in the Clouds," วิดีโอ YouTube, 30:43, โพสต์โดย DevOps Enterprise Summit 2014, 28 ตุลาคม 2014, https://www.youtube.com/watch?v=SSmixnMpsI4 .

Ashman สรุปว่า "การให้นักพัฒนาทำงานในสถาปัตยกรรม Building Blocks ทำให้เกิดการปรับปรุงที่ยอดเยี่ยมในด้าน modularity ของโค้ด ช่วยให้พวกเขาทำงานได้อย่างอิสระและมีอิสระมากขึ้น เมื่อรวมกับการอัปเดตกระบวนการ build ของเรา พวกเขายังได้รับ feedback ที่เร็วขึ้นและดีขึ้นเกี่ยวกับงานของพวกเขา ซึ่งหมายถึงคุณภาพที่ดีขึ้น" 25

การใช้ Strangler Fig Application Pattern และการสร้าง codebase แบบ modular ทำให้ทีมที่ Blackboard สามารถทำงานได้อย่างอิสระมากขึ้น และจัดการปัญหาแต่ละอย่างได้อย่างปลอดภัยและรวดเร็วยิ่งขึ้น

Continuous Learning (การเรียนรู้อย่างต่อเนื่อง)

ข้อมูลสนับสนุนความสำคัญของสถาปัตยกรรมและบทบาทในการขับเคลื่อนประสิทธิภาพระดับสูง โดยรายงาน State of DevOps Report ของ DORA และ Puppet ปี 2017 พบว่าสถาปัตยกรรมเป็นปัจจัยที่ใหญ่ที่สุดที่ส่งผลต่อ continuous delivery

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

ผลการค้นพบเหล่านี้สะท้อนอีกครั้งในรายงาน State of DevOps Report ของ DORA ปี 2018 และ 2019 ซึ่งแสดงให้เห็นถึงความสำคัญอย่างต่อเนื่องของการมีสถาปัตยกรรมแบบ loosely coupled ต่อความสามารถของทีมในการ deploy และ release อย่างรวดเร็วและมี friction ต่ำ 27

Conclusion (บทสรุป)

ในระดับที่สำคัญ สถาปัตยกรรมที่ service ของเราทำงานอยู่เป็นตัวกำหนดว่าเราทดสอบและ deploy โค้ดของเราอย่างไร เนื่องจากเรามักจะติดอยู่กับสถาปัตยกรรมที่ถูกปรับให้เหมาะสมกับเป้าหมายขององค์กรที่แตกต่างกัน หรือกับยุคสมัยที่ผ่านพ้นไปนานแล้ว เราจึงต้องสามารถโยกย้ายจากสถาปัตยกรรมหนึ่งไปยังอีกสถาปัตยกรรมหนึ่งได้อย่างปลอดภัย กรณีศึกษาในบทนี้ รวมถึงกรณีศึกษาของ Amazon ที่นำเสนอก่อนหน้านี้ อธิบายเทคนิคต่างๆ อย่างเช่น strangler fig pattern ที่สามารถช่วยให้เราโยกย้ายระหว่างสถาปัตยกรรมได้แบบ incremental ทำให้เราสามารถปรับตัวให้เข้ากับความต้องการขององค์กรได้