วิธีการออกแบบระบบการแจ้งเตือนที่ปรับขนาดได้? [ปิด]


32

ฉันต้องเขียนผู้จัดการระบบการแจ้งเตือน

นี่คือข้อกำหนดของฉัน:

ฉันต้องสามารถส่งการแจ้งเตือนบนแพลตฟอร์มที่แตกต่างกันซึ่งอาจแตกต่างกันโดยสิ้นเชิง (สำหรับตัวอย่างฉันต้องสามารถส่ง SMS หรืออีเมลได้)

บางครั้งการแจ้งเตือนอาจเหมือนกันสำหรับผู้รับทุกคนสำหรับแพลตฟอร์มที่กำหนด แต่บางครั้งอาจเป็นการแจ้งเตือนต่อผู้รับ (หรือหลายคน) ต่อแพลตฟอร์ม

การแจ้งเตือนแต่ละครั้งสามารถมีส่วนของข้อมูลเฉพาะแพลตฟอร์มได้ (สำหรับตัวอย่าง MMS ที่มีเสียงหรือภาพ)

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

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

จากนั้นระบบจะต้องส่งการแจ้งเตือนไปยังผู้ให้บริการแพลตฟอร์ม


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

ฉันว่าวัตถุต่อไปนี้ (ในภาษาเทียม):

Notificationวัตถุทั่วไป:

class Notification {
    String                 $message;
    Payload                $payload;
    Collection<Recipient>  $recipients;
}

ปัญหาเกี่ยวกับวัตถุต่อไปนี้จะเกิดอะไรขึ้นถ้าฉันมีผู้รับ 1,000,000? แม้ว่าRecipientวัตถุนั้นจะเล็กมากมันก็จะใช้หน่วยความจำมากเกินไป

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

การแจ้งเตือนที่สร้างขึ้นแต่ละครั้งสามารถเก็บไว้ในที่เก็บข้อมูลถาวรเช่น DB หรือ Redis

มันจะเป็นการดีหรือไม่ที่จะรวมกันในภายหลังเพื่อให้แน่ใจว่าสามารถปรับขนาดได้หรือไม่?

ในขั้นตอนที่สองฉันต้องดำเนินการการแจ้งเตือนนี้

แต่ฉันจะแยกแยะการแจ้งเตือนกับผู้ให้บริการแพลตฟอร์มที่เหมาะสมได้อย่างไร

ฉันควรใช้วัตถุเช่นMMSNotificationขยายabstract Notificationหรือไม่ หรือสิ่งที่ต้องการNotification.setType('MMS')?

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

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

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

ฉันยังสามารถใช้EventManagerเพื่ออนุญาตให้มีพฤติกรรมที่เสียบได้

ข้อเสนอแนะหรือความคิดใด ๆ

ขอบคุณที่สละเวลา

หมายเหตุ: ฉันเคยทำงานใน PHP และเป็นไปได้ว่าภาษาที่ฉันเลือก


แก้ไข (ตามคำตอบของ morphunreal)

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

  • ภาษา / ระบบใดบ้างที่จะสร้างการแจ้งเตือน?

มันเป็นของฉันเองฉันรับผิดชอบในการสร้างการแจ้งเตือนทางโปรแกรม แต่สร้างจาก UI

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

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

  • มีกฎทางธุรกิจสำหรับการเพิ่มใบเสร็จรับเงิน CC / BCC / อ่าน

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

  • เครื่องกำเนิดไฟฟ้าทราบประเภทของข้อความที่กำลังส่ง (เช่น SMS / อีเมล) หรือเป็นไปตามผู้รับ

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

  • เครื่องกำเนิดไฟฟ้าจำเป็นต้องมีการยืนยันข้อความที่ถูกส่ง / รับ / อ่าน (async กับการส่งแบบซิงโครนัส)

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

  • มีข้อกำหนดในการจัดเก็บประวัติของแหล่งข้อความ / ผู้รับ (นานแค่ไหน)

ใช่เราต้องการสร้างสถิติและรายงานบางอย่าง * กำหนดจุดสิ้นสุดการแจ้งเตือน


  • บริการใดบ้างที่ใช้ในการส่งข้อความ ขึ้นอยู่กับว่าบางคนเป็น webservice REST คลาสสิกอื่น ๆ เป็นโปรโตคอลที่แปลกใหม่มันขึ้นอยู่กับผู้ให้บริการ

  • มีข้อเสนอแนะ / การยืนยันอะไรบ้าง (ซิงค์ / async)

ขึ้นอยู่กับว่าบางคนจะซิงโครนัสและตอบกลับด้วยข้อผิดพลาดในขณะที่บางคนต้องดึงหลังจากนั้นเพื่อตรวจสอบข้อผิดพลาด

  • เป็นไปได้ไหมที่จะเพิ่มจุดสิ้นสุดใหม่ [แม้ว่าจะเป็นเช่นนั้นจะต้องมีการสรุปหรือไม่]

ใช่แอปของเรากำลังเติบโตและเราต้องการที่จะเพิ่มผู้ให้บริการรายใหม่ แต่ก็มีอัตราส่วนประมาณ 1 หรือ 2 ต่อปี


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

ถามคำถาม แต่อย่าถามคำถาม! :) ใช่บางครั้งฉันก็ไม่เข้าใจความคิดของ mods
Mrchief

upvotes และมุมมองแสดงให้เห็นว่าคำถามนี้เกี่ยวข้องมากเพียงใด ...
NoobEditor

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

คำตอบ:


16

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

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

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

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

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

กำหนดแหล่งที่มาของการแจ้งเตือน

  • ภาษา / ระบบใดบ้างที่จะสร้างการแจ้งเตือน
  • เครื่องกำเนิดไฟฟ้ารู้จักผู้รับข้อความหรือไม่หรือมีให้โดยวิธีอื่น (เช่นกฎธุรกิจสำหรับการแจ้งเตือนบางประเภทไปยังผู้รับบางคน)
  • มีกฎทางธุรกิจสำหรับการเพิ่มใบเสร็จรับเงิน CC / BCC / อ่าน
  • เครื่องกำเนิดไฟฟ้าทราบประเภทของข้อความที่กำลังส่ง (เช่น SMS / อีเมล) หรือเป็นไปตามผู้รับ
  • เครื่องกำเนิดไฟฟ้าจำเป็นต้องมีการยืนยันข้อความที่ถูกส่ง / รับ / อ่าน (async กับการส่งแบบซิงโครนัส)
  • มีข้อกำหนดในการจัดเก็บประวัติของแหล่งข้อความ / ผู้รับ (นานแค่ไหน)

กำหนดจุดสิ้นสุดการแจ้งเตือน

  • มีการใช้บริการใดในการส่งข้อความ
  • มีข้อเสนอแนะ / การยืนยันอะไรบ้าง (ซิงค์ / async)
  • เป็นไปได้ไหมที่จะเพิ่มจุดสิ้นสุดใหม่ [แม้ว่าจะเป็นเช่นนั้นจะต้องมีการสรุปหรือไม่]

ฉันลังเลที่จะให้ตัวอย่างสถาปัตยกรรมที่เป็นรูปธรรมเนื่องจากมันขึ้นอยู่กับปัจจัยที่เกี่ยวข้องเป็นอย่างมาก แต่บ่อยครั้งที่ระบบข้อความที่ง่ายที่สุดเกี่ยวข้องกับคิวพื้นฐานไม่ว่าจะเป็นในหน่วยความจำ / แอปพลิเคชัน, ไม่มี SQL, ดิสก์หรือฐานข้อมูลเชิงสัมพันธ์ จากนั้นกระบวนการที่แยกต่างหาก (หรือกระบวนการที่แยกกันหลายอย่างถ้าแจกจ่าย) สามารถโพลคิวสำหรับประเภทข้อความของพวกเขา [เช่นงาน cron]; และส่งออกตามความจำเป็น

นอกจากนี้ยังสามารถปรับปรุงให้ดีขึ้นได้โดยใช้เทคนิคแบบพุช (เช่น PostgreSQL NOTIFY / LISTEN) หากมีข้อกำหนดสำหรับข้อความที่จะส่งทันที

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


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

-2

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

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