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


12

สถานการณ์ปัจจุบัน

เรากำลังดำเนินการ (และตอนนี้ยังคงรักษา) เว็บแอปพลิเคชันการช็อปปิ้งออนไลน์ในสถาปัตยกรรม microservice

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

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

ในขณะนี้shopping-cartmicroservice ของเรากำลังรวบรวมข้อมูลทั้งหมดจาก microservices อื่น ๆ แม้ว่าส่วนหนึ่งของข้อมูลนี้จะถูกใช้งานโดยshopping-cartส่วนใหญ่จะใช้เพื่อป้อนกฎของเครื่องมือเป็นส่วนใหญ่

ข้อกำหนดใหม่

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

ดำเนินการต่อตามที่เป็นอยู่เราจะเผชิญกับปัญหาหลายประการ:

  • ทุกคน (เรียกเครื่องมือกฎ) ต้องนำการดึงข้อมูลกลับมาใช้ใหม่แม้ว่าพวกเขาจะไม่ต้องการมัน
  • การร้องขอไปยังเอ็นจินกฎมีความซับซ้อน
  • ต่อไปในทิศทางนี้เราจะต้องขนส่งข้อมูลนี้ไปทั่วเครือข่ายสำหรับคำขอจำนวนมาก (คิดว่าμs A μsโทรμs B เรียกเครื่องมือกฎ แต่ A มีข้อมูลที่ต้องการกฎเครื่องยนต์อยู่แล้ว);
  • shopping-cart ได้กลายเป็นใหญ่เนื่องจากการดึงข้อมูลทั้งหมด
  • ฉันอาจลืม ...

เราจะทำอย่างไรเพื่อหลีกเลี่ยงปัญหาเหล่านี้

เป็นการดีที่เราจะหลีกเลี่ยงการเพิ่มความซับซ้อนมากขึ้นในเครื่องมือกฎ เราต้องทำให้แน่ใจว่ามันจะไม่กลายเป็นคอขวด - ตัวอย่างเช่นข้อมูลบางอย่างค่อนข้างช้าที่จะดึงข้อมูล (10 วินาทีขึ้นไป) ดังนั้นเราจึงทำการดึงข้อมูลล่วงหน้าในshopping-cartลักษณะที่ข้อมูลมีแนวโน้มที่จะอยู่ที่นั่นก่อนที่เราจะเรียกกฎ เอ็นจิ้นและรักษาประสบการณ์ผู้ใช้ที่เป็นที่ยอมรับ

ความคิดบางอย่าง

  1. ให้เอ็นจินกฎดึงข้อมูลที่ต้องการ สิ่งนี้จะเพิ่มความซับซ้อนให้มากขึ้นโดยละเมิดหลักการความรับผิดชอบเดียว ( ยิ่ง… );
  2. ใช้พร็อกซีμsก่อนเครื่องมือสร้างกฎเพื่อดึงข้อมูล
  3. ปรับใช้ "data fetcher" μsที่กฎเอ็นจิ้นเรียกใช้เพื่อดึงข้อมูลทั้งหมดที่ต้องการในคราวเดียว (คอมโพสิตสอบถามรายละเอียดเพิ่มเติม)

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

3
ทางออกที่ดีที่สุดของคุณเพื่อหลีกเลี่ยงปัญหาเหล่านั้นคือการกำจัดกฎของเครื่องยนต์
whatsisname

@Andy เอ็นจินกฎคือ microservice แยกต่างหาก API ของมันค่อนข้างเหมาะshopping-cartแต่เราสามารถปรับให้เข้ากับความต้องการของไมโครไซต์อื่น ๆ ได้ง่าย (พวกเขายังคงเกี่ยวข้องกับผู้ใช้ผลิตภัณฑ์และการสั่งซื้อ) ตามที่เราเห็นพวกเขาจะต้องการข้อมูลอินพุตเดียวกันโดยเฉพาะอย่างยิ่งเมื่อธุรกิจสามารถเลือกเพรดิเคตที่จะใช้ microservices อื่น ๆ ให้ข้อมูลทั้งหมดยกเว้นเนื้อหาในรถเข็น การดึงข้อมูลไม่ซับซ้อนต่อ seแต่มันจะซับซ้อนเมื่อคุณต้องโทรหาไมโครไซต์อื่น ๆ ~ 10 และรักษาโครงสร้างที่คาดไว้โดยเอ็นจินกฎ
Didier L

@whatsisname ฉันไม่ได้เป็นแฟนตัวยงของการมีกฎกติกาโดยทั่วไป แต่ในเวลาปัจจุบันเราต้องจัดการกับมันและต่อไปและธุรกิจกำลังเปลี่ยนแปลงการกำหนดค่าในแต่ละวัน แม้ว่าเราจะกำจัดมันไปแล้ว แต่เราก็ยังต้องการส่วนประกอบที่กำหนดค่าได้เพื่อทำสิ่งเดียวกันโดยใช้ข้อมูลอินพุตเดียวกัน ... มันยังคงเป็นเอ็นจิ้นกฎเพียงแค่ใช้ชื่ออื่นและเราก็ยังต้องเจอปัญหาเดียวกัน
Didier L

คำตอบ:


8

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

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

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

ทุกคน (เรียกเครื่องมือกฎ) ต้องนำการดึงข้อมูลกลับมาใช้ใหม่แม้ว่าพวกเขาจะไม่ต้องการมัน

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

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

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

ปัญหาส่วนใหญ่เกิดจากสิ่งนี้

การร้องขอไปยังเอ็นจินกฎมีความซับซ้อน

ทำให้ซับซ้อนน้อยลง

ค้นหาวิธีที่จะทำให้ซับซ้อนน้อยลง อย่างจริงจัง. datamodels ทั่วไปแบ่งเอ็นจินกฎเดี่ยวของคุณออกเป็นเล็ก ๆ หรืออะไรทำนองนั้น ทำให้เอ็นจิ้นกฎของคุณทำงานได้ดีขึ้น อย่าใช้วิธี "ติดขัดทุกอย่างในการสืบค้นและทำให้มันซับซ้อน" ต่อไป - ดูอย่างจริงจังว่าคุณกำลังทำอะไรอยู่และทำไม

กำหนดโปรโตคอลบางอย่างสำหรับข้อมูลของคุณ ฉันเดาว่าพวกคุณไม่มีแผน API ที่กำหนดไว้ (ตามข้างบน) และเริ่มเขียน REST call hoc ทุกครั้งที่ต้องการ สิ่งนี้มีความซับซ้อนมากขึ้นเรื่อย ๆ เนื่องจากคุณต้องดูแลไมโครไซต์ทุกครั้งที่มีการอัปเดต

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

ตอนนี้อะไร ...

หลังจากนี้คุณอย่างน้อยก็ทดสอบประเด็นที่ใหญ่ที่สุด

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

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

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

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

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

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

คุณใช้วลี "data fetching" ซ้ำแล้วซ้ำอีก ข้อมูลนี้อยู่ในฐานข้อมูลหรือไม่? ถ้าไม่ลองทำสิ่งนี้ - ถ้าคุณใช้เวลามากในการดึงข้อมูลด้วยตนเองดูเหมือนว่าการใช้ฐานข้อมูลจริงเป็นความคิดที่ดี

คุณอาจมีการออกแบบที่มีฐานข้อมูลสำหรับข้อมูลที่คุณดึงข้อมูล (ขึ้นอยู่กับสิ่งนี้คือสิ่งที่คุณได้กล่าวถึงหลายครั้ง), เอ็นจินกฎไม่กี่ตัวและไคลเอนต์ของคุณ

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

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


ขอบคุณสำหรับคำตอบของคุณ @enderland อันที่จริงสถาปัตยกรรมไมโครเซอร์วิสยังค่อนข้างใหม่สำหรับเราดังนั้นคำถามนี้ เอ็นจิ้นกฎนี้พัฒนาขึ้นมาเล็กน้อยเพื่อนำเรามาที่นี่ดังนั้นตอนนี้เราต้องการเส้นทางการขับขี่เพื่อแก้ไข มันคือ (โชคดี) ไร้สัญชาติอย่างสมบูรณ์ดังนั้นปริมาณของข้อมูลที่ใช้เป็นอินพุต และนี่คือสิ่งที่เราต้องการจัดการก่อนเพื่อให้เป็นองค์ประกอบที่สามารถใช้ซ้ำได้ แต่จะลดปริมาณข้อมูลอินพุตโดยไม่ลดภาคแสดงที่มีอยู่ได้อย่างไร? ฉันเดาว่าเราต้องการ API ที่สามารถดึงข้อมูลได้ด้วยตัวเอง แต่จะออกแบบสถาปัตยกรรมได้อย่างไร?
Didier L

เกี่ยวกับปัญหาด้านประสิทธิภาพนั้นมาจากไมโครไซต์ที่เรียกบริการ JMS และ SOAP ที่ช้าซึ่งดำเนินการโดยแบ็คเอนด์ พวกเขามีฐานข้อมูลของตัวเอง แต่ประสิทธิภาพไม่ใช่เป้าหมายแรกของพวกเขา (ตราบใดที่มันจัดการกับโหลด) และมีคนจำนวนมากเกินไปที่จะลองทำซ้ำข้อมูลและเก็บรักษาไว้ (สำหรับบางคนที่เราทำ) สิ่งที่ดีที่สุดที่เราทำได้คือการแคชและดึงข้อมูลล่วงหน้า
Didier L

ดังนั้นเมื่อคุณพูดถึง " เครื่องมือกฎน้อย " ฉันเข้าใจว่าคุณหมายถึงเครื่องมือกฎพิเศษที่ประเมินเฉพาะภาคแสดงด้วยอินพุต 1 ประเภทใช่มั้ย คุณจะแนะนำให้พวกเขาดึงข้อมูลที่พวกเขาต้องการหรือควรดึงข้อมูลล่วงหน้า? นอกจากนี้เรายังต้องการส่วนประกอบบางอย่างเพื่อเตรียมการของ predicates แล้วใช่ไหม และให้ความสนใจที่จะไม่เพิ่มค่าใช้จ่ายของเครือข่ายมากเกินไปเนื่องจากการเชื่อมโยงนี้
Didier L

1

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

ผู้บริโภคปัจจุบันของเอ็นจิ้นกฎสามารถจัดหากระบวนการในการรวบรวมข้อมูลที่ต้องการให้กับองค์ประกอบวัตถุประสงค์พิเศษเพิ่มเติม

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

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

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

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


0

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

ในฐานะที่เป็นเรื่องจริงสำหรับการนำไปใช้ฉันจะพูดถึงว่า IBM Operational Decision Manager กำลังเริ่มทำเอกสารและสนับสนุนการใช้ผลิตภัณฑ์ภายในคอนเทนเนอร์นักเทียบท่าแล้ว ฉันแน่ใจว่าผลิตภัณฑ์อื่นให้การสนับสนุนเช่นนี้และมันจะกลายเป็นกระแสหลัก


0

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.