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):
Notification
objek 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 Recipient
objeknya 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 MMSNotification
memperluas 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 NotificationProcessor
objek yang saya bisa saya tambahkan NotificationHandler
masing NotificationHandler
- masing akan bertanggung jawab untuk menghubungkan penyedia platform dan melakukan notifikasi.
Saya juga bisa menggunakan a EventManager
untuk 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.
Jawaban:
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,
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
Tentukan Poin Akhir Pemberitahuan
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.
sumber
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.
sumber