Schnelles Lernen - Best Practices für RocketMQ

Empfohlene Vorgehensweise


1 Produzent

1.1 Hinweise zum Senden von Nachrichten

1 Verwendung von Tags

Eine Anwendung verwendet so oft wie möglich ein Thema, und der Nachrichtensubtyp kann durch Tags identifiziert werden. Tags können von der Anwendung frei festgelegt werden. Nur wenn der Hersteller die Tags beim Senden einer Nachricht festlegt, kann der Verbraucher Tags verwenden, um Nachrichten über den Broker zu filtern, wenn er die Nachricht abonniert: message.setTags ("TagA").

2 Verwendung von Schlüsseln

Der eindeutige Identifikationscode jeder Nachricht auf Serviceebene sollte auf das Schlüsselfeld eingestellt werden, um den Ort des Nachrichtenverlustproblems in Zukunft zu erleichtern. Der Server erstellt für jede Nachricht einen Index (Hash-Index), und die Anwendung kann den Inhalt der Nachricht nach Thema und Schlüssel abfragen und angeben, wer die Nachricht verwendet. Da es sich um einen Hash-Index handelt, stellen Sie bitte sicher, dass der Schlüssel so eindeutig wie möglich ist, um mögliche Hash-Kollisionen zu vermeiden.

   // 订单Id   
   String orderId = "20034568923546";   
   message.setKeys(orderId);   

3 Protokolldruck

Wenn die Nachricht erfolgreich gesendet wurde oder fehlgeschlagen ist, muss das Nachrichtenprotokoll gedruckt und die Felder SendResult und Key gedruckt werden. Solange die Methode zum Senden von Nachrichten keine Ausnahme auslöst, bedeutet dies, dass die Nachricht erfolgreich gesendet wurde. Es gibt mehrere Status für erfolgreiches Senden, die in sendResult definiert sind. Im Folgenden wird jeder Status beschrieben:

  • SEND_OK

Die Nachricht wurde erfolgreich gesendet. Es ist zu beachten, dass der Erfolg einer Nachricht nicht bedeutet, dass sie zuverlässig ist. Um sicherzustellen, dass keine Nachrichten verloren gehen, sollten Sie auch den synchronen Master-Server oder das synchrone Flashen aktivieren, nämlich SYNC_MASTER oder SYNC_FLUSH.

  • FLUSH_DISK_TIMEOUT

Die Nachricht wurde erfolgreich gesendet, aber das Leeren des Servers ist abgelaufen. Zu diesem Zeitpunkt ist die Nachricht in die Serverwarteschlange (Speicher) eingegangen, und die Nachricht geht nur verloren, wenn der Server ausfällt. Die Konfigurationsparameter für den Nachrichtenspeicher können den Flash-Modus und die Zeitdauer für das synchrone Flashen festlegen. Wenn der Broker-Server den Flash-Modus auf synchrones Flashen eingestellt hat, dh FlushDiskType = SYNC_FLUSH (Standard ist der asynchrone Flash-Modus), wenn der Broker-Server nicht synchron blinkt Wenn das Blinken innerhalb der Blinkzeit abgeschlossen ist (die Standardeinstellung ist 5s), kehrt es zu dieser Zeitüberschreitung zurück.

  • FLUSH_SLAVE_TIMEOUT

Die Nachricht wurde erfolgreich gesendet, aber der Server hat bei der Synchronisierung mit dem Slave eine Zeitüberschreitung festgestellt. Zu diesem Zeitpunkt ist die Nachricht in die Serverwarteschlange eingegangen, und die Nachricht geht nur verloren, wenn der Server ausfällt. Wenn die Rolle des Broker-Servers der synchrone Master ist, dh SYNC_MASTER (der Standard ist der asynchrone Master oder ASYNC_MASTER), und der Slave-Broker-Server die Synchronisierung mit dem Master-Server nicht innerhalb der Synchronisationsblinkzeit abschließt (Standard ist 5 Sekunden), kehrt er in diesen Zustand zurück. - Zeitüberschreitung bei der Datensynchronisierung mit dem Slave-Server.

  • SLAVE_NOT_AVAILABLE

Die Nachricht wurde erfolgreich gesendet, aber der Slave ist derzeit nicht verfügbar. Wenn die Rolle des Broker-Servers der synchrone Master ist, dh SYNC_MASTER (der Standard ist der asynchrone Master-Server, nämlich ASYNC_MASTER), aber kein Slave-Broker-Server konfiguriert ist, wird dieser Status wiederhergestellt. Es ist kein Slave-Server verfügbar.

1.2 Umgang mit Fehlern beim Senden von Nachrichten

Die Sendemethode von Producer selbst unterstützt interne Wiederholungsversuche, und die Wiederholungslogik lautet wie folgt:

  • Bis zu 2 Mehrfachversuche (2 Mal für die synchrone Übertragung und 0 Mal für die asynchrone Übertragung).
  • Wenn das Senden fehlschlägt, wenden Sie sich an den nächsten Broker. Die Gesamtzeit dieser Methode überschreitet nicht den von sendMsgTimeout festgelegten Wert, der standardmäßig 10 Sekunden beträgt.
  • Wenn das Senden einer Nachricht an den Broker selbst eine Timeout-Ausnahme generiert, wird dieser nicht erneut versucht.

Die obige Strategie garantiert bis zu einem gewissen Grad auch, dass die Nachricht erfolgreich gesendet werden kann. Wenn das Unternehmen hohe Anforderungen an die Zuverlässigkeit von Nachrichten stellt, wird empfohlen, dass die Anwendung eine entsprechende Wiederholungslogik hinzufügt: Wenn die Sendesynchronisierungsmethode beispielsweise nicht gesendet werden kann, versuchen Sie, die Nachricht in der Datenbank zu speichern, und der Hintergrundthread versucht es regelmäßig erneut, um sicherzustellen, dass die Nachricht beim Broker eintreffen muss.

Warum die obige DB-Wiederholungsmethode nicht in den MQ-Client integriert ist, sondern von der Anwendung selbst ausgeführt werden muss, hauptsächlich basierend auf den folgenden Überlegungen: Erstens ist der MQ-Client als zustandsloser Modus konzipiert, der für eine beliebige horizontale Erweiterung geeignet und korrekt ist Der Verbrauch von Maschinenressourcen beträgt nur CPU, Speicher und Netzwerk. Zweitens, wenn ein KV-Speichermodul in den MQ-Client integriert ist, können die Daten nur zuverlässiger auf einer synchronen Festplatte abgelegt werden, und der Leistungsaufwand für die synchrone Festplatte selbst ist relativ hoch, sodass normalerweise eine asynchrone Festplattenplatzierung verwendet wird und der Prozess zum Herunterfahren der Anwendung nicht durch den MQ-Betrieb beeinflusst wird. Bei der Kontrolle des Wartungspersonals kann es häufig vorkommen, dass kill -9 auf gewalttätige Weise heruntergefahren wird und Daten verloren gehen, weil sie nicht rechtzeitig platziert werden. Drittens ist die Zuverlässigkeit der Maschine, auf der sich der Produzent befindet, gering, im Allgemeinen eine virtuelle Maschine, die nicht zum Speichern wichtiger Daten geeignet ist. Zusammenfassend wird empfohlen, den Wiederholungsprozess von der Anwendung zu steuern.

1.3 Wählen Sie den zu sendenden Oneway

Normalerweise ist das Senden einer Nachricht ein solcher Prozess:

  • Der Client sendet eine Anfrage an den Server
  • Server-Verarbeitungsanforderung
  • Der Server gibt eine Antwort an den Client zurück

Daher ist die zeitaufwändige Zeit für das Senden einer Nachricht die Summe der oben genannten drei Schritte, und einige Szenarien erfordern sehr kurze Zeit, aber die Zuverlässigkeitsanforderungen sind nicht hoch, z. B. Protokollsammlungsanwendungen, die in Oneway-Form aufgerufen werden können Das Oneway-Formular sendet nur eine Anforderung, ohne auf eine Antwort zu warten, und die Sendeanforderung ist nur ein Overhead eines Betriebssystemaufrufs auf Client-Implementierungsebene, dh das Schreiben von Daten in den Socket-Puffer des Clients. Dieser Vorgang dauert normalerweise Mikrosekunden.

2 Verbraucher

2.1 Der Verbrauchsprozess ist idempotent

RocketMQ kann das Duplizieren von Nachrichten (genau einmal) nicht vermeiden. Wenn das Unternehmen also sehr empfindlich auf das Duplizieren von Verbrauch reagiert, muss es auf Unternehmensebene dedupliziert werden. Sie können relationale Datenbanken für die Deduplizierung verwenden. Zunächst müssen Sie den eindeutigen Schlüssel der Nachricht ermitteln, der msgId oder ein eindeutiges Identifikationsfeld im Nachrichteninhalt sein kann, z. B. die Bestell-ID. Stellen Sie vor dem Verbrauch fest, ob der eindeutige Schlüssel in der relationalen Datenbank vorhanden ist. Wenn es nicht existiert, einfügen und verbrauchen, andernfalls überspringen. (Der eigentliche Prozess sollte das Problem der Atomizität berücksichtigen, um festzustellen, ob ein Einfügeversuch vorliegt. Wenn der Primärschlüsselkonflikt gemeldet wird, schlägt die Einfügung fehl und wird direkt übersprungen.)

msgId muss eine global eindeutige Kennung sein. Bei der tatsächlichen Verwendung kann es jedoch Situationen geben, in denen dieselbe Nachricht zwei verschiedene msgIds enthält (aktive Neuübertragung durch den Verbraucher, Wiederholung durch den Client-Neuübertragungsmechanismus usw.). Diese Situation erfordert Machen Sie Geschäftsfelder wiederholten Verbrauch.

2.2 Möglichkeiten, mit langsamem Verbrauch umzugehen

1 Verbessern Sie die Verbrauchsparallelität

Das meiste Nachrichtenverbrauchsverhalten ist E / A-intensiv, dh es kann die Datenbank betreiben oder RPC aufrufen. Die Verbrauchsgeschwindigkeit dieser Art von Verbrauchsverhalten liegt im Durchsatz der Back-End-Datenbank oder des externen Systems. Durch Erhöhen der Verbrauchsparallelität kann die Gesamtsumme verbessert werden. Verbrauchsdurchsatz, aber der Grad der Parallelität steigt bis zu einem gewissen Grad an, wird aber abnehmen. Daher muss die Anwendung einen angemessenen Grad an Parallelität festlegen. Es gibt verschiedene Möglichkeiten, die Parallelität des Verbrauchs wie folgt zu ändern:

  • Erhöhen Sie unter derselben ConsumerGroup die Anzahl der Consumer-Instanzen, um den Grad der Parallelität zu erhöhen (beachten Sie, dass Consumer-Instanzen, die die Anzahl der Abonnementwarteschlangen überschreiten, ungültig sind). Sie können eine Maschine hinzufügen oder mehrere Prozesse auf einer vorhandenen Maschine starten.
  • Verbessern Sie die verbrauchsparallelen Threads eines einzelnen Verbrauchers, indem Sie die Parameter KonsumThreadMin und KonsumThreadMax ändern.

2 Chargenverbrauch

Wenn bestimmte Geschäftsprozesse den Stapelverbrauch unterstützen, kann der Verbrauchsdurchsatz erheblich verbessert werden. Beispielsweise dauert es bei Anwendungen zum Abzug von Bestellungen 1 Sekunde, um jeweils eine Bestellung zu bearbeiten, und es kann nur 2 Sekunden dauern, bis 10 Bestellungen gleichzeitig verarbeitet werden. Dies kann den Durchsatz des Verbrauchs erheblich erhöhen. Durch Festlegen des Parameters consumerMessageBatchMaxSize ist der Standardwert 1, dh es wird jeweils nur eine Nachricht verbraucht. Wenn beispielsweise N festgelegt ist, ist die Anzahl der verbrauchten Nachrichten jedes Mal kleiner oder gleich N.

3 Überspringen Sie nicht wichtige Nachrichten

Wenn eine Nachrichtenakkumulation auftritt, wenn die Verbrauchsgeschwindigkeit nicht mit der Sendegeschwindigkeit Schritt gehalten hat und das Unternehmen keine hohen Daten benötigt, können Sie unwichtige Nachrichten verwerfen. Wenn sich beispielsweise die Anzahl der Nachrichten in einer bestimmten Warteschlange auf mehr als 100.000 erhöht, versuchen Sie, einige oder alle Nachrichten zu verwerfen, damit Sie schnell mit der Geschwindigkeit des Sendens von Nachrichten Schritt halten können. Der Beispielcode lautet wie folgt:

    public ConsumeConcurrentlyStatus consumeMessage(
            List<MessageExt> msgs,
            ConsumeConcurrentlyContext context) {
    
    
        long offset = msgs.get(0).getQueueOffset();
        String maxOffset =
                msgs.get(0).getProperty(Message.PROPERTY_MAX_OFFSET);
        long diff = Long.parseLong(maxOffset) - offset;
        if (diff > 100000) {
    
    
            // TODO 消息堆积情况的特殊处理
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        }
        // TODO 正常消费过程
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }    

4 Optimieren Sie den Verbrauchsprozess jeder Nachricht

Der Verbrauchsprozess einer Nachricht ist beispielsweise wie folgt:

  • Abfrage von DB gemäß Meldung [Daten 1]
  • Abfrage von DB gemäß Meldung [Daten 2]
  • Komplexe Geschäftsberechnungen
  • Fügen Sie [Daten 3] in die Datenbank ein
  • Fügen Sie [Daten 4] in die Datenbank ein

Während des Verbrauchs dieser Nachricht gibt es 4 Interaktionen mit der Datenbank. Wenn sie jedes Mal mit 5 ms berechnet wird, beträgt die Gesamtzeit 20 ms. Angenommen, die Geschäftsberechnung dauert 5 ms, beträgt die Gesamtzeit 25 ms. Wenn Sie also viermal mit der Datenbank interagieren können Die Optimierung erfolgt zweimal, dann kann die Gesamtzeit auf 15 ms optimiert werden, dh die Gesamtleistung wird um 40% erhöht. Wenn die Anwendung empfindlich auf Latenz reagiert, kann DB daher auf SSD-Festplatten bereitgestellt werden. Im Vergleich zu SCSI-Festplatten ist die RT der ersteren viel kleiner.

2.3 Verbrauchsprotokoll

Wenn die Anzahl der Nachrichten gering ist, wird empfohlen, Nachrichten in der Verbrauchserfassungsmethode zu drucken, die für den Verbrauch zeitaufwändig ist, um die spätere Fehlerbehebung zu erleichtern.

   public ConsumeConcurrentlyStatus consumeMessage(
            List<MessageExt> msgs,
            ConsumeConcurrentlyContext context) {
    
    
        log.info("RECEIVE_MSG_BEGIN: " + msgs.toString());
        // TODO 正常消费过程
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }   

Wenn Sie jede Nachricht drucken und Zeit verbrauchen können, ist dies bei der Behebung von Online-Problemen wie langsamem Verbrauch bequemer.

2.4 Andere Verbrauchervorschläge

1 Über Verbraucher und Abonnements

Das erste, was zu beachten ist, ist, dass verschiedene Verbrauchergruppen einige Themen unabhängig voneinander konsumieren können und jede Verbrauchergruppe ihren eigenen Verbrauchsoffset hat. Stellen Sie sicher, dass die Abonnementinformationen jedes Verbrauchers in derselben Gruppe beibehalten werden Konsistent.

2 Über bestellte Nachrichten

Verbraucher sperren jede Nachrichtenwarteschlange, um sicherzustellen, dass sie einzeln verwendet werden. Dies führt zwar zu Leistungseinbußen, ist jedoch hilfreich, wenn Sie sich um die Reihenfolge der Nachrichten kümmern. Wir empfehlen, keine Ausnahmen auszulösen. Sie können stattdessen ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT zurückgeben.

3 Informationen zum gleichzeitigen Verbrauch

Wie der Name schon sagt, werden diese Nachrichten von Verbrauchern gleichzeitig verwendet. Es wird empfohlen, sie für eine gute Leistung zu verwenden. Es wird nicht empfohlen, Ausnahmen auszulösen. Sie können stattdessen ConsumeConcurrentlyStatus.RECONSUME_LATER zurückgeben.

4 Informationen zum Verbrauchsstatus

Für Listener mit gleichzeitigem Verbrauch können Sie RECONSUME_LATER zurückgeben, um den Verbraucher darüber zu informieren, dass die Nachricht jetzt nicht konsumiert werden kann, und hoffen, dass sie später wieder konsumiert werden kann. Anschließend können Sie weiterhin andere Nachrichten verwenden. Bei einem Listener für bestellte Nachrichten können Sie die Nachricht nicht überspringen, da Sie sich um ihre Reihenfolge kümmern. Sie können jedoch SUSPEND_CURRENT_QUEUE_A_MOMENT zurückgeben, um den Verbraucher anzuweisen, eine Weile zu warten.

5 Informationen zum Blockieren

Es wird nicht empfohlen, den Listener zu blockieren, da dies den Thread-Pool blockiert und möglicherweise den Consumer-Prozess beendet

6 Informationen zum Festlegen der Anzahl der Threads

Verbraucher verwenden ThreadPoolExecutor, um Nachrichten intern zu konsumieren. Sie können sie also ändern, indem Sie setConsumeThreadMin oder setConsumeThreadMax festlegen.

7 Informationen zu Verbrauchsstellen

Wenn Sie eine neue Verbrauchergruppe erstellen, müssen Sie entscheiden, ob Sie bereits in Broker vorhandene Verlaufsnachrichten verwenden möchten. CONSUME_FROM_LAST_OFFSET ignoriert Verlaufsnachrichten und verwendet anschließend generierte Nachrichten. CONSUME_FROM_FIRST_OFFSET verbraucht alle im Broker vorhandenen Informationen. Sie können auch CONSUME_FROM_TIMESTAMP verwenden, um Nachrichten zu verwenden, die nach dem angegebenen Zeitstempel generiert wurden.

3 Broker

3.1 Maklerrolle

Broker-Rollen sind in ASYNC_MASTER (asynchroner Master), SYNC_MASTER (synchroner Master) und SLAVE (Slave) unterteilt. Wenn die Zuverlässigkeit der Nachricht strenger ist, können Sie die Bereitstellungsmethode SYNC_MASTER plus SLAVE verwenden. Wenn die Anforderungen an die Nachrichtenzuverlässigkeit nicht hoch sind, kann die Bereitstellungsmethode von ASYNC_MASTER plus SLAVE verwendet werden. Wenn dies nur zum Testen zweckmäßig ist, können Sie nur ASYNC_MASTER oder SYNC_MASTER bereitstellen.

3.2 FlushDiskType

SYNC_FLUSH (synchrone Aktualisierung) verliert im Vergleich zu ASYNC_FLUSH (asynchrone Verarbeitung) viel an Leistung, ist jedoch auch zuverlässiger, sodass Sie einen Kompromiss basierend auf dem tatsächlichen Geschäftsszenario eingehen müssen.

3.3 Brokerkonfiguration

Parametername Standardeinstellungen Beschreibung
listenPort 10911 Der Überwachungsport, der Clientverbindungen akzeptiert
namesrvAddr Null nameServer Adresse
BrokerIP1 InetAddress der Netzwerkkarte IP wird derzeit vom Broker überwacht
BrokerIP2 Gleich wie BrokerIP1 Wenn es einen Master-Slave-Broker gibt und das BrokerIP2-Attribut auf dem Broker-Master-Knoten konfiguriert ist, stellt der Broker-Slave-Knoten eine Verbindung zu dem BrokerIP2 her, das vom Master-Knoten für die Synchronisation konfiguriert wurde
BrokerName Null der Name des Maklers
BrokerClusterName DefaultCluster Der Name des Clusers, zu dem dieser Broker gehört
BrokerId 0 Broker-ID, 0 bedeutet Master, andere positive Ganzzahlen bedeuten Slave
storePathCommitLog $ HOME / store / commitlog / Pfad zum Speichern des Festschreibungsprotokolls
storePathConsumerQueue $ HOME / store / verbrauchen / Der Pfad zum Speichern der Verbrauchswarteschlange
mappedFileSizeCommitLog 1024 * 1024 * 1024 (1G) Zuordnen der Dateigröße des Festschreibungsprotokolls
deleteWhen 04 Zu welcher Tageszeit löschen Sie das Festschreibungsprotokoll, das die Aufbewahrungszeit für Dateien überschritten hat
fileReservedTime 72 Aufbewahrungszeit für Dateien in Stunden
BrokerRole ASYNC_MASTER SYNC_MASTER / ASYNC_MASTER / SLAVE
flushDiskType ASYNC_FLUSH SYNC_FLUSH / ASYNC_FLUSH Der Broker im SYNC_FLUSH-Modus garantiert, dass die Nachricht geleert wird, bevor er die Bestätigung vom Hersteller erhält. Der Broker im ASYNC_FLUSH-Modus verwendet den Modus zum Flashen einer Gruppe von Nachrichten, um eine bessere Leistung zu erzielen.

4 NameServer

In RocketMQ sind Nameserver für eine einfache Routingverwaltung konzipiert. Zu seinen Aufgaben gehören:

  • Broker registrieren regelmäßig Routing-Daten bei jedem Nameserver.
  • Der Nameserver bietet die neuesten Routing-Informationen für Clients, einschließlich Hersteller, Verbraucher und Befehlszeilenclients. Wenn Sie

5 Client-Konfiguration

Im Vergleich zum Broker-Cluster von RocketMQ sind sowohl Hersteller als auch Verbraucher Kunden. Dieser Abschnitt beschreibt hauptsächlich die Konfiguration des öffentlichen Verhaltens von Produzenten und Verbrauchern.

5.1 Client-Adressierungsmodus

RocketMQ kann den Client veranlassen, den Nameserver zu finden und dann den Broker über den Nameserver zu finden. Es gibt mehrere Konfigurationsmethoden, wie unten gezeigt, die Priorität ist von hoch nach niedrig und die hohe Priorität überschreibt die niedrige Priorität.

  • Geben Sie die Nameserver-Adresse im Code an und trennen Sie mehrere Namesrv-Adressen durch Semikolons
producer.setNamesrvAddr("192.168.0.1:9876;192.168.0.2:9876");  

consumer.setNamesrvAddr("192.168.0.1:9876;192.168.0.2:9876");
  • Geben Sie die Adresse des Nameservers in den Java-Startparametern an
-Drocketmq.namesrv.addr=192.168.0.1:9876;192.168.0.2:9876  
  • Die Umgebungsvariable gibt die Adresse des Nameservers an
export   NAMESRV_ADDR=192.168.0.1:9876;192.168.0.2:9876   
  • Adressierung des statischen HTTP-Servers (Standard)

Nach dem Start des Clients wird regelmäßig auf einen statischen HTTP-Server zugegriffen. Die Adresse lautet wie folgt: http://jmenv.tbsite.net:8080/rocketmq/nsaddr . Der Rückgabeinhalt dieser URL lautet wie folgt:

192.168.0.1:9876;192.168.0.2:9876   

Der Client besucht diesen HTTP-Server standardmäßig alle 2 Minuten und aktualisiert die lokale Nameserver-Adresse. Die URL wurde im Code fest codiert. Sie können den Server, auf den zugegriffen werden soll, ändern, indem Sie die Datei / etc / hosts ändern. Fügen Sie beispielsweise / etc / hosts die folgende Konfiguration hinzu:

10.232.22.67    jmenv.taobao.net   

Es wird empfohlen, die Adressierungsmethode für den statischen HTTP-Server zu verwenden. Der Vorteil besteht darin, dass die Clientbereitstellung einfach ist und der Name Server-Cluster im laufenden Betrieb aktualisiert werden kann.

5.2 Client-Konfiguration

DefaultMQProducer, TransactionMQProducer, DefaultMQPushConsumer und DefaultMQPullConsumer erben alle von der ClientConfig-Klasse, einer öffentlichen Konfigurationsklasse für den Client. Die Konfiguration des Clients erfolgt in Form von get und set. Jeder Parameter kann mit spring oder im Code konfiguriert werden. Beispielsweise kann der Parameter namesrvAddr wie folgt konfiguriert werden: Producer.setNamesrvAddr ("192.168.0.1:9876"), andere Parameter Das gleiche gilt.

1 Öffentliche Konfiguration des Clients

Parametername Standardeinstellungen Beschreibung
namesrvAddr Adressliste des Nameservers, mehrere NameServer-Adressen werden durch Semikolons getrennt
clientIP Lokale IP Die lokale IP-Adresse des Clients, einige Computer erkennen die IP-Adresse des Clients nicht, sie muss im Code zwangsweise angegeben werden
Instanzname STANDARD Clientinstanzname, mehrere vom Client erstellte Producer und Consumer teilen sich tatsächlich eine interne Instanz (diese Instanz enthält Netzwerkverbindungen, Thread-Ressourcen usw.)
clientCallbackExecutorThreads 4 Anzahl der asynchronen Rückruf-Threads in der Kommunikationsschicht
pollNameServerInteval 30000 Abfrageintervall des Nameservers in Millisekunden
heartbeatBrokerInterval 30000 Das Intervall für das Senden von Herzschlägen an Broker in Millisekunden
persistConsumerOffsetInterval 5000 Anhaltendes Fortschrittsintervall für den Verbraucherverbrauch in Millisekunden

2 Herstellerkonfiguration

Parametername Standardeinstellungen Beschreibung
Produzentengruppe DEFAULT_PRODUCER Name der Produzentengruppe Wenn mehrere Produzenten zu einer Anwendung gehören und dieselbe Nachricht senden, sollten sie in derselben Gruppe gruppiert werden
createTopicKey TBW102 Beim Senden einer Nachricht wird automatisch ein Thema erstellt, das auf dem Server nicht vorhanden ist, und es muss ein Schlüssel angegeben werden. Mit dem Schlüssel kann die Standardroute des Themas konfiguriert werden, an das die Nachricht gesendet wird.
defaultTopicQueueNums 4 Die Anzahl der Warteschlangen, die standardmäßig beim Senden von Nachrichten und beim automatischen Erstellen von Themen erstellt werden, bei denen der Server nicht vorhanden ist
sendMsgTimeout 10000 Zeitüberschreitung beim Senden einer Nachricht in Millisekunden
compressMsgBodyOverHowmuch 4096 Der Nachrichtentext überschreitet die Größe zum Starten der Komprimierung (der Verbraucher dekomprimiert die Nachricht automatisch, wenn er sie empfängt) in Byte
retryAnotherBrokerWhenNotStoreOK FALSCH Wenn das Senden einer Nachricht sendResult zurückgibt, sendStatus! = SEND_OK, ob das Senden erneut versucht werden soll
retryTimesWhenSendFailed 2 Wenn die Nachricht nicht gesendet werden kann, die maximale Anzahl von Wiederholungsversuchen, funktioniert dieser Parameter nur im synchronen Sendemodus
maxMessageSize 4 MB Die vom Client begrenzte Nachrichtengröße überschreitet den Fehlerbericht, und der Server begrenzt ihn ebenfalls. Daher muss er in Verbindung mit dem Server verwendet werden.
transactionCheckListener Listener für die Überprüfung der Transaktionsnachricht zurück, wenn eine Transaktionsnachricht gesendet wird, muss diese festgelegt werden
checkThreadPoolMinSize 1 Die Mindestanzahl von Threads im Thread-Pool, wenn der Broker den Producer-Transaktionsstatus zurückprüft
checkThreadPoolMaxSize 1 Die maximale Anzahl von Threads im Thread-Pool, wenn der Broker den Producer-Transaktionsstatus überprüft
checkRequestHoldMax 2000 Broker回查Producer事务状态时,Producer本地缓冲请求队列大小
RPCHook null 该参数是在Producer创建时传入的,包含消息发送前的预处理和消息响应后的处理两个接口,用户可以在第一个接口中做一些安全控制或者其他操作。

3 PushConsumer配置

参数名 默认值 说明
consumerGroup DEFAULT_CONSUMER Consumer组名,多个Consumer如果属于一个应用,订阅同样的消息,且消费逻辑一致,则应该将它们归为同一组
messageModel CLUSTERING 消费模型支持集群消费和广播消费两种
consumeFromWhere CONSUME_FROM_LAST_OFFSET Consumer启动后,默认从上次消费的位置开始消费,这包含两种情况:一种是上次消费的位置未过期,则消费从上次中止的位置进行;一种是上次消费位置已经过期,则从当前队列第一条消息开始消费
consumeTimestamp 半个小时前 只有当consumeFromWhere值为CONSUME_FROM_TIMESTAMP时才起作用。
allocateMessageQueueStrategy AllocateMessageQueueAveragely Rebalance算法实现策略
subscription 订阅关系
messageListener 消息监听器
offsetStore 消费进度存储
consumeThreadMin 10 消费线程池最小线程数
consumeThreadMax 20 消费线程池最大线程数
consumeConcurrentlyMaxSpan 2000 单队列并行消费允许的最大跨度
pullThresholdForQueue 1000 拉消息本地队列缓存消息最大数
pullInterval 0 拉消息间隔,由于是长轮询,所以为0,但是如果应用为了流控,也可以设置大于0的值,单位毫秒
consumeMessageBatchMaxSize 1 批量消费,一次消费多少条消息
pullBatchSize 32 批量拉消息,一次最多拉多少条

4 PullConsumer配置

参数名 默认值 说明
consumerGroup DEFAULT_CONSUMER Consumer组名,多个Consumer如果属于一个应用,订阅同样的消息,且消费逻辑一致,则应该将它们归为同一组
brokerSuspendMaxTimeMillis 20000 长轮询,Consumer拉消息请求在Broker挂起最长时间,单位毫秒
consumerTimeoutMillisWhenSuspend 30000 长轮询,Consumer拉消息请求在Broker挂起超过指定时间,客户端认为超时,单位毫秒
consumerPullTimeoutMillis 10000 非长轮询,拉消息超时时间,单位毫秒
messageModel BROADCASTING 消息支持两种模式:集群消费和广播消费
messageQueueListener 监听队列变化
offsetStore 消费进度存储
registerTopics 注册的topic集合
allocateMessageQueueStrategy AllocateMessageQueueAveragely Rebalance算法实现策略

5 Message数据结构

字段名 默认值 说明
Topic null 必填,消息所属topic的名称
Body null 必填,消息体
Tags null 选填,消息标签,方便服务器过滤使用。目前只支持每个消息设置一个tag
Keys null 选填,代表这条消息的业务关键词,服务器会根据keys创建哈希索引,设置后,可以在Console系统根据Topic、Keys来查询消息,由于是哈希索引,请尽可能保证key唯一,例如订单号,商品Id等。
Flag 0 选填,完全由应用来设置,RocketMQ不做干预
DelayTimeLevel 0 选填,消息延时级别,0表示不延时,大于0会延时特定的时间才会被消费
WaitStoreMsgOK TRUE 选填,表示消息是否在服务器落盘后才返回应答。

6 系统配置

本小节主要介绍系统(JVM/OS)相关的配置。

6.1 JVM选项

​ 推荐使用最新发布的JDK 1.8版本。通过设置相同的Xms和Xmx值来防止JVM调整堆大小以获得更好的性能。简单的JVM配置如下所示:

​ ​-server -Xms8g -Xmx8g -Xmn4g ​


如果您不关心RocketMQ Broker的启动时间,还有一种更好的选择,就是通过“预触摸”Java堆以确保在JVM初始化期间每个页面都将被分配。那些不关心启动时间的人可以启用它:
​ -XX:+AlwaysPreTouch
禁用偏置锁定可能会减少JVM暂停,
​ -XX:-UseBiasedLocking
至于垃圾回收,建议使用带JDK 1.8的G1收集器。

-XX:+UseG1GC -XX:G1HeapRegionSize=16m   
-XX:G1ReservePercent=25 
-XX:InitiatingHeapOccupancyPercent=30

​ 这些GC选项看起来有点激进,但事实证明它在我们的生产环境中具有良好的性能。另外不要把-XX:MaxGCPauseMillis的值设置太小,否则JVM将使用一个小的年轻代来实现这个目标,这将导致非常频繁的minor GC,所以建议使用rolling GC日志文件:

-XX:+UseGCLogFileRotation   
-XX:NumberOfGCLogFiles=5 
-XX:GCLogFileSize=30m

如果写入GC文件会增加代理的延迟,可以考虑将GC日志文件重定向到内存文件系统:

-Xloggc:/dev/shm/mq_gc_%p.log123   

6.2 Linux内核参数

​ os.sh脚本在bin文件夹中列出了许多内核参数,可以进行微小的更改然后用于生产用途。下面的参数需要注意,更多细节请参考/proc/sys/vm/*的文档

  • vm.extra_free_kbytes,告诉VM在后台回收(kswapd)启动的阈值与直接回收(通过分配进程)的阈值之间保留额外的可用内存。RocketMQ使用此参数来避免内存分配中的长延迟。(与具体内核版本相关)
  • vm.min_free_kbytes,如果将其设置为低于1024KB,将会巧妙的将系统破坏,并且系统在高负载下容易出现死锁。
  • vm.max_map_count,限制一个进程可能具有的最大内存映射区域数。RocketMQ将使用mmap加载CommitLog和ConsumeQueue,因此建议将为此参数设置较大的值。(agressiveness --> aggressiveness)
  • vm.swappiness,定义内核交换内存页面的积极程度。较高的值会增加攻击性,较低的值会减少交换量。建议将值设置为10来避免交换延迟。
  • File descriptor limits,RocketMQ需要为文件(CommitLog和ConsumeQueue)和网络连接打开文件描述符。我们建议设置文件描述符的值为655350。
  • Disk scheduler,RocketMQ建议使用I/O截止时间调度器,它试图为请求提供有保证的延迟。

Ich denke du magst

Origin blog.csdn.net/weixin_42528266/article/details/108625004
Empfohlen
Rangfolge