Bagaimana cara merancang sistem notifikasi yang dapat diskalakan? [Tutup]

32

Saya perlu menulis manajer sistem notifikasi.

Inilah persyaratan saya:

Saya harus dapat mengirim Pemberitahuan pada platform yang berbeda, yang mungkin sangat berbeda (misalnya, saya harus dapat mengirim SMS atau email).

Kadang-kadang notifikasi mungkin sama untuk semua penerima untuk platform yang diberikan, tetapi kadang-kadang juga notifikasi untuk setiap penerima (atau beberapa) per platform.

Setiap notifikasi dapat berisi muatan khusus platform (untuk contohnya sebuah MMS dapat berisi suara atau gambar).

Sistem harus scalable , saya harus dapat mengirim notifikasi dalam jumlah yang sangat besar tanpa menabrak aplikasi atau server.

Ini adalah proses dua langkah, pertama pelanggan dapat mengetik pesan dan memilih platform untuk dikirim, dan pemberitahuan harus dibuat untuk diproses baik secara waktu nyata atau kemudian.

Maka sistem perlu mengirim pemberitahuan ke penyedia platform.


Untuk saat ini, saya berakhir dengan beberapa tetapi saya tidak tahu seberapa scalable itu akan atau apakah itu desain yang bagus.

Saya telah memikirkan benda-benda berikut (dalam bahasa pseudo):

Notificationobjek generik :

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

Masalah dengan objek-objek berikut adalah bagaimana jika saya memiliki 1.000.000 penerima? Bahkan jika Recipientobjeknya sangat kecil, itu akan memakan terlalu banyak memori.

Saya juga dapat membuat satu Notifikasi per penerima, tetapi beberapa penyedia platform mengharuskan saya untuk mengirimkannya dalam batch, artinya saya perlu mendefinisikan satu Notifikasi dengan beberapa Penerima.

Setiap notifikasi yang dibuat dapat disimpan dalam penyimpanan persisten seperti DB atau Redis.

Akankah itu baik untuk mengumpulkan ini nanti untuk memastikan itu dapat diskalakan?

Pada langkah kedua, saya perlu memproses pemberitahuan ini.

Tetapi bagaimana saya bisa membedakan notifikasi dengan penyedia platform yang tepat?

Haruskah saya menggunakan objek seperti MMSNotificationmemperluas abstract Notification? atau semacamnya Notification.setType('MMS')?

Untuk memungkinkan memproses banyak notifikasi pada saat bersamaan, saya pikir sistem antrian pesan seperti RabbitMQ mungkin merupakan alat yang tepat. Apakah itu?

Itu akan memungkinkan saya untuk mengantri banyak notifikasi dan meminta beberapa pekerja memunculkan notifikasi dan memprosesnya. Tetapi bagaimana jika saya perlu mengelompokkan penerima seperti terlihat di atas?

Lalu saya membayangkan NotificationProcessorobjek yang saya bisa saya tambahkan NotificationHandlermasing NotificationHandler- masing akan bertanggung jawab untuk menghubungkan penyedia platform dan melakukan notifikasi.

Saya juga bisa menggunakan a EventManageruntuk memungkinkan perilaku pluggable.

Ada umpan balik atau ide?

Terima kasih telah memberikan waktu Anda.

Catatan: Saya sudah terbiasa bekerja di PHP dan kemungkinan itu adalah bahasa pilihan saya.


Sunting (sesuai dengan jawaban morphunreal)

  • Berapa banyak pesan per detik yang Anda kirim (Tetapkan level saat ini / awal, tentukan level maksimum yang harus ditangani sistem sebelum dirancang ulang)
  • Kendala perangkat keras apa yang dimiliki sistem (memori, CPU, dll. Tersedia untuk sistem)
  • Bagaimana skala perangkat keras (mis., Menambah lebih banyak server, komputasi awan, dll.)

  • Bahasa / sistem apa yang akan menghasilkan notifikasi?

Ini adalah saya sendiri, saya bertanggung jawab untuk membuat notifikasi secara terprogram tetapi dibuat dari UI.

  • Apakah generator mengetahui penerima pesan (?) Atau apakah mereka disediakan dengan cara lain (yaitu, aturan bisnis untuk jenis lansiran tertentu ditujukan ke penerima tertentu)

Seharusnya dimungkinkan untuk membuat pemberitahuan untuk penerima tertentu, sekelompok penerima (misalnya menggunakan sistem tag), atau untuk seluruh platform.

  • Apakah ada aturan bisnis untuk menambahkan tanda terima CC / BCC / Baca

Iya nih. Perhatikan bahwa ini benar-benar platform khusus dan baca atau cc tidak tersedia di semua platform.

  • Apakah generator mengetahui jenis pesan yang dikirim (yaitu, SMS / email) atau didasarkan pada penerima

Ini didasarkan pada penerima, bagaimanapun, karena penerima terkait platform, dan platform memiliki cara berbeda untuk menangani data, UI cenderung menjadi platform spesifik untuk memungkinkan mengatur gambar, suara atau sesuatu.

  • Apakah generator memerlukan konfirmasi pesan yang dikirim / diterima / baca (async vs pengiriman sinkron)

Ya, sistem seharusnya rawan kesalahan, tetapi kami ingin menangani kesalahan untuk menetapkan seperangkat aturan, misalnya, jika server tidak dapat dijangkau, pemberitahuan harus dikirim kembali untuk proses lebih lanjut, tetapi jika pemberitahuannya tidak benar (atau telah didefinisikan sebagaimana oleh penyedia platform) itu tidak harus diulang kembali tetapi diberitahu.

  • Apakah ada persyaratan untuk menyimpan riwayat sumber / penerima pesan (berapa lama?)

Ya, kami mungkin ingin membuat beberapa statistik dan laporan. * Tentukan Poin Akhir Pemberitahuan


  • Layanan apa yang digunakan untuk mengirim pesan? Tergantung, ada yang layanan web SISA klasik, ada yang protokol eksotis, itu benar-benar terserah penyedia.

  • Umpan balik / konfirmasi apa yang disediakan (sinkronisasi / async)

Tergantung, ada yang sinkron dan membalas dengan kesalahan sementara yang lain perlu ditarik setelahnya untuk memeriksa kesalahan.

  • Apakah mungkin menambah titik akhir baru [bahkan jika demikian, apakah itu bahkan perlu diabstraksi]

Ya, sebenarnya, aplikasi kami sedang berkembang dan kami kemungkinan ingin dapat menambahkan penyedia baru, tetapi ini adalah rasio sekitar 1 atau 2 per tahun.

Trent
sumber
22
Walter, nyamuk, gbjbaanb, Robert Harvey, thorsten müller tampaknya adalah orang-orang yang malas; Saya tidak melihat alasan mengapa pertanyaan ini ditutup karena salah satu argumen berikut: "ambigu, kabur, tidak lengkap, terlalu luas, atau retoris". Pertanyaan desain tidak bisa menjadi pertanyaan sederhana karena melibatkan banyak hal, saya pikir tingkat situs web ini memungkinkan keputusan yang rumit untuk didiskusikan dengan profesional sejati.
Trent
Ajukan pertanyaan tetapi jangan ajukan pertanyaan! :) Ya, kadang-kadang saya juga gagal memahami mentalitas para mod.
Mrchief
Suara positif dan pandangan menunjukkan seberapa banyak pertanyaan ini relevan .... jika saja moderator akan mengerti !!!
NoobEditor
Menggunakan RabbitMQ adalah pendekatan yang tepat untuk masalah ini. Saya ditanyai masalah yang sangat mirip dalam salah satu wawancara perusahaan BESAR saya dan saya berjuang dengan pola penerbit / pelanggan toleran kesalahan terbaik. Pada akhirnya saya diberitahu jawaban yang benar. RabbitMQ. Sepertinya mereka telah memecahkan masalah menggunakannya. Semoga itu bisa membantu !!!
AkD

Jawaban:

16

Mulailah dengan memisahkan persyaratan fungsional dan non-fungsional Anda, dan dengan hati-hati mendefinisikannya. Sangat mudah untuk mendesain ulang sistem berdasarkan persyaratan yang ambigu.

Misalnya, persyaratan non-fungsional Anda dalam hal skalabilitas cukup ambigu. Ini dapat meringankan banyak beban mental jika Anda memasukkan angka aktual pada sistem Anda. Sebagai contoh,

  • Berapa banyak pesan per detik yang Anda kirim (Tetapkan level saat ini / awal, tentukan level maksimum yang harus ditangani sistem sebelum dirancang ulang)
  • Kendala perangkat keras apa yang dimiliki sistem (memori, CPU, dll. Tersedia untuk sistem)
  • Bagaimana skala perangkat keras (mis., Menambah lebih banyak server, komputasi awan, dll.)

Sekarang setelah Anda dapat melakukannya, Anda dapat mengatur beberapa tes untuk memastikan bahwa desain / arsitektur sistem mampu memenuhi persyaratan non-fungsional Anda.

Adapun persyaratan bisnis / fungsional untuk mengirim pemberitahuan / pesan, petunjuk berikut ini dapat membantu (jika Anda memberikan informasi lebih lanjut, saya dapat menambahkan jawaban ini):

Tentukan sumber pemberitahuan

  • Bahasa / sistem apa yang akan menghasilkan notifikasi
  • Apakah generator mengetahui penerima pesan (?) Atau apakah mereka disediakan dengan cara lain (yaitu, aturan bisnis untuk jenis lansiran tertentu ditujukan ke penerima tertentu)
  • Apakah ada aturan bisnis untuk menambahkan tanda terima CC / BCC / Baca
  • Apakah generator mengetahui jenis pesan yang dikirim (yaitu, SMS / email) atau didasarkan pada penerima
  • Apakah generator memerlukan konfirmasi pesan yang dikirim / diterima / baca (async vs pengiriman sinkron)
  • Apakah ada persyaratan untuk menyimpan riwayat sumber / penerima pesan (berapa lama?)

Tentukan Poin Akhir Pemberitahuan

  • Layanan apa yang digunakan untuk mengirim pesan
  • Umpan balik / konfirmasi apa yang disediakan (sinkronisasi / async)
  • Apakah mungkin menambah titik akhir baru [bahkan jika demikian, apakah itu bahkan perlu diabstraksi]

Saya ragu-ragu untuk memberikan contoh arsitektur beton karena akan sangat bergantung pada faktor-faktor yang terlibat; tetapi seringkali sistem pesan yang paling sederhana melibatkan antrian dasar, baik dalam memori / aplikasi, no-SQL, disk, atau basis data relasional. Kemudian proses terpisah (atau beberapa proses terpisah jika didistribusikan) dapat polling antrian untuk jenis pesan mereka [yaitu pekerjaan cron]; dan kirim seperlunya.

Ini juga dapat ditingkatkan dengan menggunakan beberapa teknik berbasis push (yaitu PostgreSQL NOTIFY / LISTEN) jika ada persyaratan untuk pesan yang akan dikirim segera.

Keuntungan dari antrian sederhana, adalah bahwa sistem yang menghasilkan pesan memiliki sedikit pekerjaan yang harus dilakukan, dan sistem pemrosesan dapat diseimbangkan berdasarkan persyaratan perangkat keras / kinerja.

nathan-m
sumber
terima kasih banyak atas jawaban detail Anda yang sebenarnya membantu saya untuk memiliki beberapa ide yang lebih jelas. Saya mengedit jawaban saya untuk menjawab pertanyaan yang Anda ajukan.
Trent
-2

Sudahkah Anda mempertimbangkan pola desain kelas terbang untuk objek notifikasi Anda? Saya tidak terlalu yakin tentang hal itu, karena saya tidak pernah menerapkan pola, tetapi saya ingat itu melibatkan berbagi beberapa keadaan di antara objek-objek kelas terbang. Saya juga berpikir, anggota dengan redundansi yang lebih besar memiliki dampak yang lebih besar jika dibagikan. Jadi itu tergantung jika Anda hanya mengirim beberapa pesan ke banyak orang atau sebaliknya.

Christoph
sumber