Tüm Ürünler
Search
Belge Merkezi

ApsaraMQ for RocketMQ:Send and receive ordered messages

Son Güncelleme:Oct 04, 2026

Sıralı mesajlar kesin ilk giren ilk çıkar (FIFO) düzeninde iletilir ve tüketilir. Bu konu, Apache RocketMQ Java SDK kullanarak TCP üzerinden sıralı mesaj göndermek ve almak için Java örnek kodları sunar.

Sıralı mesajların çalışma mantığı

Sıralı mesajlar parça anahtarı ile bölümlere ayrılır. Her parça anahtarı özel bir parçaya eşlenir ve bu parça içindeki mesajlar gönderildikleri sırayla iletilir.

Bu davranışı yöneten üç kural şunlardır:

  1. Parça bazında sıralama -- Aynı parça anahtarını paylaşan mesajlar her zaman FIFO düzeninde iletilir.

  2. Parçalar arasında sıralama yok -- Farklı parça anahtarlarına sahip mesajlar birbirlerine göre herhangi bir sırada gelebilir.

  3. Parça anahtarı zorunludur -- Her sıralı mesaj bir parça anahtarı içermelidir. Bu anahtar, aramalar için kullanılan genel mesaj anahtarından bağımsızdır.

İş gereksinimlerinize uygun sıralama modeli oluşturmak için parça anahtarlarını kullanın. Örneğin, parça anahtarını sipariş kimliği olarak ayarlayarak aynı siparişe ait tüm mesajların sırayla işlenmesini, farklı siparişlere ait mesajların ise paralel olarak işlenmesini sağlayabilirsiniz.

Sıralama semantiği ve kısıtlamaları hakkında daha fazla bilgi için bkz. Sıralı mesajlar.

Ön koşullar

Başlamadan önce aşağıdakilere sahip olduğunuzdan emin olun:

Not

ApsaraMQ for RocketMQ konusunda yeniyseniz, mesaj gönderip almadan önce çalışan bir proje kurmak için demo projesi ile başlayın.

Sıralı mesaj gönderme

Sıralama garantisi

Broker, gönderenin mesajları göndermek için tek bir üretici veya iş parçacığı kullandığı sıraya göre mesaj sırasını belirler. Birden çok üretici veya iş parçacığı eş zamanlı olarak mesaj gönderirse broker bunları varış zamanına göre sıralar; bu sıra, amaçlanan iş sırasından farklı olabilir.

Örnek kod

Aşağıdaki yer tutucuları gerçek değerlerinizle değiştirin:

Yer Tutucu Açıklama Örnek
<your-group-id> ApsaraMQ for RocketMQ konsolunda oluşturulan Grup Kimliği GID_order_group
<your-access-key> Kimlik doğrulama için AccessKey ID LTAI5tXxx
<your-secret-key> Kimlik doğrulama için AccessKey secret xXxXxXx
<your-tcp-endpoint> Instance Details sayfasındaki TCP Endpoint bölümünden alınan TCP uç noktası http://MQ_INST_xxx.mq-internet-access.mq-internet.aliyuncs.com:80

Tam kod için bkz. ApsaraMQ for RocketMQ kod deposu.

package com.aliyun.openservices.ons.example.order;

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.aliyun.openservices.ons.api.SendResult;
import com.aliyun.openservices.ons.api.order.OrderProducer;

import java.util.Date;
import java.util.Properties;

public class ProducerClient {

    public static void main(String[] args) {
        Properties properties = new Properties();
        // Group ID created in the ApsaraMQ for RocketMQ console.
        properties.put(PropertyKeyConst.GROUP_ID, "<your-group-id>");
        // AccessKey ID for authentication.
        properties.put(PropertyKeyConst.AccessKey, "<your-access-key>");
        // AccessKey secret for authentication.
        properties.put(PropertyKeyConst.SecretKey, "<your-secret-key>");
        // TCP endpoint from the Instance Details page in the ApsaraMQ for RocketMQ console.
        properties.put(PropertyKeyConst.NAMESRV_ADDR, "<your-tcp-endpoint>");

        OrderProducer producer = ONSFactory.createOrderProducer(properties);
        // Call start() once before sending any messages.
        producer.start();

        for (int i = 0; i < 1000; i++) {
            String orderId = "biz_" + i % 10;
            Message msg = new Message(
                    // Topic for ordered messages.
                    "Order_global_topic",
                    // Tag for filtering on the broker side.
                    "TagA",
                    // Message body in binary format.
                    // Producer and consumer must agree on serialization and deserialization.
                    "send order global msg".getBytes()
            );
            // Message key -- a business identifier, ideally globally unique.
            // Use this key to look up the message in the ApsaraMQ for RocketMQ console.
            msg.setKey(orderId);

            // Sharding key -- determines the partition for ordered delivery.
            // Messages with the same sharding key are delivered in FIFO order.
            String shardingKey = String.valueOf(orderId);
            try {
                SendResult sendResult = producer.send(msg, shardingKey);
                if (sendResult != null) {
                    System.out.println(new Date() + " Send mq message success. Topic is:" + msg.getTopic() + " msgId is: " + sendResult.getMessageId());
                }
            } catch (Exception e) {
                // Handle failure: retry or persist the message for later resend.
                System.out.println(new Date() + " Send mq message failed. Topic is:" + msg.getTopic());
                e.printStackTrace();
            }
        }
        // Shut down the producer before exiting.
        // Skip this if the producer sends messages frequently.
        producer.shutdown();
    }

}

Sıralı mesaj alma

Yeniden deneme davranışı

Bir sıralı mesaj tüketilemediğinde broker, mevcut mesaj başarıyla işlenene veya maksimum yeniden deneme sayısına ulaşana kadar aynı parçadaki sonraki tüm mesajları engeller. Bu engelleme davranışı FIFO sıralamasını korur ancak parçadaki diğer mesajların işlenmesini geciktirebilir.

Yeniden deneme davranışını iki parametre kontrol eder:

Parametre Açıklama Geçerli değerler
SuspendTimeMillis Başarısız olan bir sıralı mesaj için yeniden denemeler arasındaki bekleme süresi (milisaniye) 10 -- 30.000
MaxReconsumeTimes Mesaj atlanmadan önceki maksimum yeniden deneme sayısı Tamsayı (örneğin, 20)

Bu değerleri işleme gecikmelerine karşı toleransınıza göre ayarlayın. Daha düşük bir SuspendTimeMillis değeri daha hızlı yeniden deneme yapar ancak broker yükünü artırır. Daha düşük bir MaxReconsumeTimes değeri parçanın engellemesini daha erken kaldırır ancak daha fazla deneme ile başarılı olabilecek mesajların atlanmasına neden olabilir.

Örnek kod

Aşağıdaki örnek kod, üretici örneği ile aynı yer tutucuları kullanır. Kodu çalıştırmadan önce bunları gerçek değerlerinizle değiştirin.

package com.aliyun.openservices.ons.example.order;

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.aliyun.openservices.ons.api.order.ConsumeOrderContext;
import com.aliyun.openservices.ons.api.order.MessageOrderListener;
import com.aliyun.openservices.ons.api.order.OrderAction;
import com.aliyun.openservices.ons.api.order.OrderConsumer;

import java.util.Properties;

public class ConsumerClient {

    public static void main(String[] args) {
        Properties properties = new Properties();
        // Consumer group ID created in the ApsaraMQ for RocketMQ console.
        properties.put(PropertyKeyConst.GROUP_ID, "<your-group-id>");
        // AccessKey ID for authentication.
        properties.put(PropertyKeyConst.AccessKey, "<your-access-key>");
        // AccessKey secret for authentication.
        properties.put(PropertyKeyConst.SecretKey, "<your-secret-key>");
        // TCP endpoint from the Instance Details page in the ApsaraMQ for RocketMQ console.
        properties.put(PropertyKeyConst.NAMESRV_ADDR, "<your-tcp-endpoint>");
        // Wait time (ms) before retrying a failed ordered message. Valid values: 10 to 30,000.
        properties.put(PropertyKeyConst.SuspendTimeMillis, "100");
        // Maximum retry attempts for a failed message.
        properties.put(PropertyKeyConst.MaxReconsumeTimes, "20");

        OrderConsumer consumer = ONSFactory.createOrderedConsumer(properties);

        consumer.subscribe(
                // Topic to subscribe to.
                "Order_global_topic",
                // Tag filter expression:
                //   "*"                       -- subscribe to all tags
                //   "TagA || TagB || TagC"     -- subscribe to TagA, TagB, or TagC only
                "*",
                new MessageOrderListener() {
                    /**
                     * Return OrderAction.Success after processing the message.
                     * Return OrderAction.Suspend if processing fails or throws
                     * an exception -- the broker will retry after SuspendTimeMillis.
                     */
                    @Override
                    public OrderAction consume(Message message, ConsumeOrderContext context) {
                        System.out.println(message);
                        return OrderAction.Success;
                    }
                });

        // Call start() once to begin consuming.
        consumer.start();
    }
}

Sonraki adımlar