Normal mesajlar, ApsaraMQ for RocketMQ içindeki varsayılan mesaj türüdür ve özel teslimat semantiğine sahip değildir. Zamanlanmış, gecikmeli, sıralı ve işlemsel mesajlardan farklı olarak normal mesajlar ek teslimat davranışı taşımaz.
Bu konuda, Go için HTTP istemci SDK'sını kullanarak normal mesajların nasıl gönderileceği ve alınacağına ilişkin örnek kodlar sunulmaktadır.
Önkoşullar
Başlamadan önce aşağıdaki adımları tamamladığınızdan emin olun:
Go HTTP istemci SDK'sının yüklü olması. Daha fazla bilgi için bkz. Ortamı hazırlama
Konsolda bir ApsaraMQ for RocketMQ örneği, konusu ve tüketici grubu oluşturmuş olmanız. Daha fazla bilgi için bkz. Kaynak oluşturma
Alibaba Cloud hesabınız için bir AccessKey çifti oluşturmuş olmanız. Daha fazla bilgi için bkz. AccessKey çifti oluşturma
Yapılandırma parametreleri
Aşağıdaki örneklerde belirtilen parametreler gereklidir. Kodu çalıştırmadan önce yer tutucuları gerçek değerlerinizle değiştirin.
| Yer Tutucu | Açıklama | Nerede Bulunur |
|---|---|---|
<your-http-endpoint> |
Örneğinizin HTTP uç noktası | ApsaraMQ for RocketMQ konsolunda Instance Details sayfası > HTTP Endpoint bölümü |
<your-topic> |
Mesajların gönderileceği konu | Konsolda oluşturulmalıdır. Her konu yalnızca bir mesaj türünü destekler |
<your-instance-id> |
Örneğinizin kimliği (ID) | Instance Details sayfası. Örneğin ad alanı yoksa bu değeri null veya boş bir dize olarak ayarlayın |
<your-group-id> |
Tüketici grubunuzun kimliği (ID) (yalnızca tüketici için) | Konsolda oluşturulmalıdır |
AccessKey kimlik bilgileri ortam değişkenlerinden okunur:
ALIBABA_CLOUD_ACCESS_KEY_IDALIBABA_CLOUD_ACCESS_KEY_SECRET
Normal mesajları gönderme
Aşağıdaki örnek, bir üreticiyi başlatır ve bir konuya dört mesaj gönderir. Her mesaj; bir gövde, isteğe bağlı bir etiket, bir mesaj anahtarı ve özel özellikler içerir.
package main
import (
"fmt"
"os"
"strconv"
"time"
"github.com/aliyunmq/mq-http-go-sdk"
)
func main() {
endpoint := "<your-http-endpoint>"
accessKey := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
secretKey := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
topic := "<your-topic>"
instanceId := "<your-instance-id>"
client := mq_http_sdk.NewAliyunMQClient(endpoint, accessKey, secretKey, "")
producer := client.GetProducer(instanceId, topic)
for i := 0; i < 4; i++ {
msg := mq_http_sdk.PublishMessageRequest{
MessageBody: "hello mq!",
MessageTag: "", // Optional: filter tag
Properties: map[string]string{}, // Optional: custom properties
}
msg.MessageKey = "MessageKey"
msg.Properties["a"] = strconv.Itoa(i)
ret, err := producer.PublishMessage(msg)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("Publish ---->\n\tMessageId:%s, BodyMD5:%s, \n",
ret.MessageId, ret.MessageBodyMD5)
time.Sleep(100 * time.Millisecond)
}
}
Önemli noktalar:
PublishMessagesenkron bir çağrıdır ve başarı durumundaMessageIdileMessageBodyMD5değerlerini döndürür.Mesajları, eşleşen etiket filtresine sahip aboneliklerle belirli tüketicilere yönlendirmek için
MessageTagdeğerini ayarlayın.Mesaj için özel bir tanımlayıcı belirlemek amacıyla
MessageKeykullanın.
Normal mesajları alma
Aşağıdaki örnek, bir tüketiciyi başlatır ve uzun oylama (long polling) kullanarak sürekli olarak mesajları yoklar. Her toplu işi işledikten sonra, yeniden teslim edilmelerini önlemek için mesajları onaylar.
package main
import (
"fmt"
"os"
"strings"
"time"
"github.com/aliyunmq/mq-http-go-sdk"
"github.com/gogap/errors"
)
func main() {
endpoint := "<your-http-endpoint>"
accessKey := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
secretKey := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
topic := "<your-topic>"
instanceId := "<your-instance-id>"
groupId := "<your-group-id>"
client := mq_http_sdk.NewAliyunMQClient(endpoint, accessKey, secretKey, "")
consumer := client.GetConsumer(instanceId, topic, groupId, "")
for {
endChan := make(chan int)
respChan := make(chan mq_http_sdk.ConsumeMessageResponse)
errChan := make(chan error)
go func() {
select {
case resp := <-respChan:
// Process the batch
var handles []string
fmt.Printf("Consume %d messages---->\n", len(resp.Messages))
for _, v := range resp.Messages {
handles = append(handles, v.ReceiptHandle)
fmt.Printf("\tMessageID: %s, PublishTime: %d, MessageTag: %s\n"+
"\tConsumedTimes: %d, FirstConsumeTime: %d, NextConsumeTime: %d\n"+
"\tBody: %s\n"+
"\tProps: %s\n",
v.MessageId, v.PublishTime, v.MessageTag, v.ConsumedTimes,
v.FirstConsumeTime, v.NextConsumeTime, v.MessageBody, v.Properties)
}
// Acknowledge processed messages
ackerr := consumer.AckMessage(handles)
if ackerr != nil {
fmt.Println(ackerr)
if errAckItems, ok := ackerr.(errors.ErrCode).Context()["Detail"].([]mq_http_sdk.ErrAckItem); ok {
for _, errAckItem := range errAckItems {
fmt.Printf("\tErrorHandle:%s, ErrorCode:%s, ErrorMsg:%s\n",
errAckItem.ErrorHandle, errAckItem.ErrorCode, errAckItem.ErrorMsg)
}
} else {
fmt.Println("ack err =", ackerr)
}
time.Sleep(3 * time.Second)
} else {
fmt.Printf("Ack ---->\n\t%s\n", handles)
}
endChan <- 1
case err := <-errChan:
if strings.Contains(err.(errors.ErrCode).Error(), "MessageNotExist") {
fmt.Println("\nNo new message, continue!")
} else {
fmt.Println(err)
time.Sleep(3 * time.Second)
}
endChan <- 1
case <-time.After(35 * time.Second):
fmt.Println("Timeout of consumer message ??")
endChan <- 1
}
}()
// Long polling: wait up to 3 seconds for new messages, fetch up to 3 per batch
consumer.ConsumeMessage(respChan, errChan,
3, // Max messages per batch (up to 16)
3, // Long polling wait time in seconds (up to 30)
)
<-endChan
}
}
Uzun oylama (Long Polling) çalışma mekanizması
Uzun oylama modunda, mevcut bir mesaj yoksa istek, belirttiğiniz süre boyunca (en fazla 30 saniye) broker üzerinde bekletilir. Bir mesaj geldiğinde broker anında yanıt verir. Bu yöntem, kısa oylamaya kıyasla boş yanıtları azaltır. Varsayılan ağ zaman aşımı 35 saniyedir.
Onaylama ve yeniden teslimat
Bir mesajı işledikten sonra, tüketimi onaylamak için makbuz tanıtıcısı ile birlikte AckMessage çağrısını yapın. Broker, NextConsumeTime son tarihinden önce bir onay almazsa mesajı yeniden teslim eder. Her yeniden teslimatta yeni bir makbuz tanıtıcısı atanır.
Not: Mesajı onaylamadan önce makbuz tanıtıcısının süresi dolarsa onaylama işlemi başarısız olur. Hata yanıtı, başarısız olan her tanıtıcı için ErrorHandle, ErrorCode ve ErrorMsg bilgilerini içerir.