Tüm Ürünler
Search
Belge Merkezi

ApsaraMQ for RocketMQ:Send and receive ordered messages by using the HTTP client SDK for Node.js

Son Güncelleme:Oct 04, 2026

ApsaraMQ for RocketMQ'daki sıralı mesajlar, katı ilk giren ilk çıkar (FIFO) teslimatı garanti eder. İş mantığınızda işleme sırasının önemli olduğu durumlarda sıralı mesajları kullanın; örneğin, belirli bir fiyata verilen en erken teklifin kazanması gereken işlem eşleştirme veya ekleme, güncelleme ve silme işlemlerinin sırayla yeniden oynatılması gereken veritabanı değişikliği senkronizasyonu gibi senaryolarda bu yaklaşım uygundur.

Bu konu, Node.js için @aliyunmq/mq-http-sdk paketini kullanarak sıralı mesajların nasıl gönderileceğini ve alınacağını gösterir.

Sıralamanın çalışma biçimi

ApsaraMQ for RocketMQ iki tür sıralama kapsamı destekler:

  • Genel olarak sıralı mesajlar -- Bir konudaki tüm mesajlar tek bir FIFO dizisi halinde teslim edilir ve tüketilir.

  • Bölümlere göre sıralı mesajlar -- Mesajlar, bir parçalama anahtarı kullanılarak bölümlere dağıtılır. Her bölüm içinde mesajlar FIFO düzeninde teslim edilir ve tüketilir. Farklı bölümlerdeki mesajlar aynı anda tüketilebilir.

Bir parçalama anahtarı, mesajın hangi bölüme yönlendirileceğini belirler. Mesaj anahtarı ise mesaj araması için kullanılan ayrı bir dizindir. Bu iki kavramı karıştırmayın.

Sıralama, birbirinden bağımsız iki garantiden oluşur:

Garanti Gereksinim
Üretim sırası Mesajları tek bir üreticiden tek bir iş parçacığı üzerinde gönderin. Birden fazla üretici veya iş parçacığı eşzamanlı olarak gönderim yaparsa broker mesajları varış sırasına göre kaydeder; bu sıra, amaçlanan iş sırasından farklı olabilir.
Tüketim sırası Aynı bölümden sonraki mesaj grubunu tüketmeden önce mevcut mesaj grubundaki her mesajı onaylayın. Broker bir onay (ACK) almazsa yeni mesajları teslim etmeden önce onaylanmamış mesajı yeniden teslim eder.

Ön koşullar

Başlamadan önce aşağıdaki adımları tamamladığınızdan emin olun:

Sıralı mesajları gönderme

Önemli

Sıra yalnızca tek bir üretici tek bir iş parçacığı üzerinden mesaj gönderdiğinde garanti edilir. Birden fazla üretici veya iş parçacığı eşzamanlı olarak gönderim yaparsa broker mesajları varış sırasına göre kaydeder; bu sıra, amaçlanan iş sırasından farklı olabilir.

Kodu çalıştırmadan önce aşağıdaki yer tutucuları gerçek değerlerinizle değiştirin:

Yer Tutucu Açıklama
${HTTP_ENDPOINT} ApsaraMQ for RocketMQ konsolundaki Instance Details sayfasında > HTTP Endpoint bölümünde bulunan HTTP uç noktası
${TOPIC} Konsolda oluşturulan konu adı
${INSTANCE_ID} Örnek kimliği. Örneğin bir ad alanı varsa kimliği belirtin. Yoksa null veya "" olarak ayarlayın. Ad alanı bilgisi için Instance Details sayfasını kontrol edin.
const {
  MQClient,
  MessageProperties
} = require('@aliyunmq/mq-http-sdk');

// HTTP endpoint. Get this from Instance Details > HTTP Endpoint in the console.
const endpoint = "${HTTP_ENDPOINT}";
// Load credentials from environment variables.
const accessKeyId = process.env['ALIBABA_CLOUD_ACCESS_KEY_ID'];
const accessKeySecret = process.env['ALIBABA_CLOUD_ACCESS_KEY_SECRET'];

var client = new MQClient(endpoint, accessKeyId, accessKeySecret);

// Topic created in the ApsaraMQ for RocketMQ console.
const topic = "${TOPIC}";
// Instance ID. Set to null or "" if the instance does not have a namespace.
const instanceId = "${INSTANCE_ID}";

const producer = client.getProducer(instanceId, topic);

(async function(){
  try {
    // Send 8 messages. Sharding key i % 2 routes messages to 2 partitions.
    for(var i = 0; i < 8; i++) {
      msgProps = new MessageProperties();
      // Set a custom property.
      msgProps.putProperty("a", i);
      // Set the sharding key. Messages with the same key go to the same partition.
      msgProps.shardingKey(i % 2);
      // Publish with body "hello mq." and tag "TagA".
      res = await producer.publishMessage("hello mq.", "TagA", msgProps);
      console.log("Publish message: MessageID:%s,BodyMD5:%s", res.body.MessageId, res.body.MessageBodyMD5);
    }
  } catch(e) {
    // Handle send failures. Implement retry or persistence logic as needed.
    console.log(e)
  }
})();

Sıralı mesajları alma

Mesajları sırayla tüketmek için consumeMessage() yerine consumeMessageOrderly() yöntemini çağırın. Bu yöntem, aynı bölümden gelen mesajların gönderilme sırasına göre ulaşmasını sağlar.

Temel davranışlar şunlardır:

  • Tek bir çağrı birden fazla bölümden mesaj döndürebilir. Her bölüm içinde sıra korunur.

  • Broker bir ACK almazsa aynı bölümdeki sonraki mesajı teslim etmeden önce o mesajı yeniden teslim eder.

  • Broker aynı bölümden sonraki grubu teslim etmeden önce bir gruptaki tüm mesajları onaylamanız gerekir.

  • Uzun anketleme: Kullanılabilir mesaj yoksa broker belirtilen bekleme süresi boyunca bağlantıyı açık tutar ve bir mesaj geldiğinde hemen yanıt verir.

const {
  MQClient,
} = require('@aliyunmq/mq-http-sdk');

// HTTP endpoint. Get this from Instance Details > HTTP Endpoint in the console.
const endpoint = "${HTTP_ENDPOINT}";
// Load credentials from environment variables.
const accessKeyId = process.env['ALIBABA_CLOUD_ACCESS_KEY_ID'];
const accessKeySecret = process.env['ALIBABA_CLOUD_ACCESS_KEY_SECRET'];

var client = new MQClient(endpoint, accessKeyId, accessKeySecret);

// Topic created in the ApsaraMQ for RocketMQ console.
const topic = "${TOPIC}";
// Consumer group ID created in the ApsaraMQ for RocketMQ console.
const groupId = "GID_http";
// Instance ID. Set to null or "" if the instance does not have a namespace.
const instanceId = "${INSTANCE_ID}";

const consumer = client.getConsumer(instanceId, topic, groupId);

(async function(){
  while(true) {
    try {
      // consumeMessageOrderly(numOfMessages, waitSeconds)
      //   numOfMessages: max messages per call (up to 16)
      //   waitSeconds:   long polling duration in seconds (up to 30)
      res = await consumer.consumeMessageOrderly(
          3, // Receive up to 3 messages per call.
          3  // Wait up to 3 seconds if no messages are available.
          );

      if (res.code == 200) {
        console.log("Consume Messages, requestId:%s", res.requestId);
        const handles = res.body.map((message) => {
          console.log("\tMessageId:%s,Tag:%s,PublishTime:%d,NextConsumeTime:%d,FirstConsumeTime:%d,ConsumedTimes:%d,Body:%s" +
            ",Props:%j,ShardingKey:%s,Prop-A:%s,Tag:%s",
              message.MessageId, message.MessageTag, message.PublishTime, message.NextConsumeTime, message.FirstConsumeTime, message.ConsumedTimes,
              message.MessageBody,message.Properties,message.ShardingKey,message.Properties.a);
          return message.ReceiptHandle;
        });

        // Acknowledge consumed messages.
        // If NextConsumeTime passes without an ACK, the broker redelivers the message.
        res = await consumer.ackMessage(handles);
        if (res.code != 204) {
          // ACK failed -- typically caused by an expired receipt handle.
          console.log("Ack Message Fail:");
          const failHandles = res.body.map((error)=>{
            console.log("\tErrorHandle:%s, Code:%s, Reason:%s\n", error.ReceiptHandle, error.ErrorCode, error.ErrorMessage);
            return error.ReceiptHandle;
          });
          handles.forEach((handle)=>{
            if (failHandles.indexOf(handle) < 0) {
              console.log("\tSucHandle:%s\n", handle);
            }
          });
        } else {
          console.log("Ack Message suc, RequestId:%s\n\t", res.requestId, handles.join(','));
        }
      }
    } catch(e) {
      if (e.Code.indexOf("MessageNotExist") > -1) {
        // No messages available. Long polling continues.
        console.log("Consume Message: no new message, RequestId:%s, Code:%s", e.RequestId, e.Code);
      } else {
        console.log(e);
      }
    }
  }
})();

En iyi uygulamalar

  • Mesajları tek bir üretici iş parçacığından gönderin. Aynı parçalama anahtarına gönderim yapan birden fazla üretici veya iş parçacığı, broker mesajları gönderilme zamanına göre değil varış zamanına göre kaydettiğinden amaçlanan sırayı bozabilir.

  • Sonraki grubu tüketmeden önce her grubu onaylayın. Broker, mevcut gruptaki tüm mesajlar onaylanana kadar bir bölüm için sonraki grubun teslim edilmesini engeller. Onayları atlamak veya geciktirmek tüketimi durdurur.

İlgili kaynaklar