Ölçeklenebilir bir bildirim sistemi nasıl tasarlanır? [kapalı]


32

Bir bildirim sistemi yöneticisi yazmam gerekiyor.

İşte benim gereksinimlerim:

Tamamen farklı olabilecek farklı platformlarda bir Bildirim gönderebilmem gerekiyor (örneğin, SMS veya E-posta gönderebilmem gerekiyor).

Bazen bildirim, belirli bir platformdaki tüm alıcılar için aynı olabilir, ancak bazen platform başına alıcı (veya birkaç) başına bildirim olabilir.

Her bildirim platforma özgü veri yükü içerebilir (örneğin bir MMS bir ses veya görüntü içerebilir).

Sistemin ölçeklendirilebilir olması gerekiyor, uygulamayı veya sunucuyu kilitlemeden çok miktarda bildirim gönderebilmeliyim.

Bu iki aşamalı bir işlemdir, önce müşteri bir mesaj yazabilir ve gönderilecek bir platform seçebilir ve bildirimlerin daha sonra gerçek zamanlı olarak işlenmesi için oluşturulmalıdır.

Daha sonra sistemin bildirimi platform sağlayıcısına göndermesi gerekir.


Şimdilik biraz olsa bitirdim ama ne kadar ölçeklenebilir olacağını ya da iyi bir tasarım olup olmadığını bilmiyorum.

Aşağıdaki nesneleri (sözde bir dilde) düşündüm:

genel bir Notificationnesne:

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

Aşağıdaki nesnelerle ilgili sorun, 1.000.000 alıcı olduğumda ne olur? RecipientNesne çok küçük olsa bile , çok fazla bellek alacaktır.

Ayrıca alıcı başına bir Bildirim de oluşturabilirim, ancak bazı platform sağlayıcıları toplu iş olarak göndermemi gerektiriyor, bu da birden fazla Alıcı ile bir Bildirim tanımlamam gerektiği anlamına geliyor.

Her oluşturulan bildirim, bir DB veya Redis gibi kalıcı bir depoda saklanabilir.

Ölçeklenebilir olduğundan emin olmak için bunu daha sonra toplamak iyi olur mu?

İkinci adımda, bu bildirimi işleme koymam gerekiyor.

Ancak bildirimi doğru platform sağlayıcısına nasıl ayırt edebilirim?

Bir MMSNotificationgenişletme gibi bir nesne kullanmalı mıyım abstract Notification? ya da benzeri bir şey Notification.setType('MMS')?

Aynı anda birçok bildirimin işlenmesine izin vermek için, RabbitMQ gibi bir mesajlaşma kuyruk sisteminin doğru araç olabileceğini düşünüyorum. Bu mu?

Bir çok bildirimi sıraya koymamı ve birkaç çalışanı bildirip işlem yapmamı sağlayacaktı. Peki ya alıcıları yukarıda görüldüğü gibi gruplandırmam gerekiyorsa?

Sonra, her birini NotificationProcessorekleyebileceğim bir nesneyi platform sağlayıcısına bağlamak ve bildirimde bulunmaktan sorumlu olacağını hayal ediyorum .NotificationHandlerNotificationHandler

EventManagerTakılabilir davranışa izin vermek için bir de kullanabilirim .

Herhangi bir geri bildirim veya fikir?

Zaman ayırdığınız için teşekkürler.

Not: PHP'de çalışmaya alışkınım ve muhtemelen istediğim dil.


Düzenleme (morphunreal'in cevabına göre)

  • Saniyede kaç mesaj gönderiyorsunuz (Geçerli / başlangıç ​​seviyelerini tanımlayın, sistemin yeniden tasarlanmadan önce kullanması gereken bir maksimum seviye tanımlayın)
  • Sistemin hangi donanım kısıtlamaları var (sistem için mevcut bellek, işlemci vb.)
  • Donanım nasıl ölçeklenir (yani daha fazla sunucu, bulut bilişim vb. Eklemek)

  • Hangi diller / sistemler bildirimde bulunacak?

Kendi başıma, bildirim programlı olarak oluşturmak için ancak bir kullanıcı arabiriminden yapılandırılmış olarak sorumluyum.

  • Jeneratör mesajın alıcılarını biliyor mu (?) Veya başka bir yolla mı sağlanıyor (örneğin, belirli uyarı türleri için iş kuralları belirli alıcılara gidiyor)

Belirli bir alıcıya, bir alıcı grubuna (örneğin bir etiket sistemi kullanarak) veya tüm platform için bir bildirim oluşturmak mümkün olmalıdır.

  • CC / BCC / Read makbuzlarını eklemek için iş kuralları var mı

Evet. Bunun gerçekten platforma özgü olduğunu ve okuma veya cc'nin tüm platformlarda bulunmadığını unutmayın.

  • Jeneratör gönderdiği mesajın türünü biliyor mu (yani, SMS / e-posta) veya alıcıya mı bağlı

Bununla birlikte, alıcı, platformla ilgili olduğundan ve platformların verileri ele almanın farklı bir yolu olduğu için, UI'nin görüntülerin, bir sesin veya başka bir şeyin kurulmasına izin vermek için platforma özgü olması muhtemeldir.

  • Jeneratör gönderilen / alınan / okunan iletilerin onaylanmasını gerektirir mi?

Peki, sistem hataya açık olmalı, ancak bir kural kümesi tanımlamak için hatayı ele almak istiyoruz, örneğin, sunucuya erişilemiyorsa, bildirim daha sonraki işlemler için tekrar yapılmalı, ancak bildirim yanlışsa (veya Platform sağlayıcısı tarafından tanımlandığı gibi) yeniden doldurulmamalı, bildirilmemelidir.

  • İleti kaynaklarının / alıcılarının geçmişini saklamak için gereksinimler var mı (ne kadar süreyle?)

Evet, muhtemelen bazı istatistikler ve raporlar hazırlamak istiyoruz. * Bildirim Bitiş Noktalarını Tanımla


  • Mesaj göndermek için hangi servisler kullanılıyor? Bazıları klasik REST web hizmeti, bazıları ise egzotik protokol, gerçekten sağlayıcıya bağlı.

  • Hangi geri bildirim / onay sağlanır (senkron / asenkron)

Bağımlı olarak, bazıları senkronizedir ve bir hatayı cevaplarken, bazılarının hataları kontrol etmek için daha sonra çekilmeleri gerekir.

  • Yeni bitiş noktaları eklemek olası mıdır [öyle olsa bile, soyutlanması gerekebilir]

Evet, aslında, uygulamamız büyüyor ve muhtemelen yeni bir sağlayıcı ekleyebilmek istiyoruz, ancak yılda 1 veya 2 gibi bir oranın oranı.


22
Walter, gnat, gbjbaanb, Robert Harvey, thorsten müller tembel insanlar gibi görünüyor; Bu sorunun, şu argümanlardan biri nedeniyle kapanmasına neden olan bir sebep görmüyorum: "belirsiz, belirsiz, eksik, aşırı geniş veya retorik". Bir tasarım sorusu basit bir soru olamaz çünkü çok fazla şey içermektedir, bu web sitesinin seviyesinin bu kadar karmaşık kararların gerçek profesyonellerle tartışılmasına izin vermesine rağmen.
Trent,

Soru sor ama soru sorma! :) Evet, bazen ben de modların zihniyetini anlayamıyorum.
Şef,

Olumlu oylar ve görüşler bu sorunun ne kadar alakalı olduğunu gösteriyor .... eğer sadece moderatörler anlasaydı !!!
NoobEditor

RabbitMQ kullanmak bu problem için doğru yaklaşımdır. BIG şirket görüşmelerimden birinde çok benzer bir soruyu sordum ve hataya en iyi toleranslı yayıncı / abone modeli ile mücadele ediyordum. Sonunda bana doğru cevap söylendi. RabbitMQ. Kullanarak sorunu çözmüş gibi görünüyorlar. Umarım yardımcı olur!!!
AkD,

Yanıtlar:


16

İşlevsel ve işlevsel olmayan gereksinimlerinizi ayırarak ve bunları dikkatlice tanımlayarak başlayın. Belirsiz gereksinimlere dayanan bir sistemi fazla tasarlamak çok kolaydır.

Örneğin, ölçeklenebilirlik açısından işlevsel olmayan gereksinimleriniz oldukça belirsizdir. Sisteminize gerçek rakamlar koyarsanız, çok fazla zihinsel yükü azaltabilir. Örneğin,

  • Saniyede kaç mesaj gönderiyorsunuz (Geçerli / başlangıç ​​seviyelerini tanımlayın, sistemin yeniden tasarlanmadan önce kullanması gereken bir maksimum seviye tanımlayın)
  • Sistemin hangi donanım kısıtlamaları var (sistem için mevcut bellek, işlemci vb.)
  • Donanım nasıl ölçeklenir (yani daha fazla sunucu, bulut bilişim vb. Eklemek)

Artık bunun dışında olduğunuza göre, sistem tasarımı / mimarisinin işlevsel olmayan gereksinimlerinizi yerine getirebildiğinden emin olmak için bazı testler yapabilirsiniz .

Bildirim / mesaj göndermenin işletme / işlevsel gereksinimlerine gelince, aşağıdaki ipuçları yardımcı olabilir (daha fazla bilgi sağlarsanız bu cevaba ekleyebilirim):

Bildirim kaynaklarını tanımlayın

  • Hangi diller / sistemler bildirimde bulunacak?
  • Jeneratör mesajın alıcılarını biliyor mu (?) Veya başka bir yolla mı sağlanıyor (örneğin, belirli uyarı türleri için iş kuralları belirli alıcılara gidiyor)
  • CC / BCC / Read makbuzlarını eklemek için iş kuralları var mı
  • Jeneratör gönderdiği mesajın türünü biliyor mu (yani, SMS / e-posta) veya alıcıya mı bağlı
  • Jeneratör gönderilen / alınan / okunan iletilerin onaylanmasını gerektirir mi?
  • İleti kaynaklarının / alıcılarının geçmişini saklamak için gereksinimler var mı (ne kadar süreyle?)

Bildirim Bitiş Noktalarını Tanımla

  • Mesaj göndermek için hangi servisler kullanılıyor
  • Hangi geri bildirim / onay sağlanır (senkron / asenkron)
  • Yeni bitiş noktaları eklemek olası mıdır [öyle olsa bile, soyutlanması gerekebilir]

İlgili faktörlere dayanarak yoğun bir şekilde bağlı olacağı için somut bir mimari örnek vermekte tereddüt ediyorum; ancak çoğu zaman en basit mesaj sistemleri, hafızada / uygulamada, SQL'de, diskte veya ilişkisel veritabanında temel bir sıra içerir. Daha sonra ayrı bir işlem (ya da dağıtılmışsa birkaç ayrı işlem) mesaj türleri için kuyruğu yok edebilir [yani bir cron işi]; ve gerektiği gibi gönderin.

Mesajların hemen gönderilmesi için bir gereksinim varsa, bazı itme tabanlı teknikler (örn. PostgreSQL NOTIFY / LISTEN) kullanılarak da geliştirilebilir.

Basit bir sıranın avantajı, mesajı oluşturan sistemin yapacak çok az işi olması ve işlem sisteminin donanım / performans gereksinimlerine göre dengelenebilmesidir.


Bazı net cevaplarınız için çok net teşekkür ederim. Verdiğim soruları cevaplamak için cevabımı düzenledim.
Trent,

-2

Bildirim nesneleriniz için kolay tasarım desenini düşündünüz mü? Bu konuda hiçbir zaman emin değilim, çünkü modeli asla uygulamamıştım, ancak şunu hatırlıyorum: bazı halleri uçucu nesneler arasında paylaşmayı içeriyor. Ayrıca, daha fazla yedekliliğe sahip üyelerin paylaşıldıklarında daha büyük etkiye sahip olduğunu düşünüyorum. Bu nedenle, birçok kişiye yalnızca birkaç msj göndermenize veya bunun tersi olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.