ApsaraMQ for RocketMQ prend en charge trois modes de transmission pour les messages normaux. Choisissez un mode en fonction du niveau de garantie de livraison requis par votre application :
| Mode | Comportement | Meilleur cas d'utilisation |
|---|---|---|
| Synchrone | Le producteur attend l'accusé de réception du broker avant d'envoyer le message suivant. | Scénarios nécessitant une confirmation de livraison |
| Asynchrone | Le producteur envoie un message et poursuit immédiatement son exécution. Un rappel renvoie le résultat. | Flux de travail sensibles à la latence |
| Unidirectionnel | Le producteur envoie un message sans attendre de réponse. | Scénarios à haut débit où une perte occasionnelle de messages est acceptable |
Prérequis
Avant de commencer, assurez-vous d'avoir :
Des instances, topics et groupes de consommateurs créés dans la console ApsaraMQ for RocketMQ
Une paire AccessKey pour votre compte Alibaba Cloud
(Facultatif) Des paramètres de journalisation configurés
Configuration commune du producteur
Les trois modes partagent la même logique d'initialisation. Créez un producteur une seule fois, puis appelez la méthode d'envoi spécifique au mode choisi.
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.SendResult;
import com.aliyun.openservices.ons.api.SendCallback;
import com.aliyun.openservices.ons.api.OnExceptionContext;
import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import java.util.Date;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
Properties properties = new Properties();
// Read credentials from environment variables.
properties.put(PropertyKeyConst.AccessKey, System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
properties.put(PropertyKeyConst.SecretKey, System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// Send timeout in milliseconds.
properties.setProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000");
// TCP endpoint. Find this in the TCP Endpoint section of the Instance Details page
// in the ApsaraMQ for RocketMQ console.
properties.put(PropertyKeyConst.NAMESRV_ADDR, "<your-tcp-endpoint>");
Producer producer = ONSFactory.createProducer(properties);
// Call start() once before sending any messages.
producer.start();
Remplacez l'espace réservé par votre valeur réelle :
| Espace réservé | Description | Exemple |
|---|---|---|
<your-tcp-endpoint> |
L'endpoint TCP de votre instance | http://MQ_INST_xxxxx.mq-internet.region.aliyuncs.com:80 |
Créer un message
Chaque appel d'envoi nécessite un objet Message. Le constructeur accepte trois arguments :
Message msg = new Message(
"TopicTestMQ", // Topic -- must be a normal-message topic
"TagA", // Tag -- used by consumers to filter messages
"Hello MQ".getBytes() // Body -- binary payload; producer and consumer must
// agree on the serialization format
);
// Optional: set a business key for message tracing in the console.
msg.setKey("ORDERID_100");
Un topic utilisé pour des messages normaux ne peut pas être utilisé pour d'autres types de messages, tels que les messages transactionnels ou planifiés.
Transmission synchrone
Le producteur envoie un message et se bloque jusqu'à ce que le broker renvoie une réponse. Si aucune exception n'est levée, le message a bien été livré.

Cas d'utilisation : Scénarios nécessitant une confirmation de livraison, tels que les notifications par e-mail, les alertes d'inscription ou les messages promotionnels.
Exemple de code
for (int i = 0; i < 100; i++) {
Message msg = new Message("TopicTestMQ", "TagA", "Hello MQ".getBytes());
msg.setKey("ORDERID_" + i);
try {
SendResult sendResult = producer.send(msg);
// A non-null result means the broker accepted the message.
if (sendResult != null) {
System.out.println(new Date() + " Send mq message success. Topic is:"
+ msg.getTopic() + " msgId is: " + sendResult.getMessageId());
}
} catch (Exception e) {
// Handle failures: retry or persist the message for later delivery.
System.out.println(new Date() + " Send mq message failed. Topic is:" + msg.getTopic());
e.printStackTrace();
}
}
Transmission asynchrone
Le producteur envoie un message et revient immédiatement. La réponse du broker est transmise via un SendCallback doté de deux méthodes : onSuccess et onException.

Cas d'utilisation : Flux de travail sensibles à la latence où le thread appelant ne doit pas se bloquer, par exemple pour soumettre une tâche de transcodage vidéo et traiter le résultat dans un rappel.
Exemple de code
Message msg = new Message("TopicTestMQ", "TagA", "Hello MQ".getBytes());
msg.setKey("ORDERID_100");
producer.sendAsync(msg, new SendCallback() {
@Override
public void onSuccess(final SendResult sendResult) {
System.out.println("send message success. topic=" + sendResult.getTopic()
+ ", msgId=" + sendResult.getMessageId());
}
@Override
public void onException(OnExceptionContext context) {
// Handle failures: retry or persist the message for later delivery.
System.out.println("send message failed. topic=" + context.getTopic()
+ ", msgId=" + context.getMessageId());
}
});
// Block for 3 seconds to wait for the callback. In production, use a
// CountDownLatch or similar mechanism instead of Thread.sleep.
TimeUnit.SECONDS.sleep(3);
Transmission unidirectionnelle
Le producteur envoie un message et poursuit son exécution. Aucune réponse n'est renvoyée et aucun rappel n'est déclenché. Ce mode offre le débit le plus élevé au détriment de la fiabilité : un message peut être envoyé en quelques microsecondes.

Cas d'utilisation : Scénarios à volume élevé où une perte occasionnelle de messages est acceptable, tels que la collecte de journaux ou le reporting de métriques.
Le broker n'envoie aucune réponse en mode unidirectionnel, donc les messages échoués sont perdus silencieusement. Si la perte de données n'est pas acceptable, utilisez plutôt la transmission synchrone ou asynchrone.
Exemple de code
for (int i = 0; i < 100; i++) {
Message msg = new Message("TopicTestMQ", "TagA", "Hello MQ".getBytes());
msg.setKey("ORDERID_" + i);
// No return value, no callback. Fire and forget.
producer.sendOneway(msg);
}
Arrêter le producteur
Arrêtez le producteur avant la fermeture de votre application afin de libérer les ressources.
producer.shutdown();
L'arrêt du producteur libère la mémoire. Si votre application envoie fréquemment des messages, maintenez le producteur en cours d'exécution au lieu de le créer et de le détruire pour chaque requête.
Comparaison des modes de transmission
Les trois modes diffèrent selon que le producteur attend ou non une réponse du broker, ainsi que par le compromis entre débit et fiabilité.
| Mode | Méthode d'envoi | TPS | Réponse du broker | Fiabilité | Cas d'utilisation typique |
|---|---|---|---|---|---|
| Synchrone | producer.send(msg) |
Élevé | Oui – le producteur se bloque jusqu'à ce que le broker accuse réception du message | Aucune perte de message | Notifications, confirmations de commande |
| Asynchrone | producer.sendAsync(msg, callback) |
Élevé | Oui – transmise via SendCallback |
Aucune perte de message | Transcodage vidéo, flux de travail asynchrones |
| Unidirectionnel | producer.sendOneway(msg) |
Le plus élevé | Non – le broker ne répond pas, donc le producteur ne peut pas détecter les échecs | Perte de message possible | Collecte de journaux, métriques |
Étapes suivantes
S'abonner aux messages – consommez les messages normaux que vous avez envoyés