การจัดการการเปลี่ยนแปลงในสถาปัตยกรรม microservice ที่ขับเคลื่อนด้วยเหตุการณ์


9

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

สมมุติว่าเรามีแอปพลิเคชั่นที่ให้บริการต่าง ๆ สี่อย่าง แต่ละบริการเหล่านี้มีฐานข้อมูลของตัวเองเพื่อเก็บข้อมูลในเครื่อง

ในการตั้งค่านี้บริการสี่รายการสื่อสารกันโดยใช้ Event Bus ดังนั้นเมื่อมีสิ่งใดเกิดขึ้นในบริการมันจะเผยแพร่กิจกรรม บริการอื่น ๆ ทั้งหมดที่มีความสนใจในเหตุการณ์นั้นจะดำเนินการด้วยวิธีของตนเอง

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

คำถามของฉันคือ: เราจะจัดการการเปลี่ยนแปลงในเหตุการณ์เหล่านี้ได้อย่างไร

ดังนั้นบริการสมมติว่าลงทะเบียนผู้ใช้ใหม่ในแอปพลิเคชัน ดังนั้นจึงส่งกิจกรรม "" UserRegistered "Service B เลือกกิจกรรมนั้นและประมวลผล แต่นักพัฒนาบางคนในทีมบริการ C ตัดสินใจว่าพวกเขาต้องการเพศของผู้ใช้ที่ลงทะเบียนด้วยดังนั้นเหตุการณ์จึงเปลี่ยนไปและแอตทริบิวต์เพศ ถูกเพิ่มไปยังเหตุการณ์ "UserRegistered"

เราจะมั่นใจได้อย่างไรว่า Service B ยังสามารถรับเหตุการณ์เดียวกันด้วยคุณสมบัติพิเศษนั้นโดยไม่ต้องปรับใช้ซ้ำ

และมีวิธีอื่นในการแก้ไขปัญหานี้แล้วกำหนดเหตุการณ์เหล่านี้หรือไม่


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

ฉันมีอิสระในการเลือกรูปแบบที่จะใช้สำหรับข้อความของฉัน ฉันคิดว่าการใช้ JSON เป็นวิธีที่ดีที่สุด สิ่งสำคัญคือบริการต่าง ๆ เหล่านี้สร้างขึ้นในภาษาที่ต่างกัน นั่นเป็นเหตุผลที่จำเป็นต้องใช้รูปแบบทั่วไปเช่น XML หรือ JSON
CGeense

คำตอบ:


1

เหตุการณ์ไม่ได้เกี่ยวกับสิ่งที่เปลี่ยนแปลง มันเกี่ยวกับเมื่อมีบางสิ่งเปลี่ยนแปลง

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

ไม่ได้แก้ปัญหาการสื่อสารการเปลี่ยนแปลงเหล่านี้ มันหยุดมันจากการเป็นส่วนหนึ่งของระบบเหตุการณ์

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

อีกหลายวิธีในการดูแลผิวหน้าแมวนั้น แต่นั่นก็เป็นวิธีที่ฉันได้ทำงานในกรณีนี้อย่างแน่นอน


สิ่งนี้จะไม่เพิ่มการรับส่งข้อมูลระหว่างบริการหรือไม่ ใช้ตัวอย่างในคำถามUserRegisteredเหตุการณ์ถ้ามีเหตุการณ์ที่ไม่มีข้อมูลเกี่ยวกับผู้ใช้จะมีข้อความที่เผยแพร่ 1 ข้อความไปยังรถบัสและจากนั้น {number of services บริการที่สนใจ} ร้องขอไปยังบริการผู้ใช้หรือข้อความที่เผยแพร่ ไปที่รถบัส จากนั้นจะมีข้อความ {number of services services ที่สนใจ} ที่มีขนาดต่างกัน แม้ว่าฉันจะคิดว่านี่อาจเป็นการออกแบบที่สะอาดกว่าบนกระดาษหากประสิทธิภาพเป็นสิ่งที่น่ากังวล แต่มันก็หยุดลงในระบบที่ไม่สำคัญโดยเฉพาะผ่านเครือข่าย
Thomas Owens

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

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

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

1

เฟรมเวิร์กเช่น NServiceBus จัดการสิ่งนี้โดยใช้การกำหนดเวอร์ชันเหตุการณ์ด้วยการส่งข้อความ polymorphic

ตัวอย่างเช่นเวอร์ชัน 1 ของ Service A อาจเผยแพร่เหตุการณ์เป็น IUserRegistered_v1 เมื่อ Service A เวอร์ชัน 1.1 ต้องการรวมฟิลด์เพิ่มเติมอาจประกาศอินเตอร์เฟส IUserRegistered_v1_1 ซึ่งจะสืบทอดมาจาก IUserRegistered_v1 รวมถึงประกาศฟิลด์เพิ่มเติมบางอย่าง

เมื่อ Service A เผยแพร่เหตุการณ์ IUserRegistered_v1_1 NServiceBus จะส่งข้อความไปยังปลายทางทั้งหมดที่จัดการ IUserRegistered_v1 หรือ IUserRegistered_v1_1


0

การปรับปรุงที่เพิ่มขึ้น

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

หินแข็ง

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

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

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


-1

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

ไม่สำคัญตราบใดที่คุณกำลังเพิ่มข้อมูล ให้ค่าเริ่มต้นที่สมเหตุสมผลสำหรับเหตุการณ์ที่เก่ากว่า / ฟิลด์ที่ไม่จำเป็น

คุณควรจะต้องอัพเดทบริการที่สนใจ - ในกรณีนี้ - เพศ ตัวแยกวิเคราะห์ xml / json ควรสามารถละเว้นข้อมูลเพิ่มเติมสำหรับบริการอื่น ๆ ขึ้นอยู่กับรูปแบบข้อมูล parser และเหตุการณ์ที่คุณเลือก

ฉันไม่เห็นด้วยกับเหตุการณ์ที่ไม่มีข้อมูลที่เกี่ยวข้อง สำหรับการจัดหากิจกรรมเหตุการณ์ควรกำหนดสิ่งที่เปลี่ยนแปลง เมื่อได้รับกิจกรรมบริการอื่น ๆ ไม่ควรเรียกข้อมูลจากแหล่งที่มาของเหตุการณ์


ประเด็นของฉันคือมันต้องจัดการกับการเปลี่ยนแปลงทุกชนิด นึกถึงบริการที่เผยแพร่กิจกรรม และเหตุการณ์นั้นมีคุณสมบัติที่ล้าสมัยและควรถูกลบออก แม้ว่าบริการอื่น ๆ เหล่านี้จะไม่ได้ใช้คุณสมบัติก็จะทำลายพวกเขาเพียงเพราะพวกเขาคาดหวัง ดังนั้นฉันอ่านบทความนี้บน martinfowler.com เกี่ยวกับสัญญาที่ขับเคลื่อนโดยผู้บริโภค: martinfowler.com/articles/consumerDrivenContracts.html เมื่อใช้หลักการนี้ ผู้ให้บริการ (เหตุการณ์) แต่ละคนรู้ว่าเขาคาดหวังอะไร ด้วยข้อมูลที่เขาสามารถตรวจสอบถ้าเขาแบ่งผู้บริโภคใด ๆ
CGeense
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.