是指消息发送方发出数据后,会阻塞直到MQ服务方发回响应消息。
如重要通知邮件、报名短信通知、营销短信系统等。
SendResult sendResult = producer.send(msg);
producer.sendAsync(msg, new SendCallback() {//...});
适用于某些耗时非常短,但对可靠性要求并不高的场景,例如日志收集。
producer.sendOneway(msg);
(1)无特性的消息,区别于有特性的定时、延时、顺序和事务消息。
(2)包括上面的同步、异步、单向消息
消息队列 RocketMQ 提供的一种按照顺序进行发布和消费的消息类型,分为全局顺序消息和分区顺序消息
对于指定的一个 Topic,所有消息按照严格的先入先出(FIFO)的顺序进行发布和消费。
在证券处理中,以人民币兑换美元为 Topic,在价格相同的情况下,先出价者优先处理,则可以通过全局顺序的方式按照 FIFO 的方式进行发布和消费。
对于指定的一个 Topic,所有消息根据 Sharding Key 进行区块分区。同一个分区内的消息按照严格的 FIFO 顺序进行发布和消费。
Sharding Key是顺序消息中用来区分不同分区的关键字段,和普通消息的 Message Key是完全不同的概念。
例一:用户注册需要发送发验证码,以用户 ID 作为 sharding key, 那么同一个用户发送的消息都会按照先后顺序来发布和消费。
例二:电商的订单创建,以订单 ID 作为 sharding key,那么同一个订单相关的创建订单消息、订单支付消息、订单退款消息、订单物流消息都会按照先后顺序来发布和消费。
String orderId = "Order_0000001";
//msg-key: "PAY_201907151223001" 标识此条消息业务id
//msg-key: 以方便您在无法正常收到消息情况下,可通过控制台查询消息并补发。
String payId = "PAY_201907151223001";
Message msg = new Message("pay", "TAG1", "PAY_201907151223001" ,
("支付消息,内容为:xxxxx " ).getBytes(RemotingHelper.DEFAULT_CHARSET));
// 分区顺序消息中区分不同分区的关键字段,sharding key 于普通消息的 key 是完全不同的概念。
// 全局顺序消息,该字段可以设置为任意非空一个字符串常量即可。
String shardingKey = orderId;
SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
@Override
public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
//arg为后续传递的shardingKey,可以根据hash算法or其他方法来计算出id;
//可参考hashmap的hash算法;
int id = hash(arg);
int index = id % mqs.size();
return mqs.get(index);
}
}, shardingKey);
consumer.registerMessageListener(new MessageListenerOrderly() {
@Override
public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs,
ConsumeOrderlyContext context) {
//处理消息...
return ConsumeOrderlyStatus.SUCCESS;
}
});
Producer 将消息发送到消息队列 RocketMQ 服务端,但并不期望这条消息立马投递,而是延迟一定时间后才投递到 Consumer 进行消费
Producer 将消息发送到消息队列 RocketMQ 服务端,但并不期望这条消息立马投递,而是推迟到在当前时间点之后的某一个时间投递到 Consumer 进行消费
// 延时消息,单位毫秒(ms),在指定延迟时间(当前时间之后)进行投递,例如消息在 3 秒后投递
long delayTime = System.currentTimeMillis() + 3000;
// 设置消息需要被投递的时间
msg.setStartDeliverTime(delayTime);
// 定时消息,单位毫秒(ms),在指定时间戳(当前时间之后)进行投递,例如 2019-08-01 16:21:00 投递。如果被设置成当前时间戳之前的某个时刻,消息将立刻投递给消费者。
long timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2019-08-01 16:21:00").getTime();
msg.setStartDeliverTime(timeStamp);
消息队列 RocketMQ 提供类似 X/Open XA 的分布事务功能,通过消息队列 RocketMQ 的事务消息能达到分布式事务的最终一致.
说明:事务消息发送对应步骤 1、2、3、4,事务消息回查对应步骤 5、6、7。
TransactionListener transactionListener = new DeducationTransactionListenerImpl();
//`producer`需要绑定transactionListener
producer.setTransactionListener(transactionListener);
//`producer`需要sendMessageInTransaction方法发送消息
SendResult sendResult = producer.sendMessageInTransaction(msg, null);
public class DeducationTransactionListenerImpl implements TransactionListener {
//当发送prepare(half)消息成功后,会执行此逻辑
@Override
public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
LocalTransactionState state ;
//todo 执行业务方法,并根据执行结果,返回state
return state;
}
/**
* 当没有回应prepare(half)消息时,brokder会检查此条消息的状态
* @param msg
* @return
*/
@Override
public LocalTransactionState checkLocalTransaction(MessageExt msg) {
LocalTransactionState state ;
//todo 查看订单bizNo的状态,并返回state
return state;
}
}
TransactionStatus.CommitTransaction 提交事务,允许订阅方消费该消息。
TransactionStatus.RollbackTransaction 回滚事务,消息将被丢弃不允许消费。
TransactionStatus.Unknow 暂时无法判断状态,期待固定时间以后消息队列 RocketMQ 服务端向发送方进行消息回查。
/**
* 在消息属性中添加第一次消息回查的最快时间,单位秒。
* 例如,以下设置实际第一次回查时间为 120 秒 ~ 125 秒之间
*
* 以上方式只确定事务消息的第一次回查的最快时间,实际回查时间向后浮动0~5秒;
* 如第一次回查后事务仍未提交,后续每隔5秒回查一次。
*/
msg.putUserProperty(MessageConst.PROPERTY_CHECK_IMMUNITY_TIME_IN_SECONDS,"120");
广播消息、 批量消息
MQServer主动向消费端推送
消费端在需要时,主动到MQServer拉取
使用相同 Group ID 的订阅者属于同一个集群。
同一个集群下的订阅者消费逻辑必须完全一致(包括 Tag 的使用),这些订阅者在逻辑上可以认为是一个消费节点。
任意一条消息只需要被集群内的任意一个消费者处理即可。
上一篇跳转—SpringCloud之RocketMQ1 下一篇跳转—SpringCloud之RocketMQ3
官方文档
参考链接1
参考链接2
参考链接3
参考链接4
参考链接5
随心所往,看见未来。Follow your heart,see light!
欢迎点赞、关注、留言,收藏及转发,一起学习、交流!