Wymagania wstępne
Upewnij się, że masz zainstalowane Erlang i Elixir na swoim komputerze. W tym poradniku używam następujących wersji:
Będziesz także potrzebować uruchomionego Dockera. Używam Docker Compose, więc upewnij się, że masz go również zainstalowanego.
Konfigurowanie środowiska
Na początek utworzymy dwie oddzielne instancje Phoenix:
Zanim uruchomimy instancje, musimy skonfigurować kilka plików.
Utwórz docker-compose.yml:
W katalogu głównym projektu utwórz plik docker-compose.yml
:
Upewnij się, że nazwa sieci jest taka sama dla wszystkich instancji.
Utwórz Dockerfile:
W katalogu głównym projektu utwórz plik Dockerfile
:
Utwórz entrypoint-dev.sh:
W katalogu głównym projektu utwórz plik entrypoint-dev.sh
:
Utwórz .env:
W katalogu głównym projektu utwórz plik .env
:
Edytuj plik dev.exs:
Aby umożliwić dostęp do obu instancji przez localhost, przejdź do pliku config/dev.exs
i zmodyfikuj wiersz 12:
Uruchamianie instancji
Otwórz terminal w katalogu głównym projektu i utwórz sieć, która połączy kontenery:
Następnie uruchom kontenery za pomocą poniższego polecenia:
Teraz aplikacje powinny działać na portach określonych w pliku .env
. W moim przypadku są dostępne pod:
Konfigurowanie Libcluster
Teraz skonfigurujemy klaster dla instancji.
Zainstaluj libcluster:
Na początek musimy zainstalować libcluster jako zależność. Aby to zrobić, dodaj go do pliku mix.exs
:
Konfiguracja topologii
Następnie skonfigurujemy topologię. W tym przykładzie użyjemy strategii Gossip, która automatycznie odkrywa węzły w sieci.
W pliku config/config.exs
dodaj następujące linie na końcu, przed import_config:
Jeśli chcesz mieć większą kontrolę nad węzłami, możesz również skorzystać z strategii EPMD. Upewnij się, że sprawdziłeś dokumentację libcluster w poszukiwaniu innych dostępnych opcji.
Inicjalizacja Libcluster
Teraz musimy aktywować Libcluster podczas uruchamiania aplikacji.
Dodaj poniższe linie do pliku lib/*_instance/application.ex
:
Sprawdzanie połączenia
Teraz zbudujemy ponownie instancje i sprawdzimy dzienniki. Uruchom poniższe polecenia w obu katalogach:
Kiedy obie instancje działają, w jednej z nich (zwykle tej, która uruchomiła się pierwsza) powinno pojawić się coś takiego:
To oznacza, że nasze instancje zostały pomyślnie połączone i są gotowe do interakcji za pomocą PubSub!
Konfigurowanie PubSub
Teraz czas skonfigurować PubSub, aby umożliwić interakcję między instancjami.
W tym przewodniku rozdzielimy zadania na dwie instancje:
- Instancja 1 będzie wysyłać wiadomości.
- Instancja 2 będzie je odbierać.
Najpierw jednak musimy upewnić się, że obie instancje używają tego samego PubSub.
Aby to zrobić, otwórz plik config/config.exs
w obu instancjach i zmodyfikuj wiersz 22 (lub miejsce, gdzie jest konfiguracja endpointu):
Następnie w pliku lib/*_instance/application.ex
zaktualizuj funkcję start:
Ustawianie Nadawcy
Ten krok jest dość prosty; wszystko, co musimy zrobić, to wywołać funkcję PubSub.broadcast_from/3 z jakiegoś miejsca. Użyjemy do tego Phoenix LiveView.
Utwórz następujące pliki:
lib/first_instance_web/live/sender_live/index.ex
:
lib/first_instance_web/live/sender_live/index.html.heex
:
Teraz dodaj nową trasę na żywo w zakresie przeglądarki w lib/first_instance_web/router.ex
:
Odwiedź localhost:4000/sender i przetestuj kliknięcie przycisku. Jeśli wszystko jest skonfigurowane poprawnie, powinieneś zobaczyć komunikat o sukcesie.
Konfiguracja Odbiorcy
W tym samouczku zainicjalizuję subskrypcję PubSub wraz z aplikacją, aby uniknąć tworzenia innej strony. Dzięki PubSub możesz wysyłać wiadomości na każdą stronę, ale tylko użytkownicy połączeni z tą stroną otrzymają wiadomości. Inicjalizując PubSub z aplikacją, pozwala mi to używać go jak aplikacji do przesyłania wiadomości (np. RabbitMQ), umożliwiając interakcje z wydarzeniami na odbiorniku, niezależnie od tego, czy są połączeni użytkownicy.
Utwórz plik lib/second_instance/listener.ex
z następującą zawartością:
Na koniec, w application.ex
, dodaj odbiornik do listy dzieci:
Test końcowy
Świetnie! Teraz, gdy zakończyłeś konfigurację, system powinien działać zgodnie z oczekiwaniami:
- Otwórz logi Dockera dla odbiornika (jak w moim przypadku example_two) za pomocą następującego polecenia:
-
Przejdź do strony internetowej pierwszej instancji (np. example_one) w przeglądarce: localhost:4000/sender
-
Kliknij przycisk, aby wysłać sygnał. Za każdym razem, gdy klikniesz przycisk, powinieneś zobaczyć następujący komunikat w logach odbiornika:
To oznacza, że PubSub działa poprawnie, a instancje komunikują się za pośrednictwem LibCluster i Phoenix PubSub. Teraz twoje dwie instancje są gotowe do interakcji ze sobą, wysyłając i odbierając wiadomości w klastrze.
Możesz używać tej metody do różnych zastosowań, takich jak:
-
Powiadomienia w czasie rzeczywistym: Wysyłaj powiadomienia między różnymi węzłami w klastrze, na przykład informując użytkowników z różnych instancji o nowych wiadomościach, zdarzeniach systemowych lub aktualizacjach na żywo.
-
Rozproszone przetwarzanie zadań: Dziel zadania między wieloma węzłami do równoległego przetwarzania. Na przykład każda instancja może obsługiwać różne części dużego zbioru danych lub obciążenia, a węzły mogą koordynować za pomocą wiadomości.
-
Aplikacje czatu w wielu instancjach: Zbuduj system czatu, w którym użytkownicy połączeni z różnymi węzłami mogą nadal wymieniać wiadomości w czasie rzeczywistym, korzystając z PubSub do komunikacji między instancjami.
-
Aktualizacje na żywo w pulpitach nawigacyjnych: Jeśli masz wiele serwerów obsługujących różne strumienie danych, możesz wysyłać aktualizacje do pulpitów użytkowników w czasie rzeczywistym, nawet jeśli użytkownik jest połączony z innym węzłem niż ten, z którego pochodziły dane.
Używam tej konfiguracji z ponad 30 instancjami, z których żadna nie jest świadoma istnienia innych, ale wszystkie otrzymują zdarzenia z „centralnej” instancji.
Śmiało eksploruj swoje własne pomysły i dostosuj tę konfigurację do potrzeb swojego projektu!