Bu konu, ApsaraMQ for RocketMQ HTTP istemci SDK aracılığıyla normal mesajların nasıl gönderileceğini ve alınacağını gösteren Java örnekleri sunar. Normal mesajlar varsayılan mesaj türüdür; zamanlanmış, gecikmeli, sıralı ve işlemsel mesajlardan farklı olarak özel teslimat semantiği taşımazlar ve tüketicilere mümkün olan en kısa sürede iletilirler.
Ön koşullar
Başlamadan önce şunları yaptığınızdan emin olun:
Java SDK'yı yükleyin. Daha fazla bilgi için bkz. Ortamı hazırlama
ApsaraMQ for RocketMQ konsolunda gerekli kaynakları oluşturun: bir örnek, bir konu (Normal mesaj türüne ayarlanmış) ve bir tüketici grubu. Daha fazla bilgi için bkz. Kaynakları oluşturma
AccessKey çiftinizi (AccessKey ID ve AccessKey secret) edinin. Daha fazla bilgi için bkz. AccessKey çifti oluşturma
Çalışma mantığı
Her iki örnek de aynı iş akışını izler:
HTTP uç noktası ve AccessKey kimlik bilgileriyle bir
MQClientörneği oluşturun.Bir üretici veya tüketiciyi belirli bir örnek ve konuya bağlayın.
Mesajları gönderin veya yoklayın, ardından işlem bittiğinde istemciyi kapatın.
Her konu yalnızca bir mesaj türünü destekler. Normal mesajlar için oluşturulan bir konu, zamanlanmış, gecikmeli, sıralı veya işlemsel mesajları gönderemez veya alamaz.
Mesaj gönderme
Aşağıdaki örnek, senkron yayınlama kullanarak dört normal mesajı döngü içinde bir konuya gönderir. publishMessage yöntemi bir özel durum fırlatmadan dönerse mesaj başarıyla gönderilmiş demektir.
Yer tutucuları gerçek değerlerinizle değiştirin:
| Yer Tutucu | Açıklama | Nerede Bulunur |
|---|---|---|
<your-http-endpoint> |
Örneğin HTTP uç noktası | Instance Details sayfası > HTTP Endpoint bölümü |
<your-topic> |
Konu adı | ApsaraMQ for RocketMQ konsolu |
<your-instance-id> |
Örnek Kimliği. Örnekte ad alanı yoksa null veya "" olarak ayarlayın |
Instance Details sayfası |
import com.aliyun.mq.http.MQClient;
import com.aliyun.mq.http.MQProducer;
import com.aliyun.mq.http.model.TopicMessage;
import java.util.Date;
public class Producer {
public static void main(String[] args) {
MQClient mqClient = new MQClient(
"<your-http-endpoint>",
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
);
final String topic = "<your-topic>";
final String instanceId = "<your-instance-id>";
// Get a producer for this topic and instance.
MQProducer producer;
if (instanceId != null && instanceId != "") {
producer = mqClient.getProducer(instanceId, topic);
} else {
producer = mqClient.getProducer(topic);
}
try {
for (int i = 0; i < 4; i++) {
TopicMessage pubMsg = new TopicMessage(
"hello mq!".getBytes(), // Message body
"A" // Message tag for filtering
);
// Custom property
pubMsg.getProperties().put("a", String.valueOf(i));
// Business key for message tracing (use an order ID, user ID, or similar identifier)
pubMsg.setMessageKey("MessageKey");
// Publish synchronously. No exception means success.
TopicMessage pubResultMsg = producer.publishMessage(pubMsg);
System.out.println(new Date() + " Send mq message success. Topic is:" + topic
+ ", msgId is: " + pubResultMsg.getMessageId()
+ ", bodyMD5 is: " + pubResultMsg.getMessageBodyMD5());
}
} catch (Throwable e) {
System.out.println(new Date() + " Send mq message failed. Topic is:" + topic);
e.printStackTrace();
}
mqClient.close();
}
}
Önemli noktalar:
Kimlik bilgilerinin ortam değişkenlerinden alınması:
ALIBABA_CLOUD_ACCESS_KEY_IDveALIBABA_CLOUD_ACCESS_KEY_SECRETdeğerleri ortam değişkenlerinden okunur. Kodu çalıştırmadan önce bu değişkenleri ayarlayın.Mesaj etiketi: Etiketler, abonelerin bir konu içindeki mesajları filtrelemesine olanak tanır. Bu örnekte etiket
"A"olarak belirlenmiştir.Mesaj anahtarı: Mesaj anahtarını sipariş kimliği veya kullanıcı kimliği gibi bir iş tanımlayıcısı olarak ayarlayın. Bu, ApsaraMQ for RocketMQ konsolunda mesajları sorgulamayı ve izlemeyi kolaylaştırır.
Mesajları alma ve onaylama
Aşağıdaki örnek, uzun yoklama döngüsü kullanarak bir konudan mesajları tüketir. Her toplu işi işledikten sonra broker'a bir onay (ACK) gönderir. Broker, yeniden deneme aralığı geçmeden önce bir ACK almazsa mesajı yeniden iletir.
Yer tutucuları gerçek değerlerinizle değiştirin:
| Yer Tutucu | Açıklama | Nerede Bulunur |
|---|---|---|
<your-http-endpoint> |
Örneğin HTTP uç noktası | Instance Details sayfası > HTTP Endpoint bölümü |
<your-topic> |
Konu adı | ApsaraMQ for RocketMQ konsolu |
<your-instance-id> |
Örnek Kimliği. Örnekte ad alanı yoksa null veya "" olarak ayarlayın |
Instance Details sayfası |
<your-group-id> |
Tüketici grubu kimliği | ApsaraMQ for RocketMQ konsolu |
import com.aliyun.mq.http.MQClient;
import com.aliyun.mq.http.MQConsumer;
import com.aliyun.mq.http.common.AckMessageException;
import com.aliyun.mq.http.model.Message;
import java.util.ArrayList;
import java.util.List;
public class Consumer {
public static void main(String[] args) {
MQClient mqClient = new MQClient(
"<your-http-endpoint>",
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
);
final String topic = "<your-topic>";
final String groupId = "<your-group-id>";
final String instanceId = "<your-instance-id>";
// Get a consumer for this topic, group, and instance.
final MQConsumer consumer;
if (instanceId != null && instanceId != "") {
consumer = mqClient.getConsumer(instanceId, topic, groupId, null);
} else {
consumer = mqClient.getConsumer(topic, groupId);
}
// Poll for messages in a loop.
// In production, use multiple threads for concurrent consumption.
do {
List<Message> messages = null;
try {
// Long polling: if no message is available, the request hangs
// on the broker for up to the specified number of seconds.
messages = consumer.consumeMessage(
3, // Max messages per batch (up to 16)
3 // Long-polling timeout in seconds (up to 30)
);
} catch (Throwable e) {
e.printStackTrace();
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
if (messages == null || messages.isEmpty()) {
System.out.println(Thread.currentThread().getName() + ": no new message, continue!");
continue;
}
// --- Process messages ---
for (Message message : messages) {
System.out.println("Receive message: " + message);
}
// --- Acknowledge messages ---
// Each message has a unique receipt handle that expires after
// the delivery retry interval. ACK before it expires to prevent
// redelivery.
{
List<String> handles = new ArrayList<String>();
for (Message message : messages) {
handles.add(message.getReceiptHandle());
}
try {
consumer.ackMessage(handles);
} catch (Throwable e) {
if (e instanceof AckMessageException) {
AckMessageException errors = (AckMessageException) e;
System.out.println("Ack message fail, requestId is:" + errors.getRequestId()
+ ", fail handles:");
if (errors.getErrorMessages() != null) {
for (String errorHandle : errors.getErrorMessages().keySet()) {
System.out.println("Handle:" + errorHandle
+ ", ErrorCode:" + errors.getErrorMessages().get(errorHandle).getErrorCode()
+ ", ErrorMsg:" + errors.getErrorMessages().get(errorHandle).getErrorMessage());
}
}
continue;
}
e.printStackTrace();
}
}
} while (true);
}
}
Önemli noktalar:
Uzun yoklama: Tüketici, belirtilen zaman aşımı süresi boyunca (bu örnekte 3 saniye) bağlantıyı broker üzerinde açık tutar. Bu süre zarfında bir mesaj gelirse broker bir sonraki yoklama döngüsünü beklemek yerine hemen yanıt verir. Maksimum zaman aşımı 30 saniyedir.
Toplu iş boyutu: Her
consumeMessageçağrısı, belirtilen sayıda mesaja kadar (bu örnekte 3, maksimum 16) mesaj döndürür.Alındı tanıtıcısı: Bir mesaj her iletildiğinde benzersiz bir zaman damgasına sahip yeni bir alındı tanıtıcısı alır. Mesajı onaylamak (ACK) için bu tanıtıcıyı kullanın. Tanıtıcı, ACK broker'a ulaşmadan önce sona ererse mesaj yeniden iletilir.
Eşzamanlılık: Bu örnek tek bir iş parçacığı kullanır. Daha yüksek aktarım hızı için üretim ortamında birden çok iş parçacığı ile tüketim yapın.
Kullanım notları
Konu başına tek tür: Normal mesajlar için oluşturulan bir konu diğer mesaj türlerini (zamanlanmış, gecikmeli, sıralı veya işlemsel) gönderemez veya alamaz. Her mesaj türü için ayrı konular oluşturun.
Anlamlı mesaj anahtarları ayarlayın: Mesaj anahtarı olarak sipariş kimlikleri veya kullanıcı kimlikleri gibi iş tanımlayıcılarını kullanın. Bu, konsolda mesajları daha hızlı sorgulamanızı ve izlemenizi sağlar.
ACK hatalarını düzgün şekilde yönetin:
ackMessageyöntemi birAckMessageExceptionözel durumu fırlatırsa başarısız olan tanıtıcıları ve hata kodlarını günlüğe kaydedin. Broker, onaylanmamış mesajları otomatik olarak yeniden ilettiğinden ACK hatalarını kritik hata olarak değerlendirmekten kaçının.Kaynakları temizleyin: Üretici veya tüketiciye artık ihtiyaç duyulmadığında HTTP bağlantılarını serbest bırakmak için
mqClient.close()yöntemini çağırın.
Sonraki adımlar
Ortamı hazırlama: Java SDK'yı yükleyin ve bağımlılıkları yapılandırın.
Kaynakları oluşturma: Konsolda örnekleri, konuları ve tüketici gruplarını kurun.