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