Jestem na początku budowania systemu powiadomień w stylu Facebooka dla naszej strony (typ gier społecznościowych) i teraz badam, jak najlepiej zaprojektować taki system. Nie interesuje mnie, jak wysyłać powiadomienia do użytkownika ani nic w tym rodzaju (na razie nawet). Badam, jak zbudować system na serwerze (jak przechowywać powiadomienia, gdzie je przechowywać, jak je pobrać itp.).
A więc ... niektóre wymagania, które mamy:
- w godzinach szczytu mamy około 1 tys. jednocześnie zalogowanych użytkowników (i znacznie więcej gości, ale nie mają oni tutaj znaczenia, ponieważ nie będą mieli powiadomień), które wygenerują wiele zdarzeń
- będą różne rodzaje powiadomień (użytkownik A dodał Cię jako znajomego, użytkownik B skomentował Twój profil, użytkownik C polubił Twój obraz, użytkownik D pokonał Cię w grze X, ...)
- większość wydarzeń wygeneruje 1 powiadomienie dla 1 użytkownika (użytkownik X polubił Twój obraz), ale zdarzają się przypadki, gdy jedno zdarzenie wygeneruje wiele powiadomień (na przykład urodziny użytkownika Y)
- powiadomienia powinny być zgrupowane razem; jeśli na przykład czterech różnych użytkowników lubi jakiś obraz, właściciel tego obrazu powinien otrzymać jedno powiadomienie informujące, że obraz podobał się czterem użytkownikom, a nie cztery oddzielne powiadomienia (tak jak robi to FB)
OK, więc pomyślałem, że powinienem stworzyć coś w rodzaju kolejki, w której będę przechowywać zdarzenia, gdy się pojawią. Wtedy miałbym zadanie w tle ( biegacz ?), Które przeglądałoby tę kolejkę i generowało powiadomienia na podstawie tych zdarzeń. To zadanie przechowuje następnie powiadomienia w bazie danych dla każdego użytkownika (więc jeśli zdarzenie dotyczy 10 użytkowników, byłoby 10 oddzielnych powiadomień). Następnie, gdy użytkownik otwierał stronę z listą powiadomień, czytałem mu wszystkie te powiadomienia (myśleliśmy o tym, żeby ograniczyć to do 100 najnowszych) i grupowałem je razem, a na koniec wyświetlałem.
Rzeczy, które mnie interesują w przypadku tego podejścia:
- skomplikowane jak diabli :)
- czy baza danych to najlepsza pamięć masowa tutaj (używamy MySQL), czy powinienem użyć czegoś innego (redis też wydaje się pasować)
- co mam przechowywać jako powiadomienie? identyfikator użytkownika, identyfikator użytkownika, który zainicjował zdarzenie, typ zdarzenia (żebym mógł je pogrupować i wyświetlić odpowiedni tekst), ale wtedy trochę nie wiem, jak przechowywać rzeczywiste dane powiadomienia (na przykład adres URL i tytuł obrazu, który był lubiany). Czy powinienem po prostu „upiec” te informacje podczas generowania powiadomienia, czy też powinienem zapisać identyfikator rekordu (obraz, profil, ...), na który ma to wpływ, i wyciągnąć informacje z bazy danych podczas wyświetlania powiadomienia.
- wydajność powinna być tutaj OK, nawet jeśli muszę przetwarzać 100 powiadomień w locie podczas wyświetlania strony powiadomień
- możliwy problem z wydajnością przy każdym żądaniu, ponieważ musiałbym wyświetlać użytkownikowi liczbę nieprzeczytanych powiadomień (co mogłoby być problemem samo w sobie, ponieważ grupowałbym powiadomienia razem). Można by tego jednak uniknąć, gdybym wygenerował widok powiadomień (gdzie są one zgrupowane) w tle, a nie w locie
Co myślisz o zaproponowanym przeze mnie rozwiązaniu i moich obawach? Proszę o komentarz, jeśli sądzisz, że powinienem wspomnieć o czymś innym, co byłoby tutaj istotne.
Och, używamy PHP dla naszej strony, ale myślę, że nie powinno to być dużym czynnikiem.