Blog

MongoDB-Warteschlangen — Warum und wie wir sie bei FloQast verwenden

Joseph Vu
April 5, 2021

Plattformteams variieren von Unternehmen zu Unternehmen. Bei FloQast besteht die Mission des Plattformteams darin, Produktteams in die Lage zu versetzen, innovative Produkte schneller und eigenständig zu liefern, indem das Entwicklererlebnis verbessert und die Abhängigkeiten zwischen den Teams verringert werden. In diesem Artikel werden wir erörtern, wie das Plattformteam von FloQast MongoDB um die Effizienz der Entwickler zu erhöhen.

Das Problem

Da FloQast weiter wächst, stellen wir immer mehr Entwicklungsteams zusammen, um unseren Kunden mehr Funktionen bieten zu können. Ein häufiger Lösung in jedem dieser Teams ist die Verwendung einer Nachrichtenwarteschlange. Traditionell haben wir gewählt AWS SQS als unser Nachrichtenwarteschlangenservice.Ein typischer Entwickler-Workflow würde wie folgt aussehen:

  • Eine Warteschlange erstellen
  • Aktualisieren Sie den Anwendungscode, um Nachrichten in die Warteschlange zu übertragen
  • Aktualisieren Sie die Verbraucher so, dass sie aus der Warteschlange konsumieren:
    • Aktualisieren Sie den vorhandenen monolithischen Worker-Service, um ihn aus der Warteschlange zu nutzen, oder
    • Erstellen Sie einen neuen Dienst und implementieren Sie SQS erneut
  • Lokale Setup-Skripte aktualisieren

Das hat gut funktioniert, als wir noch ein relativ kleines Team waren, aber das hat jetzt zu einigen Problemen in Bezug auf die Wartbarkeit und Doppelarbeit geführt. Wir mussten zahlreiche Warteschlangen für jede unserer Umgebungen sowie individuelle Warteschlangen für jeden Entwickler erstellen, sodass lokale Setup-Skripte und Dokumentation verwaltet werden mussten (was in den meisten Fällen ein nachträglicher Einfall ist). Darüber hinaus waren wir dann gezwungen, entweder weiterhin Updates an einem bestehenden monolithischen Service vorzunehmen oder SQS in einem neuen Service erneut zu implementieren.

Unsere Lösung

Wir haben uns entschieden, einige der Probleme zu lösen, indem wir die Warteschlange vereinfacht und abstrahiert haben. Entwickler sollten sich keine Gedanken über die Warteschlangenimplementierung machen müssen. Sie müssen nur wissen, wie Nachrichten zu einer Warteschlange hinzugefügt werden und wie Nachrichten aus einer Warteschlange verarbeitet werden. Obwohl wir AWS SQS bereits in gewissem Umfang verwendet haben, haben wir uns stattdessen dafür entschieden, MongoDB als Nachrichtenwarteschlange zu verwenden. Es gab mehrere Gründe, warum wir uns für diesen Ansatz entschieden haben. Die erste war, damit wir vermeiden konnten, für jede Umgebung eine separate Warteschlange (wir haben zusätzlich zu QA und Produktion eine Umgebung pro Team) sowie eine separate Warteschlange pro Entwickler verwalten zu müssen (ich weiß, verrückt!). Der Grund, warum wir für jeden Entwickler separate Warteschlangen haben, ist, dass wir vermeiden können, die Nachrichten der anderen zu konsumieren. Die zweite war, dass MongoDB bereits in allen unseren bestehenden Systemen verfügbar war. Dadurch wurde die Anlaufzeit erheblich reduziert, da sich die Entwickler nicht mehr mit SQS vertraut machen und den Infrastrukturcode ändern mussten (wir verwenden Terraform), oder pflegen Sie lokale Setup-Skripte.

Wie es in der Entwicklung aussieht

Auf dem Weg zu einer Microservice-basierten Architektur haben wir uns für AWS Lambda als unsere Technologie ideal sowohl für die Verarbeitung von Nachrichten aus einer Warteschlange als auch für die Möglichkeit, Nachrichten an Warteschlangen weiterzuleiten. Dadurch entfällt die Notwendigkeit, bestehende Dienste zugunsten eines separat einsetzbaren Lambdas zu modifizieren. Wir haben bereitgestellte Abstraktionen über Lambda Layers Dadurch können Entwickler problemlos Nachrichten zu jeder Warteschlange hinzufügen. Der typische Entwickler-Workflow sieht jetzt so aus:

  • Aktualisieren Sie den Anwendungscode, um Nachrichten in die Warteschlange zu übertragen
  • Schreiben Sie Lambda-Code, der aus der Warteschlange konsumiert werden soll

Das Hinzufügen von Nachrichten zur Warteschlange sieht so aus:

// Available via a lambda layer
const { addMessage } = require('floqast-queue');

exports.handler = async (event, context) => {
    const queueName = 'test-queue';
    const payload = {
        message: 'Hello World!'
    };
    const messageId = await addMessage({
        queueName,
        payload
    });
    console.log(`Added message: ${messageId} to queue: ${queueName}`);
};

Lambda-Code, der ausgeführt wird, wenn eine Nachricht zur Warteschlange hinzugefügt wird:

exports.handler = async (event) => {
    const {
        queueName,
        message: {
            id,
            payload
        }
    } = event;

    console.log(`Received message: ${id} from queue: ${queueName} with payload: ${JSON.stringify(payload)}`);
};

Schließlich haben wir, um die Abfrage und Verarbeitung von Nachrichten zu erleichtern, einen Dienst eingerichtet, der Die atomare findAndModify-Methode von MongoDB um das erste Element in der Warteschlange (FIFO) abzurufen und ein Lambda aufzurufen, das auf einer Reihe von Regeln basiert, die vom Entwickler bereitgestellt werden. Im Rahmen der Lambda-Bereitstellung wurde ein regeln.json Die Datei muss sowohl den Namen des Lambda als auch den Namen der Warteschlange angeben, damit sie zur Bereitstellungszeit mit diesem Dienst synchronisiert werden können. Das regeln.json wird so aussehen:

{
    "rules": [
        {
            "queueName": "test-queue",
            "lambdaName": "test-lambda"
        }
    ]
}

Es gibt zusätzliche Eigenschaften wie die Sichtbarkeits-Timeout, tote Warteschlange, maximale Parallelität oder max. Wiederholungen das kann auch über das konfiguriert werden regeln.json sind aber außerhalb des Geltungsbereichs dieses Artikels.

Fazit

Wir sind uns der Vorteile eines dedizierten Messaging-Systems nicht bewusst. Die Wartbarkeit und einfache Implementierung machten MongoDB jedoch zu einer guten Wahl für uns zu diesem Zeitpunkt. Wir werden unsere Systeme weiterhin überwachen, um festzustellen, ob MongoDB zu einem Engpass wird. Darüber hinaus können wir aufgrund der Art und Weise, wie wir die Warteschlangenimplementierung abstrahiert haben, für den Fall, dass dies zu einem Problem wird, MongoDB problemlos gegen ein dediziertes Messaging-System austauschen, ohne jemals den vorhandenen Lambda-Code eines Entwicklers ändern zu müssen.