Wie kann ich die Verbreitung veralteter/falscher RabbitMQ-Verbindungsobjekte im Verwaltungs-Plugin verhindern, ohne den Server zu aktualisieren?

Wie kann ich die Verbreitung veralteter/falscher RabbitMQ-Verbindungsobjekte im Verwaltungs-Plugin verhindern, ohne den Server zu aktualisieren?

Kontext:

Wir verwenden einen RabbitMQ 2.8.4 HA-Cluster für die Nachrichtenübermittlung in einem mittelgroßen Rechenzentrum (Hunderte bis Tausende von Servern). Die Nachrichtenfunktionen sind für unsere App von entscheidender Bedeutung.

Wir verwenden die C-Client-API für AMQP/RabbitMQ-Operationen und die HTTP-API für das RabbitMQ-Verwaltungs-Plugin, um den Warteschlangenstatus regelmäßig zu überwachen und Warnungen basierend auf Größe/Durchsatz usw. zu senden.

Die einzigen von Clients zu den Messaging-Servern zulässigen Ports/Verbindungen befinden sich auf den AMQP-Ports und auf HTTP für die Verwaltungs-API.

Für die nahe Zukunft hat das Management entschieden, dass Ausfallzeiten des Messaging-Clusters (was Ausfallzeiten für bestimmte Teile der App bedeutet) nicht akzeptabel sind. In einigen Monaten wird dies möglich sein, aber bis dahin können wir aus verkaufsorientierten Gründen keine Wartung des Messaging-Systems durchführen. Das ist zwar ärgerlich, aber wir (die Infrastruktur-/DevOps-Leute) können diese Entscheidungen nicht treffen.

Problem:

Wir sind seit einiger Zeit Opfer des Problems, das indiese SO-Frage. Nach einem Verbindungssturm oder einem langen Zeitraum, in dem neue Clients eine Verbindung herstellen und sehr häufig das AMQP-System verwenden, zeigt die RabbitMQ-Verwaltungs-API Hunderttausende von Verbindungen an, die sie als „aktiv“ auflistet, aber nicht mehr existiert. netstat, lsofund andere Diagnosen beweisen, dass die Sockets, die diesen Verbindungen entsprechen, auf den Clients nicht geöffnet sind; die Verwaltungs-API ist aus irgendeinem Grund einfach nicht in der Lage, die Einträge zu bereinigen. rabbitmqctl list_connectionszeigt manchmal einige der nicht vorhandenen Verbindungen als noch geöffnet an, aber es zeigt immer viel weniger an als die Verwaltungs-API, und ihre „Veraltungs“-Erkennung scheint besser zu sein als die der API und sie bereinigt die falschen Verbindungen schließlich aus ihrer Liste.

Wenn wir versuchen, eine dieser „falschen“ Verbindungen über die Web-Benutzeroberfläche zu löschen, reagiert die Seite nicht auf unser Drücken von „Löschen“ und die Verbindung bleibt in der Liste. Wenn wir versuchen, sie zu löschen, indem wir ein DELETE in der JSON-API senden, erhalten wir einen 500-Serverfehler, der angibt, dass die Verbindung nicht gültig ist und daher nicht gelöscht werden kann (genau wie in der oben verlinkten SO-Frage beschrieben).

Nach einer langen Ansammlung dieser nicht vorhandenen Verbindungsobjekte passieren drei schlimme Dinge (in keiner bestimmten Reihenfolge):

  • Der RabbitMQ-Server weist massive Speicherspitzen auf (die aus dem Nichts kommen; sie entsprechen nicht dem langsamen Verbindungsaufbau in der Verwaltungs-API, obwohl der Speicherverbrauch mit der Zeit langsam zunimmt). Dies führt häufig zu einem Absturz.
  • Die Verwaltungs-API reagiert nicht mehr auf Anforderungen (Zeitüberschreitung bei den API-Clients).
  • Der RabbitMQ-Server selbst beginnt sporadisch, Verbindungen von AMQP-Clients abzulehnen, die nichts mit HTTP/der Verwaltungs-API tun.

In Fällen, in denen dieses Problem unsere App zum Absturz bringt, müssen wir eines von zwei Dingen tun: * Den gesamten Messaging-Cluster neu starten, was schlecht ist, weil es zu vorübergehenden Ausfallzeiten kommt und schlecht, weil während dieses Vorgangs Nachrichten verloren gehen können. * Die Datenbank der Verwaltungs-API neu starten und löschen, was schlecht ist, weil wir die Verwaltungs-API nicht verwenden können, und noch schlimmer, weil es die Verwaltungs-API häufig so beschädigt, dass sie nicht wieder ordnungsgemäß gestartet werden kann, bis wir den gesamten Cluster wie im ersten Punkt neu starten.

Die meisten Leute, die von ähnlichen Problemen betroffen sind, lösen diese durch ein Upgrade auf RabbitMQ 3.*. Wir haben weder die Zeit, noch die Erlaubnis, noch die Ausfallzeitberechtigung für ein solches Projekt. Selbst angesichts der periodischen, mehrere Minuten dauernden Ausfälle, wenn wir den Cluster aufgrund dieses Problems neu starten, waren wir nicht berechtigt, ein Upgrade durchzuführen. Es ist eine rein politische Einschränkung, aber eine bedauerliche Realität.

Frage:

Da wir RabbitMQ in naher Zukunft nicht aktualisieren können und weiterhin die Verwaltungs-API verwenden müssen, stellt sich die Frage, wie wir das Problem der dauerhaften, veralteten Verbindungen lösen können, die zu Ausfällen des Messaging-Clusters führen.

Wir können neuen/anderen Client-Code entwickeln und Jobs auf den Messaging-Servern selbst ausführen, wir können ihn jedoch nicht rabbitmqctllokal oder über ssheinen der Client-Computer verwenden.

Was wir versucht haben:

  • Wir haben versucht, die AMQP-Clientbibliotheken zu wechseln, in der Hoffnung, dass ein besserer Client selbst aufräumt und keine veralteten Verbindungen hinterlässt, aber ohne Erfolg. Das Problem besteht weiterhin.
  • Wir haben versucht, mit den TCP-Einstellungen auf den RabbitMQ-Servern selbst zu spielen tcp_keepalive. exit_on_closeKeine Kombination dieser Werte löst das Problem.
  • Wir haben ein Skript erstellt, das alle Verbindungen durchläuft, die von der Verbindungsliste der JSON-API zurückgegeben werden, und für jede Verbindung, die länger geöffnet war, als es bei Verwendung nötig wäre, ein DELETE sendet. Alle derartigen Anfragen werden mit 500 Serverfehlern beantwortet, wie in der oben verlinkten SO-Frage beschrieben.

Antwort1

Sie starten alles regelmäßig neu.

Die andere Möglichkeit besteht darin, den Fix von 3.x auf Ihre aktuelle Version zurückzuportieren. Wenn Sie jedoch kein Upgrade durchführen dürfen, dürfen Sie dies wahrscheinlich auch nicht tun. Und es wird mit ziemlicher Sicherheit viel mehr Arbeit bedeuten als ein Upgrade, insbesondere wenn der RabbitMQ-Code erheblich überarbeitet wurde.

Bis Sie diePolitikJe nach Situation sind dies Ihre Optionen.

verwandte Informationen