目的
解决大型分布式互联网项目消息的使用
规范
一、设计原理
说明:
- NameServer是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。
- Broker部署相对复杂,Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master,Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。Master可以部署多个。每个Broker与Name Server集群中的所有节点建立长连接,定时注册Topic信息到所有NameServer。
- Producer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可以集群部署。
- Consumer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker配置决定。
二、使用教程
1、严格顺序消息的发送与消费
要注意严格顺序消息发送端要向一个queue发送消息,消费端要配置为 ORDERLY 模式,这牺牲了集群的性能。
1、pom.xml配置
rocketmq.namesrvAddr=10.16.68.136:9876;10.16.68.137:9876
|
2、普通顺序消息的发送与消费
1、pom.xml配置
rocketmq.namesrvAddr=10.16.68.136:9876;10.16.68.137:9876
|
3、非顺序消息的发送与消费
1、pom.xml配置
rocketmq.namesrvAddr=10.16.68.136:9876;10.16.68.137:9876
|
4、Pull消费消息
pull consumer 需要根据业务场景自己进行封装,暂不推荐使用。
/**
* PullConsumer,订阅消息
*/
public class PullConsumer {
//Java缓存
private static final Map<MessageQueue, Long> offseTable = new HashMap<MessageQueue, Long>();
public static void main(String[] args) throws MQClientException {
DefaultMQPullConsumer consumer = new DefaultMQPullConsumer( "PullConsumerGroup" );
consumer.setNamesrvAddr( "127.0.0.1:9876" );
consumer.start();
//拉取订阅主题的队列,默认队列大小是4
Set<MessageQueue> mqs = consumer.fetchSubscribeMessageQueues( "TopicTestMapBody" );
for (MessageQueue mq : mqs) {
System.out.println( "Consume from the queue: " + mq);
SINGLE_MQ: while ( true ){
try {
PullResult pullResult = consumer.pullBlockIfNotFound(mq, null , getMessageQueueOffset(mq), 32 );
List<MessageExt> list=pullResult.getMsgFoundList();
if (list!= null &&list.size()< 100 ){
for (MessageExt msg:list){
System.out.println(SerializableInterface.deserialize(msg.getBody()));
}
}
System.out.println(pullResult.getNextBeginOffset());
putMessageQueueOffset(mq, pullResult.getNextBeginOffset());
switch (pullResult.getPullStatus()) {
case FOUND:
// TODO
break ;
case NO_MATCHED_MSG:
break ;
case NO_NEW_MSG:
break SINGLE_MQ;
case OFFSET_ILLEGAL:
break ;
default :
break ;
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
consumer.shutdown();
}
private static void putMessageQueueOffset(MessageQueue mq, long offset) {
offseTable.put(mq, offset);
}
private static long getMessageQueueOffset(MessageQueue mq) {
Long offset = offseTable.get(mq);
if (offset != null ){
System.out.println(offset);
return offset;
}
return 0 ;
}
|