消息队列RocketMQ版是阿里云基于Apache RocketMQ构建的低延迟、高并发、高可用、高可靠的分布式消息中间件。
严格保证先进先出的生产消费。
主要用于
为了保证消息一定会被消费,或者网络环境不稳定、或者用户应用重启发布的情况下,还设置有重复尝试机制,按照消费幂等去保证一致性,
因为不同的Message ID对应的消息内容可能相同,有可能出现冲突(重复)的情况,所以真正安全的幂等处理,不建议以Message ID作为处理依据。最好的方式是以业务唯一标识作为幂等处理的关键依据,而业务的唯一标识可以通过消息Key设置。
Message message = new Message();
message.setKey("ORDERID_100");
SendResult sendResult = producer.send(message);
consumer.subscribe("ons_test", "*", new MessageListener() {
public Action consume(Message message, ConsumeContext context) {
String key = message.getKey()
// 根据业务唯一标识的Key做幂等处理。
}
});
rocketmq支持的消息有四种:普通消息、定时延时消息、顺序消息和事务消息
(此处理论知识主要来源于阿里云,为防止连接失效,或者网站知识发生变化,顺便将自己觉得重要的内容全部copy了过来)
普通消息是指消息队列RocketMQ版中无特性的消息,区别于有特性的定时和延时消息、顺序消息和事务消息,同时四种之间的topic也不能混用。
普通消息
发送方式:同步(Sync)发送、异步(Async)发送和单向(Oneway)发送。
同步发送是指消息发送方发出一条消息后,会在收到服务端返回响应之后才发下一条消息的通讯方式,此种方式应用场景非常广泛,例如重要通知邮件、报名短信通知、营销短信系统等。
异步发送是指发送方发出一条消息后,不等服务端返回响应,接着发送下一条消息的通讯方式。消息队列RocketMQ版的异步发送,需要您实现异步发送回调接口(SendCallback)。消息发送方在发送了一条消息后,不需要等待服务端响应即可发送第二条消息。发送方通过回调接口接收服务端响应,并处理响应结果。异步发送一般用于链路耗时较长,对响应时间较为敏感的业务场景,例如,您视频上传后通知启动转码服务,转码完成后通知推送转码结果等。
发送方只负责发送消息,不等待服务端返回响应且没有回调函数触发,即只发送请求不等待应答。此方式发送消息的过程耗时非常短,一般在微秒级别,适用于某些耗时非常短,但对可靠性要求并不高的场景,例如日志收集。
具体实现:
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.ONSFactory;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import java.util.Properties;
public class ProducerTest {
public static void main(String[] args) {
Properties properties = new Properties();
// AccessKeyId 阿里云身份验证,在阿里云用户信息管理控制台获取。
properties.put(PropertyKeyConst.AccessKey,"XXX");
// AccessKeySecret 阿里云身份验证,在阿里云用户信息管理控制台获取。
properties.put(PropertyKeyConst.SecretKey, "XXX");
//设置发送超时时间,单位毫秒。
properties.setProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000");
// 设置TCP接入域名,进入控制台的实例详情页面的TCP协议客户端接入点区域查看。
properties.put(PropertyKeyConst.NAMESRV_ADDR, "XXX");
Producer producer = ONSFactory.createProducer(properties);
// 在发送消息前,必须调用start方法来启动Producer,只需调用一次即可。
producer.start();
//循环发送消息。
for (int i = 0; i < 100; i++){
Message msg = new Message( //
// 普通消息所属的Topic,切勿使用普通消息的Topic来收发其他类型的消息。
"TopicTestMQ",
// Message Tag可理解为Gmail中的标签,对消息进行再归类,方便Consumer指定过滤条件在消息队列RocketMQ版的服务器过滤。
"TagA",
// Message Body可以是任何二进制形式的数据,消息队列RocketMQ版不做任何干预。
// 需要Producer与Consumer协商好一致的序列化和反序列化方式。
"Hello MQ".getBytes());
// 设置代表消息的业务关键属性,请尽可能全局唯一。
// 以方便您在无法正常收到消息情况下,可通过阿里云服务器管理控制台查询消息并补发。
// 注意:不设置也不会影响消息正常收发。
msg.setKey("ORDERID_" + i);
try {
SendResult sendResult = producer.send(msg)