Pluggable, Modular Microservices (ไมโครเซอร์วิสแบบเสียบปลั๊กได้และเป็นโมดูล)
ที่ FinanceCo ผมเห็นความท้าทายที่น่าสนใจเกี่ยวกับไมโครเซอร์วิสตัวหนึ่งที่กำลังกลายเป็นคอขวดของหลายทีม สำหรับแต่ละประเทศ FinanceCo มีทีมเฉพาะที่โฟกัสไปที่ฟังก์ชันการทำงานเฉพาะประเทศนั้นๆ ซึ่งสมเหตุสมผลมาก เพราะแต่ละประเทศก็มีข้อกำหนดและความท้าทายเฉพาะตัว แต่มันสร้างปัญหาให้กับเซอร์วิสกลางนี้ ซึ่งต้องการให้มีการอัปเดตฟังก์ชันการทำงานเฉพาะสำหรับแต่ละประเทศ ทีมที่เป็นเจ้าของไมโครเซอร์วิสกลางนี้ถูกถล่มด้วย pull request ที่ส่งเข้ามา ทีมทำงานได้ดีเยี่ยมในการประมวลผล pull request เหล่านี้อย่างรวดเร็ว และอันที่จริงก็โฟกัสว่านี่เป็นส่วนหลักของความรับผิดชอบของตัวเอง แต่ในเชิงโครงสร้างแล้วสถานการณ์นี้ก็ไม่ยั่งยืนจริงๆ
นี่เป็นตัวอย่างที่การที่ทีมหนึ่งมี pull request จำนวนมากอาจเป็นสัญญาณของปัญหาที่เป็นไปได้หลายอย่าง pull request จากทีมอื่นได้รับการพิจารณาอย่างจริงจังหรือไม่? หรือ pull request เหล่านี้เป็นสัญญาณว่าไมโครเซอร์วิสนี้ควรเปลี่ยนความเป็นเจ้าของหรือไม่?
Warning
ถ้าทีมหนึ่งมี pull request ขาเข้าจำนวนมาก นั่นอาจเป็นสัญญาณว่าคุณมีไมโครเซอร์วิสที่ถูกใช้ร่วมกันโดยหลายทีมจริงๆ
Changing ownership (การเปลี่ยนความเป็นเจ้าของ)
บางครั้ง สิ่งที่ถูกต้องที่ควรทำคือการเปลี่ยนว่าใครเป็นเจ้าของไมโครเซอร์วิส ลองพิจารณาตัวอย่างใน MusicCorp ทีม Customer Engagement ต้องส่ง pull request จำนวนมากที่เกี่ยวข้องกับไมโครเซอร์วิส Recommendation ไปยังทีม Marketing and Promotions เพราะมีการเปลี่ยนแปลงหลายอย่างเกิดขึ้นในเรื่องของวิธีจัดการข้อมูลลูกค้า และเพราะเราต้องแสดงคำแนะนำเหล่านี้ในหลายรูปแบบด้วย
ในสถานการณ์นี้ อาจสมเหตุสมผลที่ทีม Customer Engagement จะรับความเป็นเจ้าของไมโครเซอร์วิส Recommendation ไปเลย แต่ในกรณีของ FinanceCo ไม่มีตัวเลือกแบบนี้อยู่ ปัญหาคือ pull request มาจากทีมที่ หลากหลาย ทีม แล้วยังมีอะไรที่ทำได้อีกบ้าง?
Run multiple variations (รันหลายเวอร์ชันคู่ขนานกัน)
ตัวเลือกหนึ่งที่เราสำรวจคือให้แต่ละทีมประเทศรันไมโครเซอร์วิสที่ใช้ร่วมกันในเวอร์ชันของตัวเอง ดังนั้นทีมสหรัฐฯ ก็รันเวอร์ชันของตัวเอง ทีมสิงคโปร์ก็รันเวอร์ชันของตัวเอง และอื่นๆ
แน่นอนว่าปัญหาของวิธีนี้คือการซ้ำซ้อนของโค้ด ไมโครเซอร์วิสที่ใช้ร่วมกันนี้ implement ชุดพฤติกรรมมาตรฐานและกฎทั่วไป แต่ก็ต้องการให้ฟังก์ชันการทำงาน บางส่วนนี้ เปลี่ยนแปลงได้สำหรับแต่ละประเทศ เราไม่อยากซ้ำซ้อนฟังก์ชันการทำงาน ส่วนที่ใช้ร่วมกัน แนวคิดคือให้ทีมที่ดูแลไมโครเซอร์วิสที่ใช้ร่วมกันในตอนนี้ จัดหา framework แทน ซึ่งจริงๆ แล้วก็คือไมโครเซอร์วิสเดิมที่มีเฉพาะฟังก์ชันการทำงานส่วนที่ใช้ร่วมกันเท่านั้น แต่ละทีมประเทศสามารถ launch instance ของไมโครเซอร์วิสโครงร่างนี้ของตัวเอง แล้วเสียบปลั๊กฟังก์ชันการทำงานเฉพาะของตัวเองเข้าไป ดังที่แสดงใน Figure 15-4 .
Figure 15-4. Framework ทั่วไปสามารถให้หลายทีมรันไมโครเซอร์วิสตัวเดียวกันในหลายเวอร์ชันคู่ขนานกันได้
สิ่งสำคัญที่ต้องสังเกตตรงนี้คือ แม้ว่าเราจะสามารถใช้ฟังก์ชันการทำงานร่วมกันในตัวอย่างนี้ข้ามแต่ละเวอร์ชันเฉพาะประเทศของไมโครเซอร์วิสได้ แต่ฟังก์ชันการทำงานที่ใช้ร่วมกันนี้ก็ไม่สามารถอัปเดตในทุกเวอร์ชันของไมโครเซอร์วิสพร้อมกันได้ โดยไม่ต้องใช้การ release แบบ lockstep ขนาดใหญ่ core team ที่ดูแล framework อาจปล่อยเวอร์ชันใหม่ออกมา แต่ก็ขึ้นอยู่กับแต่ละทีมที่จะดึงโค้ดร่วมเวอร์ชันล่าสุดมาใช้และ deploy ใหม่เอง ในสถานการณ์เฉพาะนี้ FinanceCo โอเคกับข้อจำกัดนี้
ควรเน้นย้ำว่าสถานการณ์เฉพาะนี้ค่อนข้างหายาก และเป็นสิ่งที่ผมเจอแค่หนึ่งหรือสองครั้งเท่านั้น ตอนแรกผมโฟกัสไปที่การหาวิธีแยกความรับผิดชอบของไมโครเซอร์วิสกลางที่ใช้ร่วมกันนี้ออกจากกัน หรือไม่ก็มอบหมายความเป็นเจ้าของใหม่ ความกังวลของผมคือการสร้าง internal framework อาจเป็นกิจกรรมที่เสี่ยงมาก มันง่ายเกินไปที่ framework จะบวมเกินไปหรือจำกัดการพัฒนาของทีมที่ใช้มัน นี่เป็นประเภทของปัญหาที่ไม่ปรากฏให้เห็นตั้งแต่วันแรก เมื่อสร้าง internal framework ทุกอย่างเริ่มต้นด้วยเจตนาที่ดีที่สุด แม้ว่าในสถานการณ์ของ FinanceCo ผมรู้สึกว่ามันเป็นทางออกที่ถูกต้อง แต่ผมก็ขอเตือนไม่ให้รีบใช้แนวทางนี้เร็วเกินไป เว้นแต่คุณจะลองตัวเลือกอื่นๆ จนหมดแล้ว
External contribution through libraries (การส่งงานจากภายนอกผ่านไลบรารี)
อีกแบบหนึ่งของวิธีนี้คือให้แต่ละทีมประเทศส่งไลบรารีที่มีฟังก์ชันการทำงานเฉพาะประเทศของตัวเองอยู่ข้างใน แล้วนำไลบรารีเหล่านี้มาแพ็คเข้าด้วยกันในไมโครเซอร์วิสที่ใช้ร่วมกันตัวเดียว ดังที่แสดงใน Figure 15-5 .
Figure 15-5. ทีมต่างๆ ส่งไลบรารีที่มีพฤติกรรมเฉพาะของตัวเองเข้าไปยัง ไมโครเซอร์วิส ส่วนกลาง
แนวคิดตรงนี้คือ ถ้าทีมสหรัฐฯ ต้องการ implement logic เฉพาะของสหรัฐฯ ก็แค่ทำ การเปลี่ยนแปลงใน ไลบรารีตัวหนึ่ง ซึ่งจากนั้นจะถูกรวมเข้าเป็นส่วนหนึ่งของการ build ของ ไมโครเซอร์วิส ส่วนกลาง
วิธีนี้ลดความจำเป็นในการรันไมโครเซอร์วิสเพิ่มเติม เราไม่จำเป็นต้องรันหนึ่งเซอร์วิสต่อหนึ่งประเทศ—เราสามารถรันไมโครเซอร์วิสกลางตัวเดียวที่จัดการฟังก์ชันการทำงานเฉพาะสำหรับ แต่ละ ประเทศได้ ความท้าทายตรงนี้คือทีมประเทศไม่ได้เป็นผู้ตัดสินใจว่าเมื่อไรฟังก์ชันการทำงานเฉพาะของตัวเองจะถูกนำไปใช้จริง พวกเขาทำการเปลี่ยนแปลงและขอให้ deploy การเปลี่ยนแปลงใหม่นี้ได้ แต่ทีมกลางจะต้องเป็นผู้กำหนดตารางการ deploy นี้
ยิ่งไปกว่านั้น เป็นไปได้ที่บั๊กในไลบรารีเฉพาะประเทศตัวใดตัวหนึ่งอาจทำให้เกิดปัญหาใน production ที่ทีมกลางจะต้องรับผิดชอบแก้ไข ซึ่งอาจทำให้การแก้ปัญหาใน production ซับซ้อนมากขึ้น
ถึงกระนั้น ตัวเลือกนี้ก็อาจคุ้มค่าที่จะพิจารณา ถ้ามันช่วยให้คุณเลิกใช้ไมโครเซอร์วิสกลางแบบ collective ownership ได้ โดยเฉพาะเมื่อคุณไม่สามารถหาเหตุผลมารองรับการรันไมโครเซอร์วิสตัวเดียวกันหลายเวอร์ชันคู่ขนานกันได้
Change Reviews (การรีวิวการเปลี่ยนแปลง)
เมื่อใช้แนวทางโอเพนซอร์สภายในองค์กร แนวคิดของการรีวิวเป็นหลักการหลัก—การเปลี่ยนแปลงต้องถูกรีวิวก่อนที่จะได้รับการยอมรับ แต่แม้ในตอนที่ทำงานภายในทีมกับ codebase ที่คุณมีสิทธิ์ commit ได้โดยตรง การให้คนอื่นรีวิวการเปลี่ยนแปลงของคุณก็ยังมีคุณค่าอยู่ดี
ผมชอบให้คนอื่นรีวิวการเปลี่ยนแปลงของผมมาก ผมรู้สึกเสมอว่าโค้ดของผมได้ประโยชน์จากสายตาคู่ที่สอง รูปแบบการรีวิวที่ผมชอบที่สุดคือการรีวิวแบบทันทีที่ได้จากการทำ pair programming คุณและนักพัฒนาอีกคนเขียนโค้ดด้วยกันและพูดคุยเกี่ยวกับการเปลี่ยนแปลงกัน มันถูกรีวิวก่อนที่คุณจะ check in ด้วยซ้ำ
คุณไม่ต้องเชื่อคำพูดของผมเพียงอย่างเดียว กลับไปที่ Accelerate หนังสือที่เราอ้างอิงมาหลายครั้งแล้ว:
เราพบว่าการต้องขออนุมัติเฉพาะการเปลี่ยนแปลงที่มีความเสี่ยงสูงไม่มีความสัมพันธ์กับประสิทธิภาพการส่งมอบซอฟต์แวร์ ทีมที่รายงานว่าไม่มีขั้นตอนการขออนุมัติหรือใช้ peer review ได้ประสิทธิภาพการส่งมอบซอฟต์แวร์ที่สูงกว่า สุดท้าย ทีมที่ต้องขออนุมัติจากหน่วยงานภายนอกได้ประสิทธิภาพที่ต่ำกว่า
ตรงนี้เราเห็นความแตกต่างระหว่าง peer review กับการรีวิวจากภายนอก peer change review ทำโดยคนที่ส่วนใหญ่แล้วอยู่ในทีมเดียวกับคุณ และทำงานกับ codebase เดียวกับคุณ พวกเขาย่อมอยู่ในตำแหน่งที่ดีกว่าในการประเมินว่าอะไรคือการเปลี่ยนแปลงที่ดี และมักจะทำการรีวิวได้เร็วกว่าด้วย (จะพูดถึงเรื่องนี้อีกสักครู่) แต่การรีวิวจากภายนอกมักมีปัญหามากกว่าเสมอ เพราะบุคคลนั้นอยู่นอกทีมของคุณ พวกเขาจึงมักจะประเมินการเปลี่ยนแปลงตามรายการเกณฑ์ที่อาจสมเหตุสมผลหรือไม่ก็ได้ และเนื่องจากพวกเขาอยู่ทีมอื่น พวกเขาอาจไม่ได้มารีวิวการเปลี่ยนแปลงของคุณสักพักใหญ่ๆ ดังที่ผู้เขียน Accelerate ระบุไว้ว่า:
มีโอกาสแค่ไหนที่หน่วยงานภายนอกซึ่งไม่คุ้นเคยกับรายละเอียดภายในของระบบอย่างลึกซึ้ง จะสามารถรีวิวโค้ดที่เปลี่ยนแปลงนับหมื่นบรรทัดจากวิศวกรหลายร้อยคน และประเมินผลกระทบต่อระบบ production ที่ซับซ้อนได้อย่างแม่นยำ ?
ดังนั้นโดยทั่วไปแล้ว เราต้องการใช้ peer change review และหลีกเลี่ยงความจำเป็นในการรีวิวโค้ดจากภายนอก
Synchronous versus asynchronous code reviews (การรีวิวโค้ดแบบ synchronous เทียบกับ asynchronous)
ด้วย pair programming การรีวิวโค้ดจะเกิดขึ้นแบบ inline ในขณะที่โค้ดกำลังถูกเขียน อันที่จริงมันมากกว่านั้นด้วยซ้ำ เมื่อ pairing กันคุณจะมี driver (คนที่นั่งอยู่หน้าคีย์บอร์ด) และ navigator (ที่ทำหน้าที่เป็นสายตาคู่ที่สอง) ทั้งสองคนสนทนากันตลอดเวลาเกี่ยวกับการเปลี่ยนแปลงที่กำลังทำ—การรีวิวและการเปลี่ยนแปลงเกิดขึ้นพร้อมกัน การรีวิวจึงกลายเป็นแง่มุมที่แฝงอยู่และต่อเนื่องของความสัมพันธ์แบบ pairing นั่นหมายความว่าเมื่อพบปัญหา มันก็จะถูกแก้ทันที
ถ้าคุณไม่ได้ pairing กัน สถานการณ์ในอุดมคติคือการรีวิวควรเกิดขึ้นอย่างรวดเร็วมากหลังจากเขียนโค้ดเสร็จ และคุณอยากให้การรีวิวเองเป็นแบบ synchronous ให้มากที่สุดเท่าที่จะทำได้ คุณอยากพูดคุยโดยตรงกับผู้รีวิวเกี่ยวกับปัญหาที่พวกเขาพบ ตกลงร่วมกันในแนวทางแก้ไข ทำการเปลี่ยนแปลง แล้วเดินหน้าต่อ
ยิ่งคุณได้ feedback เกี่ยวกับการเปลี่ยนแปลงโค้ดเร็วเท่าไร คุณก็ยิ่งสามารถดู feedback นั้น ประเมินมัน ขอความชัดเจนเพิ่มเติม พูดคุยปัญหาให้ลึกขึ้นถ้าจำเป็น และท้ายที่สุดก็ทำการเปลี่ยนแปลงที่จำเป็นได้เร็วขึ้น ยิ่งใช้เวลานานขึ้นระหว่างการส่งการเปลี่ยนแปลงโค้ดเพื่อรีวิวกับการรีวิวที่เกิดขึ้นจริง สิ่งต่างๆ ก็จะยิ่งใช้เวลานานขึ้นและยากขึ้น
ถ้าคุณส่งการเปลี่ยนแปลงโค้ดเพื่อรีวิวและไม่ได้รับ feedback เกี่ยวกับการเปลี่ยนแปลงนั้นจนกระทั่งหลายวันต่อมา คุณก็คงย้ายไปทำงานอื่นแล้ว การจะประมวลผล feedback นั้น คุณต้องเปลี่ยน context และกลับมาทำงานที่ทำไปก่อนหน้านี้ใหม่อีกครั้ง คุณอาจเห็นด้วยกับการเปลี่ยนแปลงที่ผู้รีวิวเสนอ (ถ้าจำเป็น) ซึ่งในกรณีนั้นคุณก็แค่ทำการเปลี่ยนแปลงและส่งขออนุมัติใหม่ กรณีเลวร้ายที่สุดคือคุณอาจต้องพูดคุยเพิ่มเติมเกี่ยวกับประเด็นที่ถูกหยิบยกขึ้นมา การไปมาแบบ asynchronous ระหว่างผู้ส่งงานกับผู้รีวิวนี้อาจเพิ่มเวลาเป็น วัน ให้กับกระบวนการทำการเปลี่ยนแปลง