2012-03-02 12 views
7

To, co mam zamiar opisać, jest zasadniczo dwufazowym problemem popełnianym między dwoma odmiennymi systemami i szukam porady, jak sobie z nim radzić. W naszej aplikacji internetowej usuwamy niektóre kosztowne/niezależne operacje, takie jak wysyłanie wiadomości e-mail, poza pasmowe procesy robocze w tle (nazywamy to naszą infrastrukturą pracy).Dwuetapowe zatwierdzanie - jak skutecznie korzystać z mojej kolejki?

Aby wysłać wiadomość e-mail, na przykład w naszej bazie danych tworzymy zarówno obiekt e-mail, jak i pocztę e-mail. Następnie musimy poczekać, aż nasz monitor pracy odbierze pocztę i wyśle ​​ją. Monitor pracy zasadniczo działa poprzez odpytywanie bazy danych co kilka sekund, gdy jest bezczynny.

Dodaje to jednak opóźnienie w wysyłaniu wiadomości e-mail i dodaje to, co uważam za niepotrzebne obciążenie bazy danych z pollingiem. Byłoby o wiele ładniej, gdybyśmy mogli natychmiast umieścić zadanie poczty elektronicznej w kolejce zaraz po utworzeniu wiadomości e-mail.

Jednak obecnie się to nie udaje z dwóch powodów. Po pierwsze, kolejka jest często znacznie szybsza niż żądanie sieciowe. Wiadomość e-mail jest pobierana do przetwarzania, zanim żądanie sieci zostanie zatwierdzone przez transakcję bazy danych, więc nie może poprawnie wygenerować wiadomości e-mail. Po drugie, jeśli żądanie WWW nie powiedzie się, wycofuje transakcję bazy danych, co oznacza, że ​​wiadomość e-mail powinna być wysłana pod numer , a nie. Jeśli jednak został już umieszczony w kolejce, nie jest już kontrolowany przez żądanie.

Czy istnieje dobra strategia tworzenia zatwierdzania dwufazowego między kolejką a bazą danych? Dla odniesienia używamy RabbitMQ i MySQL z tabelami InnoDB. Jednym z pomysłów, którym kierowałem, było przyklejenie zadań do wiadomości e-mail w kolejce po zatwierdzeniu transakcji bazy danych, ale to pozostawia możliwość, że e-mail nigdy nie zostanie umieszczony w kolejce. Nadal będę musiał utworzyć proces odpytywania, który będzie monitorował wiadomości e-mail, które powinny zostać wysłane, a które nie.

Odpowiedz

0

Zdaję sobie sprawę, że spóźniam się o kilka lat :) ale chciałem dodać kilka przemyśleń na ten temat dla innych osób, które mają na to pytanie.

Wiadomość można wysłać z opóźnieniem, aby zwiększyć szanse, że baza danych będzie gotowa po otrzymaniu zlecenia. Nigdy nie użyłem RabbitMQ, ale znalazłem ten przykład użycia kolejki rabbitMQ jako opóźnionej kolejki How to create a delayed queue in RabbitMQ?. Twoja praca z pocztą e-mail nadal będzie musiała zajmować się nieskomentowanymi zapisami, ponieważ opóźnienie nie jest deterministyczną metodą postępowania z przetwarzaniem rozproszonym.

To powiedziawszy, wydaje się, że jest miejsce na ulepszenie swojego projektu. Zasadniczo architektura usług nie jest dobrym pomysłem na udostępnianie tabel db między usługami. Prowadzi to do rozproszonych transakcji i skalowania problemów. Chciałbym się upewnić, że wiadomość RabbitMQ zawiera wszystkie dane potrzebne do przetworzenia wiadomości e-mail niezależnie od innych usług. Lub jeśli potrzebuje więcej danych, powinien zażądać danych za pośrednictwem żądania ServiceBus zamiast zapytania DB.

Powiązane problemy