RocketMQ建议使用规范

目的

解决大型分布式互联网项目消息的使用

规范

一、设计原理

说明:

  1. NameServer是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。
  2. Broker部署相对复杂,Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master,Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。Master可以部署多个。每个Broker与Name Server集群中的所有节点建立长连接,定时注册Topic信息到所有NameServer。
  3. Producer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可以集群部署。
  4. Consumer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker配置决定。

二、使用教程

1、严格顺序消息的发送与消费

要注意严格顺序消息发送端要向一个queue发送消息,消费端要配置为 ORDERLY 模式,这牺牲了集群的性能。

1、pom.xml配置


  com.midea.jr.framework
  framework.mq
  0.0.1-SNAPSHOT
 


2、Message Producer 端Spring IOC xml配置

    
    
    
 


3、Message Producer 端代码
// 发送顺序消息,注意这里要持续向其中一个队列发送消息才是严格顺序消息
SendResult sr1 = messageProducer.send( new Message( "finance-sms", "message".getBytes() ), new MessageQueueSelector() {
    @Override
    public MessageQueue select( List mqs, Message msg, Object arg ) {
        Integer id = arg.hashCode();
        int index = id % mqs.size();
        return mqs.get( index );
    }
}, 1 ); 


4、Message Consumer 端Spring IOC xml配置

    
    
    
    
    
        
            
                
            
        
    
 


3、properties文件配置
rocketmq.namesrvAddr=10.16.68.136:9876;10.16.68.137:9876

2、普通顺序消息的发送与消费

1、pom.xml配置


  com.midea.finance.framework
  finance.framework.mq
  0.0.1-SNAPSHOT
 


2、Message Producer 端Spring IOC xml配置

    
    
    
 


3、Message Producer 端代码
messageProducer.send( new Message( "finance-sms", "message".getBytes() ) ); 


4、Message Consumer 端Spring IOC xml配置

    
    
    
    
    
        
            
                
            
        
    
 


3、properties文件配置
rocketmq.namesrvAddr=10.16.68.136:9876;10.16.68.137:9876

3、非顺序消息的发送与消费

1、pom.xml配置

  com.midea.finance.framework  finance.framework.mq  0.0.1-SNAPSHOT 

2、Message Producer 端Spring IOC xml配置

    
    
    
 


3、Message Producer 端代码
messageProducer.send( new Message( "finance-sms", "message".getBytes() ) ); 


4、Message Consumer 端Spring IOC xml配置

    
    
    
    
    
        
            
                
            
        
    
 


3、properties文件配置
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 offseTable = new HashMap();
  
  
    public static void main(String[] args) throws MQClientException {
        DefaultMQPullConsumer consumer = new DefaultMQPullConsumer("PullConsumerGroup");
        consumer.setNamesrvAddr("127.0.0.1:9876");
        consumer.start();
        //拉取订阅主题的队列,默认队列大小是4
        Set 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 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;
    }

你可能感兴趣的:(工作经历)