7月15日,阿里云消息中间件MQ正式发布3种消息发送方式,至此,MQ覆盖了消息发送全部场景。新增的三种方式包括可靠同步、可靠异步、单向(oneway)发送方式,满足客户在不同场景、不同传输质量和性能上的消息需求。
简介
MQ发送普通消息有三种实现方式:可靠同步发送、可靠异步发送、单向(Oneway)发送。本文介绍了每种实现的原理、使用场景以及三种实现的异同,同时提供了代码示例以供参考。
可靠同步发送
原理:同步发送是指消息发送方发出数据后,会在收到接收方发回响应之后才发下一个数据包的通讯方式。
应用场景:此种方式应用场景非常广泛,例如重要通知邮件、报名短信通知、营销短信系统等。
可靠异步发送
原理:异步发送是指发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。MQ 的异步发送,需要用户实现异步发送回调接口(SendCallback),在执行消息的异步发送时,应用不需要等待服务器响应即可直接返回,通过回调接口接收务器响应,并对服务器的响应结果进行处理。
应用场景:异步发送一般用于链路耗时较长,对 RT 响应时间较为敏感的业务场景,例如用户视频上传后通知启动转码服务,转码完成后通知推送转码结果等。
单向(Oneway)发送
原理:单向(Oneway)发送特点为只负责发送消息,不等待服务器回应且没有回调函数触发,即只发送请求不等待应答。此方式发送消息的过程耗时非常短,一般在微秒级别。
应用场景:适用于某些耗时非常短,但对可靠性要求并不高的场景,例如日志收集。
下表概括了三者的特点和主要区别。
|
发送TPS |
发送结果反馈 |
可靠性 |
同步发送 |
快 |
有 |
不丢失 |
异步发送 |
快 |
有 |
不丢失 |
单向发送 |
最快 |
无 |
可能丢失 |
示例代码
同步发送
public class ProducerTest {
public static void main(String[] args) {
Properties properties = new Properties();
properties.put(PropertyKeyConst.ProducerId, "XXX");
properties.put(PropertyKeyConst.AccessKey,"XXX");
properties.put(PropertyKeyConst.SecretKey, "XXX");
properties.setProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000");
Producer producer = ONSFactory.createProducer(properties);
producer.start();
for (int i = 0; i < 100; i++){
Message msg = new Message(
"TopicTestMQ",
"TagA",
"Hello MQ".getBytes());
msg.setKey("ORDERID_" + i);
SendResult sendResult = producer.send(msg);
System.out.println(sendResult);
}
producer.shutdown();
}
}
|
异步发送
public static void main(String[] args) {
Properties properties = new Properties();
properties.put(PropertyKeyConst.AccessKey, "DEMO_AK");
properties.put(PropertyKeyConst.SecretKey, "DEMO_SK");
properties.put(PropertyKeyConst.ProducerId, "DEMO_PID");
properties.setProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000");
Producer producer = ONSFactory.createProducer(properties);
producer.start();
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) {
System.out.println("send message failed. topic=" + context.getTopic() + ", msgId=" + context.getMessageId());
}
});
System.out.println("send message async. topic=" + msg.getTopic() + ", msgId=" + msg.getMsgID());
producer.shutdown();
}
|
单向(Oneway)发送
public static void main(String[] args) {
Properties properties = new Properties();
properties.put(PropertyKeyConst.AccessKey, "DEMO_AK");
properties.put(PropertyKeyConst.SecretKey, "DEMO_SK");
properties.put(PropertyKeyConst.ProducerId, "DEMO_PID");
properties.setProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000");
Producer producer = ONSFactory.createProducer(properties);
producer.start();
for (int i = 0; i < 100; i++){
Message msg = new Message(
"TopicTestMQ",
"TagA",
"Hello MQ".getBytes());
msg.setKey("ORDERID_" + i);
producer.sendOneway(msg);
}
producer.shutdown();
}
|
企业级互联网架构Aliware,让您的业务能力云化:https://www.aliyun.com/aliware