Monorepositories: ได้โปรดต้อง

Monorepositories: ได้โปรดต้อง

แปลบทความที่จัดทำขึ้นสำหรับนักศึกษารายวิชา "แนวทางปฏิบัติและเครื่องมือ DevOps" ในโครงการการศึกษา OTUS

คุณควรเลือก monorepository เนื่องจากพฤติกรรมที่ส่งเสริมในทีมของคุณคือความโปร่งใสและความรับผิดชอบร่วมกัน โดยเฉพาะอย่างยิ่งเมื่อทีมเติบโตขึ้น ไม่ว่าจะด้วยวิธีใด คุณจะต้องลงทุนในเครื่องมือ แต่จะดีกว่าเสมอหากพฤติกรรมเริ่มต้นคือพฤติกรรมที่คุณต้องการในคำสั่งของคุณ

ทำไมเราถึงพูดถึงเรื่องนี้?

Matt Klein เขียนบทความ "Monorepos: ได้โปรดอย่า!"  (หมายเหตุผู้แปล: การแปลในHabré “ Monorepositories: โปรดอย่า”). ฉันชอบแมตต์ ฉันคิดว่าเขาฉลาดมากและคุณควรอ่านมุมมองของเขา เดิมทีเขาโพสต์แบบสำรวจบน Twitter:

Monorepositories: ได้โปรดต้อง

แปล:
วันปีใหม่นี้ ฉันจะเถียงว่า monorepositories ไร้สาระแค่ไหน 2019 เริ่มต้นอย่างเงียบๆ ด้วยเหตุนี้ ฉันจึงเสนอแบบสำรวจให้คุณ ใครคือผู้คลั่งไคล้ตัวยง? ผู้สนับสนุน:
- โมโนเรโป
- สนิม
- แบบสำรวจไม่ถูกต้อง / ทั้งสองอย่าง

คำตอบของฉันคือ “ฉันเป็นทั้งสองคนจริงๆ” แทนที่จะพูดถึงว่า Rust เป็นยาอย่างไร เรามาดูกันว่าเหตุใดฉันจึงคิดว่าเขาผิดเกี่ยวกับ monorepositories เล็กน้อยเกี่ยวกับตัวคุณเอง ฉันเป็น CTO ของ Chef Software เรามีวิศวกรประมาณ 100 คน รหัสพื้นฐานย้อนกลับไปประมาณ 11-12 ปี และผลิตภัณฑ์หลัก 4 รายการ รหัสนี้บางส่วนอยู่ใน polyrepository (ตำแหน่งเริ่มต้นของฉัน) บางส่วนอยู่ใน monorepository (ตำแหน่งปัจจุบันของฉัน)

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

ฉันเห็นด้วยกับส่วนแรกของประเด็นของ Matt:

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

คุณจะต้องแก้ไขปัญหาเดียวกันไม่ว่าคุณจะเลือก monorepository หรือ polyrepository คุณจะเผยแพร่การเผยแพร่อย่างไร? คุณมีวิธีการอัปเดตอย่างไร? ความเข้ากันได้แบบย้อนหลัง? การพึ่งพาข้ามโครงการ? รูปแบบสถาปัตยกรรมใดที่ยอมรับได้? คุณจะจัดการโครงสร้างพื้นฐานในการสร้างและทดสอบของคุณอย่างไร รายการไม่มีที่สิ้นสุด และคุณจะแก้ปัญหาทั้งหมดได้เมื่อคุณเติบโต ไม่มีชีสฟรี

ฉันคิดว่าข้อโต้แย้งของ Matt นั้นคล้ายคลึงกับความคิดเห็นที่วิศวกร (และผู้จัดการ) หลายคนแบ่งปันกันที่ฉันเคารพ สิ่งนี้เกิดขึ้นจากมุมมองของวิศวกรที่ทำงานเกี่ยวกับส่วนประกอบหรือทีมงานที่ทำงานเกี่ยวกับส่วนประกอบ คุณจะได้ยินสิ่งต่างๆ เช่น:

  • Codebase มีขนาดใหญ่ - ฉันไม่ต้องการขยะทั้งหมดนี้
  • การทดสอบยากกว่าเพราะฉันต้องทดสอบขยะทั้งหมดนี้ที่ฉันไม่ต้องการ
  • การทำงานกับการพึ่งพาภายนอกทำได้ยากกว่า
  • ฉันต้องการระบบควบคุมเวอร์ชันเสมือนของตัวเอง

แน่นอนว่าประเด็นทั้งหมดนี้สมเหตุสมผล สิ่งนี้เกิดขึ้นในทั้งสองกรณี - ใน Polyrepository ฉันมีขยะของตัวเอง นอกเหนือจากขยะที่จำเป็นสำหรับการสร้าง... ฉันอาจต้องการขยะอื่นด้วย ดังนั้นฉันจึง "เพียงแค่" สร้างเครื่องมือที่ตรวจสอบทั้งโปรเจ็กต์ หรือฉันสร้าง monorepository ปลอมด้วยโมดูลย่อย เราสามารถเดินไปรอบๆ ได้ตลอดทั้งวัน แต่ฉันคิดว่าข้อโต้แย้งของ Matt พลาดเหตุผลหลัก ซึ่งฉันกลับหันไปสนับสนุน monorepository ค่อนข้างมาก:

มันกระตุ้นให้เกิดการสื่อสารและแสดงปัญหา

เมื่อเราแยกที่เก็บข้อมูล เราจะสร้างปัญหาเรื่องการประสานงานและความโปร่งใสโดยพฤตินัย สิ่งนี้สอดคล้องกับวิธีที่เราคิดเกี่ยวกับทีม (โดยเฉพาะวิธีที่สมาชิกแต่ละคนคิดเกี่ยวกับพวกเขา): เรามีหน้าที่รับผิดชอบในองค์ประกอบบางอย่าง เราทำงานอย่างโดดเดี่ยว ขอบเขตได้รับการแก้ไขแล้วในทีมของฉันและองค์ประกอบที่เรากำลังดำเนินการอยู่

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

  • ค้นหาสถานที่ทั้งหมดที่ใช้ API เก่า
  • มีจุดที่ไม่สามารถใช้ API ใหม่ได้หรือไม่
  • คุณสามารถแก้ไขและทดสอบส่วนประกอบอื่นๆ เพื่อให้แน่ใจว่าจะไม่แตกหักได้หรือไม่
  • ทีมเหล่านี้สามารถทดสอบการเปลี่ยนแปลงของคุณตอนนี้ได้หรือไม่?

โปรดทราบว่าคำถามเหล่านี้ไม่ขึ้นอยู่กับประเภทพื้นที่เก็บข้อมูล คุณจะต้องค้นหาทีม B, C และ D คุณจะต้องพูดคุยกับพวกเขา หาเวลา ทำความเข้าใจลำดับความสำคัญของพวกเขา อย่างน้อยเราก็หวังว่าคุณจะทำ

ไม่มีใครอยากทำเช่นนี้จริงๆ มันสนุกน้อยกว่าการแก้ไข API เหี้ยๆ มาก มันเป็นเรื่องของมนุษย์และยุ่งวุ่นวาย ใน Polyrepository คุณสามารถทำการเปลี่ยนแปลง มอบให้บุคคลที่ทำงานในส่วนประกอบนั้น (อาจไม่ใช่ B, C หรือ D) เพื่อตรวจสอบ และดำเนินการต่อไป ทีม B, C และ D สามารถใช้เวอร์ชันปัจจุบันต่อไปได้ในตอนนี้ พวกเขาจะได้รับการต่ออายุเมื่อพวกเขาตระหนักถึงอัจฉริยะของคุณ!

ใน monorepository ความรับผิดชอบจะถูกเลื่อนไปโดยดีฟอลต์ ทีม A เปลี่ยนส่วนประกอบ และหากไม่ระวัง ก็จะพัง B, C และ D ทันที ส่งผลให้ B, C และ D ปรากฏตัวที่ประตูบ้าน A และสงสัยว่าทำไมทีม A จึงพังการชุมนุม สิ่งนี้สอนให้ A ข้ามรายการด้านบนของฉันไม่ได้ พวกเขาจะต้องพูดคุยเกี่ยวกับสิ่งที่พวกเขาจะทำ B, C และ D สามารถเคลื่อนที่ได้หรือไม่? จะเกิดอะไรขึ้นถ้า B และ C สามารถทำได้ แต่ D เกี่ยวข้องอย่างใกล้ชิดกับผลข้างเคียงของพฤติกรรมของอัลกอริทึมแบบเก่า

จากนั้นเราก็ต้องคุยกันว่าเราจะออกจากสถานการณ์นี้ได้อย่างไร:

  1. รองรับ API ภายในหลายรายการ และจะทำเครื่องหมายอัลกอริทึมเก่าว่าเลิกใช้แล้วจนกว่า D จะหยุดใช้งานได้
  2. รองรับหลายเวอร์ชัน โดยเวอร์ชันหนึ่งมีอินเทอร์เฟซเก่า และเวอร์ชันใหม่
  3. ชะลอการเปิดตัวการเปลี่ยนแปลงของ A จนกว่า B, C และ D จะสามารถยอมรับได้พร้อมกัน

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

หากต้องการเผยแพร่หลายเวอร์ชัน เราจำเป็นต้องมีสาขา ตอนนี้เรามีสององค์ประกอบ - A1 และ A2 ทีม B และ C ใช้ A2 และ D ใช้ A1 เราต้องการให้ทุกส่วนประกอบพร้อมสำหรับการเผยแพร่เนื่องจากอาจจำเป็นต้องมีการอัปเดตความปลอดภัยและการแก้ไขข้อบกพร่องอื่น ๆ ก่อน D จึงสามารถดำเนินการต่อได้ ใน Polyrepository เราสามารถซ่อนสิ่งนี้ไว้ในกิ่งที่มีอายุยืนยาวซึ่งให้ความรู้สึกดีได้ ใน monorepository เราบังคับให้สร้างโค้ดในโมดูลใหม่ ทีม D ยังคงต้องทำการเปลี่ยนแปลงในส่วน "เก่า" ทุกคนสามารถเห็นค่าใช้จ่ายที่เราจ่ายได้ที่นี่ - ตอนนี้เรามีโค้ดเพิ่มขึ้นสองเท่า และการแก้ไขข้อบกพร่องใดๆ ที่เกี่ยวข้องกับ A1 และ A2 จะต้องใช้กับทั้งคู่ ด้วยวิธีการแตกแขนงใน Polyrepository สิ่งนี้จึงถูกซ่อนอยู่หลังการเก็บเชอร์รี่ เราถือว่าต้นทุนถูกกว่าเพราะไม่มีความซ้ำซ้อน จากมุมมองในทางปฏิบัติ ต้นทุนจะเท่ากัน: คุณจะสร้าง ปล่อย และบำรุงรักษาโค้ดเบสที่เหมือนกันส่วนใหญ่สองอันจนกว่าคุณจะสามารถลบหนึ่งในนั้นได้ ความแตกต่างก็คือเมื่อมีที่เก็บเดี่ยว ความเจ็บปวดนี้จะตรงและมองเห็นได้ นี่แย่ยิ่งกว่านั้นและนั่นก็ดี

ในที่สุดเราก็มาถึงจุดที่สาม ความล่าช้าในการเปิดตัว เป็นไปได้ว่าการเปลี่ยนแปลงที่ทำโดย A จะทำให้ชีวิตของทีม A ดีขึ้น สิ่งสำคัญ แต่ไม่เร่งด่วน เราขอเลื่อนเวลาออกไปได้ไหม? ใน Polyrepository เรากดสิ่งนี้เพื่อปักหมุดอาร์ติแฟกต์ แน่นอนว่าเรากำลังบอกเรื่องนี้กับ Team D เพียงใช้เวอร์ชันเก่าจนกว่าคุณจะตามทัน! สิ่งนี้จะทำให้คุณพร้อมที่จะเล่นเป็นคนขี้ขลาด ทีม A ยังคงทำงานในส่วนของตนต่อไป โดยไม่สนใจข้อเท็จจริงที่ว่าทีม D กำลังใช้เวอร์ชันที่ล้าสมัยมากขึ้น (นั่นคือปัญหาของทีม D พวกเขาโง่เขลา) ในขณะเดียวกัน Team D พูดไม่ดีเกี่ยวกับทัศนคติที่ไม่ระมัดระวังของทีม A ต่อความเสถียรของโค้ด หากพวกเขาพูดถึงมันเลย เดือนผ่านไป ในที่สุด ทีม D ตัดสินใจที่จะพิจารณาความเป็นไปได้ในการอัปเดต แต่ A มีการเปลี่ยนแปลงเพิ่มเติมเท่านั้น ทีม A แทบจะจำไม่ได้ว่าพวกเขาพัง D เมื่อใดหรืออย่างไร การอัพเกรดนั้นเจ็บปวดกว่าและใช้เวลานานกว่านั้น ซึ่งจะส่งมันลงไปตามลำดับความสำคัญ จนถึงวันที่เรามีปัญหาด้านความปลอดภัยใน A ที่บังคับให้เราต้องสร้างสาขา ทีม A ต้องย้อนเวลากลับไป หาจุดที่ D มั่นคง แก้ไขปัญหาตรงนั้น และเตรียมปล่อยตัว นี่คือตัวเลือกที่ผู้คนเลือกโดยพฤตินัย และเป็นสิ่งที่แย่ที่สุด ดูเหมือนว่าจะดีสำหรับทั้งทีม A และทีม D ตราบใดที่เราเพิกเฉยต่อกันได้

ใน monorepository ตัวที่สามไม่ใช่ตัวเลือกจริงๆ คุณถูกบังคับให้จัดการกับสถานการณ์ด้วยวิธีใดวิธีหนึ่งจากสองวิธี คุณต้องดูต้นทุนของการมีสองสาขาที่วางจำหน่าย เรียนรู้ที่จะป้องกันตนเองจากการอัปเดตที่ทำลายความเข้ากันได้แบบย้อนหลัง แต่ที่สำคัญที่สุด: คุณไม่สามารถหลีกเลี่ยงการสนทนาที่ยากลำบากได้

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

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

เฉพาะผู้ใช้ที่ลงทะเบียนเท่านั้นที่สามารถเข้าร่วมในการสำรวจได้ เข้าสู่ระบบ, โปรด.

ใครคือผู้คลั่งไคล้ที่ยิ่งใหญ่ที่สุด? ผู้สนับสนุน:

  • โมโนเรโป

  • สนิม

  • แบบสำรวจไม่ถูกต้อง / ทั้งสองอย่าง

ผู้ใช้ 33 คนโหวต ผู้ใช้ 13 รายงดออกเสียง

ที่มา: will.com

เพิ่มความคิดเห็น