Chciałbym wiedzieć, jak inne osoby radzą sobie z odzyskiwaniem po błędnym połączeniu przy użyciu oficjalnej biblioteki klienta java RabbitMQ. Używamy go do łączenia naszych serwerów aplikacji z naszym klastrem RabbitMQ i wdrożyliśmy kilka różnych sposobów na odzyskanie po awarii połączenia, ale żaden z nich nie czuje się dobrze.Jak radzisz sobie z odzyskiwaniem po błędnym połączeniu za pomocą biblioteki klienta java RabbitMQ?
Wyobraźmy sobie tę aplikację pseudo:
public class OurClassThatStartsConsumers {
Connection conn;
public void start() {
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("someusername");
factory.setPassword("somepassword");
factory.setHost("somehost");
conn = factory.newConnection();
new Thread(new Consumer(conn.createChannel())).start();
}
}
class Consumer1 implements Runnable {
public Consumer1(Channel channel) {
this.channel = channel;
}
@Override
public void run() {
while (true) {
... consume incoming messages on the channel...
// How do we handle that the connection dies?
}
}
}
w rzeczywistym świecie mamy kilkaset konsumentów. Co się stanie, jeśli połączenie zginie? W powyższym przykładzie Consumer1 nie może odzyskać, gdy połączenie zostanie zamknięte, Kanał również się zamknie, stan, z którego nie możemy odzyskać. Więc spójrzmy na kilka sposobów, aby rozwiązać ten problem:
roztwór A)
Niech każdy konsument ma swoje własne połączenia i rejestrowania zdarzeń, które powodują, kiedy umiera połączenie, a następnie obsługiwać podłączając.
Plusy: Działa
Wady:
- Ponieważ mamy dużo konsumentów, prawdopodobnie nie chce, że wiele połączeń.
- Możemy ewentualnie mieć dużo kodu duplikowane dla podłączając do królika i obsługiwać podłączając
roztwór B)
mieć każdy konsument używać tego samego połączenia i zapisz się to z połączeniem zdarzeń awaryjnych.
Plusy: mniej połączeń niż w roztworze A
Wady: Ponieważ połączenie jest zamykane musimy ponownie otworzyć/wymienić. Biblioteka klienta Java nie wydaje się być sposobem na ponowne otwarcie połączenia, więc musielibyśmy zastąpić go nowym połączeniem, a następnie jakoś powiadomić wszystkich konsumentów o tym nowym połączeniu i musieliby odtworzyć kanały i konsumentów . Ponownie pojawia się tam wiele logiki, których nie chcę widzieć u konsumenta.
Roztwór C)
Wrap Connection
i Channel
zajęcia to zajęcia, które zajmują logikę ponownego połączenia, konsument musi tylko wiedzieć o klasie WrappedChannel
. W przypadku błędu połączenia, WrappedConnection
zajmie się ponownym nawiązaniem połączenia, a po podłączeniu WrappedConnection
automatycznie utworzy nowe kanały i zarejestruje odbiorców.
Zalety: Działa - jest to właściwie rozwiązanie, którego używamy dzisiaj.
Minusy: Czuję się jak haker, myślę, że jest to coś, co powinno być obsługiwane bardziej elegancko przez leżącą pod nim bibliotekę.
Może jest o wiele lepszy sposób? Dokumentacja API nie mówi zbyt wiele o odzyskiwaniu po błędnym połączeniu.Wszelkie dane wejściowe są mile widziane :)
Czy możesz podać podpowiedź, jak to zakodować. Ponieważ wydaje się, że nie ma wywołania zwrotnego, na którym możemy odzyskać wszystkie kanały, kolejki i powiązania. Czy możesz mi powiedzieć, jak dokładnie powinienem zawinąć połączenie? – jeevs
Będziesz musiał owinąć Połączenie i Kanał, nie ma możliwości odzyskania kanału po jego rozłączeniu, więc będziesz musiał utworzyć nowy. –