การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

ในบทความนี้ ฉันจะพูดถึงวิธีที่โครงการที่ฉันกำลังทำเปลี่ยนจากเสาหินขนาดใหญ่ไปเป็นชุดไมโครเซอร์วิส

โครงการเริ่มต้นประวัติศาสตร์เมื่อนานมาแล้วในต้นปี 2000 เวอร์ชันแรกเขียนด้วย Visual Basic 6 เมื่อเวลาผ่านไปเป็นที่ชัดเจนว่าการพัฒนาในภาษานี้จะเป็นเรื่องยากที่จะสนับสนุนในอนาคตเนื่องจาก IDE และภาษาเองก็พัฒนาได้ไม่ดีนัก ในช่วงปลายทศวรรษ 2000 มีการตัดสินใจที่จะเปลี่ยนไปใช้ C# ที่มีแนวโน้มมากกว่า เวอร์ชันใหม่เขียนควบคู่ไปกับการแก้ไขเวอร์ชันเก่า โค้ดถูกเขียนใน .NET มากขึ้นเรื่อยๆ แบ็กเอนด์ใน C# ในตอนแรกมุ่งเน้นไปที่สถาปัตยกรรมบริการ แต่ในระหว่างการพัฒนา ไลบรารีทั่วไปที่มีตรรกะถูกนำมาใช้ และบริการต่างๆ ได้เปิดตัวในกระบวนการเดียว ผลลัพธ์ที่ได้คือแอปพลิเคชันที่เราเรียกว่า “บริการขนาดใหญ่”

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

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

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

Содержание

สถาปัตยกรรมและปัญหาของโซลูชันที่มีอยู่


เริ่มแรกสถาปัตยกรรมมีลักษณะดังนี้: UI เป็นแอปพลิเคชันแยกต่างหาก ส่วนเสาหินเขียนใน Visual Basic 6 แอปพลิเคชัน .NET เป็นชุดของบริการที่เกี่ยวข้องซึ่งทำงานกับฐานข้อมูลขนาดใหญ่พอสมควร

ข้อเสียของการแก้ปัญหาก่อนหน้านี้

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

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

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

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

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

ความคาดหวังจากไมโครเซอร์วิส


ปัญหาส่วนประกอบเมื่อพร้อม การส่งมอบส่วนประกอบเมื่อพร้อมโดยการสลายสารละลายและแยกกระบวนการต่างๆ

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

การแยกบริการในกระบวนการที่แยกจากกัน ตามหลักการแล้ว ฉันต้องการแยกมันออกจากคอนเทนเนอร์ แต่บริการจำนวนมากที่เขียนใน .NET Framework ทำงานบน Windows เท่านั้น ขณะนี้บริการที่ใช้ .NET Core ปรากฏขึ้นแล้ว แต่ยังมีเพียงไม่กี่บริการเท่านั้น

ความยืดหยุ่นในการปรับใช้ เราต้องการรวมบริการต่างๆ ไว้ในวิธีที่เราต้องการ ไม่ใช่วิธีที่โค้ดบังคับใช้

การใช้เทคโนโลยีใหม่ๆ สิ่งนี้น่าสนใจสำหรับโปรแกรมเมอร์ทุกคน

ปัญหาการเปลี่ยนแปลง


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

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

ในขณะที่เริ่มทำงาน พื้นที่เก็บข้อมูลมีมากกว่า 500 โปรเจ็กต์และมีโค้ดมากกว่า 700 บรรทัด นี่เป็นการตัดสินใจครั้งใหญ่และ ปัญหาที่สอง. เป็นไปไม่ได้เลยที่จะแบ่งมันออกเป็นไมโครเซอร์วิส

ปัญหาที่สาม – ขาดโครงสร้างพื้นฐานที่จำเป็น ที่จริงแล้ว เรากำลังคัดลอกซอร์สโค้ดไปยังเซิร์ฟเวอร์ด้วยตนเอง

วิธีย้ายจาก Monolith ไปสู่ ​​Microservices


การจัดเตรียมไมโครเซอร์วิส

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

เราใช้วิธีการใดในการแยกไมโครเซอร์วิสออกจากกัน

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

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

การประกอบกับโฮสต์เป็นเพียงโค้ดหนึ่งบรรทัดในคลาสโปรแกรม เราซ่อนงานกับ Topshelf ในชั้นเรียนเสริม

namespace RBA.Services.Accounts.Host
{
   internal class Program
   {
      private static void Main(string[] args)
      {
        HostRunner<Accounts>.Run("RBA.Services.Accounts.Host");

       }
    }
}

วิธีที่สองในการจัดสรรไมโครเซอร์วิสคือ: สร้างมันขึ้นมาเพื่อแก้ไขปัญหาใหม่ หากในเวลาเดียวกันเสาหินไม่เติบโตก็ถือว่ายอดเยี่ยมแล้วซึ่งหมายความว่าเรากำลังเดินไปในทิศทางที่ถูกต้อง เพื่อแก้ไขปัญหาใหม่ เราพยายามสร้างบริการแยกกัน หากมีโอกาสดังกล่าว เราก็ได้สร้างบริการ "แบบบัญญัติ" มากขึ้นที่จัดการโมเดลข้อมูลของตนเองซึ่งเป็นฐานข้อมูลแยกต่างหากได้อย่างสมบูรณ์

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

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

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

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

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

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

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

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

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

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

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

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

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

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

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

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

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

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

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

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

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

การทำงานกับฐานข้อมูล


ฐานข้อมูลสามารถแบ่งได้แย่กว่าซอร์สโค้ดเนื่องจากไม่เพียงมีสคีมาปัจจุบันเท่านั้น แต่ยังสะสมข้อมูลประวัติอีกด้วย

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

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

การแบ่งแบบเดียวกันออกเป็นบริบทที่จำกัดในโค้ดช่วยเราในการแยก มันมักจะทำให้เรามีความคิดที่ดีว่าเราแยกย่อยข้อมูลในระดับฐานข้อมูลอย่างไร เราเข้าใจว่าตารางใดเป็นของบริบทที่มีขอบเขตหนึ่งและบริบทใดเป็นของอีกบริบทหนึ่ง

เราใช้วิธีการส่วนกลางสองวิธีในการแบ่งพาร์ติชันฐานข้อมูล: การแบ่งพาร์ติชันตารางที่มีอยู่ และการแบ่งพาร์ติชันด้วยการประมวลผล

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

จำเป็นต้องมีแผนกที่มีการประมวลผลเมื่อรูปแบบธุรกิจมีการเปลี่ยนแปลงไปอย่างมาก และตารางก็ไม่เป็นที่พึงพอใจของเราอีกต่อไป

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

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

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

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

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

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

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

ต่อไป เราจะเลือกตารางที่ไมโครเซอร์วิสใหม่ใช้งานได้จากฐานข้อมูลทั่วไป เราสามารถย้ายตารางไปยังสคีมาแยกกันหรือแม้กระทั่งไปยังฐานข้อมูลทางกายภาพที่แยกจากกัน ยังคงมีการเชื่อมต่อการอ่านระหว่างไมโครเซอร์วิสและฐานข้อมูลโมโนลิธ แต่ไม่มีอะไรต้องกังวล ในการกำหนดค่านี้ มันสามารถอยู่ได้ค่อนข้างนาน

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

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

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

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

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

เพื่อให้แผนนี้ใช้งานได้ เราอาจต้องมีช่วงการเปลี่ยนแปลง

มีสองแนวทางที่เป็นไปได้

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

ที่สอง: เราแบ่งข้อมูลตามเกณฑ์ทางธุรกิจบางประการ เช่น เรามีสินค้า 5 รายการในระบบที่ถูกเก็บไว้ในฐานข้อมูลเก่า เราวางอันที่หกไว้ในงานทางธุรกิจใหม่ในฐานข้อมูลใหม่ แต่เราจะต้องมี API Gateway ที่จะซิงโครไนซ์ข้อมูลนี้และแสดงให้ลูกค้าเห็นว่าจะหาได้จากที่ไหนและอย่างไร

ทั้งสองวิธีใช้ได้ผล ให้เลือกขึ้นอยู่กับสถานการณ์

หลังจากที่เราแน่ใจว่าทุกอย่างใช้งานได้แล้ว ส่วนของเสาหินที่ทำงานกับโครงสร้างฐานข้อมูลเก่าก็สามารถปิดการใช้งานได้

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

ขั้นตอนสุดท้ายคือการลบโครงสร้างข้อมูลเก่าออก

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

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

การทำงานกับซอร์สโค้ด


นี่คือลักษณะของแผนภาพซอร์สโค้ดเมื่อเราเริ่มวิเคราะห์โครงการขนาดใหญ่

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

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

เราโชคดีที่มีไลบรารีโครงสร้างพื้นฐานที่สามารถใช้งานแยกกันได้

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

ข้อกังวลที่ใหญ่ที่สุดคือบริบทที่มีขอบเขต บังเอิญว่ามีบริบท 3-4 รายการผสมกันในแอสเซมบลีทั่วไปเดียวและใช้ร่วมกันภายในฟังก์ชันทางธุรกิจเดียวกัน จำเป็นต้องเข้าใจว่าสิ่งนี้สามารถแบ่งได้ที่ไหนและตามขอบเขตใด และจะทำอย่างไรต่อไปในการแมปส่วนนี้ให้เป็นแอสเซมบลีของซอร์สโค้ด

เราได้กำหนดกฎหลายข้อสำหรับกระบวนการแยกโค้ด

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

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

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

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

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

บริการของเราเริ่มอ้างอิงแพ็คเกจโครงสร้างพื้นฐานภายในในลักษณะเดียวกับแพ็คเกจภายนอก เราดาวน์โหลดไลบรารีภายนอกจาก Nuget ในการทำงานร่วมกับ Artifactory ที่เราวางแพ็คเกจเหล่านี้ เราใช้ตัวจัดการแพ็คเกจสองตัว ในที่เก็บข้อมูลขนาดเล็ก เรายังใช้ Nuget ในที่เก็บข้อมูลที่มีบริการหลากหลาย เราใช้ Paket ซึ่งให้ความสอดคล้องของเวอร์ชันระหว่างโมดูลมากขึ้น

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

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

ปัญหาโครงสร้างพื้นฐาน


ข้อเสียส่วนใหญ่ในการเปลี่ยนไปใช้ไมโครเซอร์วิสนั้นเกี่ยวข้องกับโครงสร้างพื้นฐาน คุณจะต้องปรับใช้อัตโนมัติ คุณจะต้องมีไลบรารีใหม่เพื่อรันโครงสร้างพื้นฐาน

การติดตั้งด้วยตนเองในสภาพแวดล้อม

ในตอนแรก เราได้ติดตั้งโซลูชันสำหรับสภาพแวดล้อมด้วยตนเอง เพื่อให้กระบวนการนี้เป็นอัตโนมัติ เราได้สร้างไปป์ไลน์ CI/CD เราเลือกกระบวนการจัดส่งแบบต่อเนื่องเนื่องจากการปรับใช้อย่างต่อเนื่องยังไม่เป็นที่ยอมรับสำหรับเราในแง่ของกระบวนการทางธุรกิจ ดังนั้นการส่งเพื่อดำเนินการจึงดำเนินการโดยใช้ปุ่มและสำหรับการทดสอบ - โดยอัตโนมัติ

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

เราใช้ Atlassian, Bitbucket สำหรับการจัดเก็บซอร์สโค้ด และ Bamboo สำหรับการสร้าง เราชอบเขียน build scripts ใน Cake เพราะว่ามันเหมือนกับ C# แพ็คเกจสำเร็จรูปมาที่ Artifactory และ Ansible จะเข้าสู่เซิร์ฟเวอร์ทดสอบโดยอัตโนมัติ หลังจากนั้นจึงสามารถทดสอบได้ทันที

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

แยกการบันทึก


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

การเปลี่ยนจาก monolith เป็น microservices: ประวัติศาสตร์และการปฏิบัติ

เมื่อใช้ Filebeat เราได้รับโอกาสในการรวบรวมบันทึกของเราจากเซิร์ฟเวอร์ จากนั้นแปลงไฟล์เหล่านั้น ใช้ Kibana เพื่อสร้างการสืบค้นใน UI และดูว่าการโทรไปมาระหว่างบริการต่างๆ อย่างไร Trace ID ช่วยได้มากในเรื่องนี้

การทดสอบและการดีบักบริการที่เกี่ยวข้อง


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

มีเซิร์ฟเวอร์ที่ให้บริการเฉพาะเวอร์ชันที่ใช้งานจริงเท่านั้น เซิร์ฟเวอร์เหล่านี้จำเป็นในกรณีที่เกิดเหตุการณ์ เพื่อตรวจสอบการส่งมอบก่อนการใช้งานและสำหรับการฝึกอบรมภายใน

เราได้เพิ่มกระบวนการทดสอบอัตโนมัติโดยใช้ไลบรารี Specflow ยอดนิยม การทดสอบทำงานโดยอัตโนมัติโดยใช้ NUnit ทันทีหลังจากการปรับใช้จาก Ansible หากความครอบคลุมของงานเป็นแบบอัตโนมัติทั้งหมด ก็ไม่จำเป็นต้องทดสอบด้วยตนเอง แม้ว่าบางครั้งยังจำเป็นต้องมีการทดสอบด้วยตนเองเพิ่มเติม เราใช้แท็กใน Jira เพื่อพิจารณาว่าจะใช้การทดสอบใดสำหรับปัญหาเฉพาะ

นอกจากนี้ ความจำเป็นในการทดสอบโหลดก็เพิ่มขึ้น ก่อนหน้านี้มีการดำเนินการเฉพาะในบางกรณีเท่านั้น เราใช้ JMeter เพื่อทำการทดสอบ, InfluxDB เพื่อจัดเก็บ และใช้ Grafana เพื่อสร้างกราฟกระบวนการ

เราประสบความสำเร็จอะไรบ้าง?


ประการแรก เรายกเลิกแนวคิดเรื่อง "การปลดปล่อย" หมดไปแล้วกับการเปิดตัวครั้งใหญ่สองเดือนเมื่อมีการปรับใช้ยักษ์ใหญ่นี้ในสภาพแวดล้อมการผลิต ซึ่งทำให้กระบวนการทางธุรกิจหยุดชะงักชั่วคราว ตอนนี้เราปรับใช้บริการโดยเฉลี่ยทุกๆ 1,5 วัน โดยจัดกลุ่มบริการเนื่องจากเริ่มดำเนินการหลังจากได้รับอนุมัติแล้ว

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

เราสามารถควบคุมรูปแบบการใช้งานได้ คุณสามารถเลือกกลุ่มบริการแยกจากโซลูชันที่เหลือได้ หากจำเป็น

นอกจากนี้ เรายังลดปัญหาลงอย่างมากด้วยการปรับปรุงคิวจำนวนมาก ขณะนี้เรามีทีมผลิตภัณฑ์แยกกันซึ่งทำงานร่วมกับบริการบางอย่างอย่างเป็นอิสระ กระบวนการ Scrum เหมาะสมแล้วที่นี่ ทีมใดทีมหนึ่งอาจมีเจ้าของผลิตภัณฑ์แยกต่างหากซึ่งจะมอบหมายงานให้

สรุป

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

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

    ป.ล. เรื่องราวสะเทือนอารมณ์มากขึ้น (และราวกับว่าเป็นการส่วนตัว) - ตาม ลิงค์.
    นี่คือรายงานเวอร์ชันเต็ม

ที่มา: will.com

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