Les messages ordonnés sont un type de message proposé par ApsaraMQ for RocketMQ. Ils sont publiés et consommés dans un ordre strict de type premier entré, premier sorti (FIFO). Cette rubrique fournit des exemples de code montrant comment envoyer et recevoir des messages ordonnés à l'aide du SDK client TCP pour C ou C++.
Informations générales
Il existe deux types de messages ordonnés :
Messages globalement ordonnés : tous les messages d'un topic spécifié sont publiés et consommés selon l'ordre FIFO.
Messages ordonnés par partition : tous les messages d'un topic spécifié sont distribués vers différentes partitions à l'aide de clés de sharding. Les messages de chaque partition sont publiés et consommés selon l'ordre FIFO. Une clé de sharding est un champ clé utilisé par les messages ordonnés pour identifier les différentes partitions. Elle diffère de la clé d'un message standard.
Pour en savoir plus, consultez la rubrique Messages ordonnés.
Prérequis
Assurez-vous d'avoir effectué les opérations suivantes :
Téléchargez le SDK pour C ou C++. Pour plus d'informations, consultez la page Notes de version du SDK client TCP pour C++.
Préparez l'environnement. Pour plus d'informations, consultez la page Préparer l'environnement (v1.x.x).
Créez dans la console ApsaraMQ for RocketMQ les ressources que vous souhaitez spécifier dans le code (instances, topics et groupes de consommateurs). Pour plus d'informations, consultez la page Créer des ressources.
Obtenez la paire AccessKey de votre compte Alibaba Cloud. Pour plus d'informations, consultez la page Créer une AccessKey.
Envoyer des messages ordonnés
Un courtier ApsaraMQ for RocketMQ détermine l'ordre de génération des messages en fonction de l'ordre dans lequel l'expéditeur utilise un seul producteur ou thread pour les envoyer. Si l'expéditeur utilise plusieurs producteurs ou threads pour envoyer des messages simultanément, l'ordre des messages dépend de l'ordre de réception par le courtier ApsaraMQ for RocketMQ. Cet ordre peut différer de l'ordre d'envoi côté application métier.
L'exemple de code suivant montre comment envoyer des messages ordonnés à l'aide du SDK client TCP pour C ou C++ :
#include "ONSFactory.h"
#include "ONSClientException.h"
#include <iostream>
using namespace ons;
int main()
{
// The parameter that is required to create and use a producer.
ONSFactoryProperty factoryInfo;
// The ID of the consumer group that you created in the ApsaraMQ for RocketMQ console.
factoryInfo.setFactoryProperty(ONSFactoryProperty::ProducerId, "XXX");
// The TCP endpoint. You can obtain the endpoint in the TCP Endpoint section of the Instance Details page in the ApsaraMQ for RocketMQ console.
factoryInfo.setFactoryProperty(ONSFactoryProperty::NAMESRV_ADDR, "XXX");
// The topic that you created in the ApsaraMQ for RocketMQ console.
factoryInfo.setFactoryProperty(ONSFactoryProperty::PublishTopics,"XXX" );
// The message content.
factoryInfo.setFactoryProperty(ONSFactoryProperty::MsgContent, "XXX");
// Make sure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are configured.
// The AccessKey ID that is used for authentication.
factoryInfo.setFactoryProperty(ONSFactoryProperty::AccessKey, getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
// The AccessKey secret that is used for authentication.
factoryInfo.setFactoryProperty(ONSFactoryProperty::SecretKey, getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// Create the producer.
OrderProducer *pProducer = ONSFactory::getInstance()->createOrderProducer(factoryInfo);
// Before you send the message, call the start() method only once to start the producer.
pProducer->start();
Message msg(
//Message Topic
factoryInfo.getPublishTopics(),
//Message Tag
"TagA",
//Message Key. Set a key to uniquely identify the message. We recommend that the key be globally unique so that if a message cannot be received, you can query it in the ApsaraMQ for RocketMQ console using the key and resend it. Note: Not setting a key does not affect message sending or receiving.
"ORDERID_100",
//Message Body
factoryInfo.getMessageContent()
);
// The key field that is used to identify partitions for partitionally ordered messages.
// This field can be set to a non-empty string for globally ordered messages.
std::string shardingKey = "abc";
// Messages that have the same sharding key are sent in order.
try
{
// Send the message. If no exception is thrown, the message is sent.
SendResultONS sendResult = pProducer->send(msg, shardingKey);
std::cout << "send success" << std::endl;
}
catch(ONSClientException & e)
{
// Specify the logic to handle errors.
}
// Before you exit your application, destroy the producer. If you do not destroy the producer, issues such as memory leaks may occur.
pProducer->shutdown();
return 0;
}
Dans le SDK C++ v1.1.1, le constructeur à trois paramètres Message(topic, tag, body) présente un bogue connu : le paramètre body est mappé de manière incorrecte au champ keys en interne. Le corps du message reste alors vide, ce qui provoque une erreur 'the message body is empty' lors de l'appel à send(). Utilisez le constructeur à quatre paramètres Message(topic, tag, key, body) comme indiqué dans l'exemple ci-dessus pour éviter ce problème.
S'abonner à des messages ordonnés
L'exemple de code suivant montre comment s'abonner à des messages ordonnés à l'aide du SDK client TCP pour C ou C++ :
#include "ONSFactory.h"
using namespace std;
using namespace ons;
// Create the consumer instance.
//After the push consumer pulls the message, the push consumer calls the consumeMessage function of the instance.
class ONSCLIENT_API MyMsgListener : public MessageOrderListener
{
public:
MyMsgListener()
{
}
virtual ~MyMsgListener()
{
}
virtual OrderAction consume(Message &message, ConsumeOrderContext &context)
{
// Consume messages based on your business requirements.
return Success; //CONSUME_SUCCESS;
}
};
int main(int argc, char* argv[])
{
// The parameter that is required to create and use the consumer.
ONSFactoryProperty factoryInfo;
// The ID of the consumer group that you created in the ApsaraMQ for RocketMQ console.
factoryInfo.setFactoryProperty(ONSFactoryProperty::ConsumerId, "XXX");
// The topic that you created in the ApsaraMQ for RocketMQ console.
factoryInfo.setFactoryProperty(ONSFactoryProperty::PublishTopics,"XXX" );
// Make sure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are configured.
// The AccessKey ID that is used for authentication.
factoryInfo.setFactoryProperty(ONSFactoryProperty::AccessKey, getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
// The AccessKey secret that is used for authentication.
factoryInfo.setFactoryProperty(ONSFactoryProperty::SecretKey, getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// The TCP endpoint. You can obtain the endpoint in the TCP Endpoint section of the Instance Details page in the ApsaraMQ for RocketMQ console.
factoryInfo.setFactoryProperty(ONSFactoryProperty::NAMESRV_ADDR, "XXX");
// Create the consumer.
OrderConsumer* orderConsumer = ONSFactory::getInstance()->createOrderConsumer(factoryInfo);
MyMsgListener msglistener;
// The message topic and tag to which the consumer subscribes.
orderConsumer->subscribe(factoryInfo.getPublishTopics(), "*",&msglistener );
// Register the instance to listen to messages. After the consumer pulls the messages, the consumer calls the consumeMessage function of the message listening class.
//Start the consumer.
orderConsumer->start();
for(volatile int i = 0; i < 1000000000; ++i) {
//wait
}
// Destroy the consumer. Before you exit the application, destroy the consumer. Otherwise, issues such as memory leaks may occur.
orderConsumer->shutdown();
return 0;
}