RocketMQ基础学习

  • RocketMQ概述  
     

           RocketMQ 是一款分布式、队列模型的消息中间件,具有以下特点: 能够保证严格的消息顺序 提供丰富的消息拉取模式 高效的订阅者水平扩展能力 实时的消息订阅机制 亿级消息堆积能力。 
     
    阿里巴巴开源其自研的第三代分布式消息中间件,目前双十一当天消息容量可达到万亿级。 
  1. RocketMQ原理
    NameServer :  保存broker的信息,并监听borker的心跳,将供Producer和Consumer获取Broker地址。如监听到master不可用,则将salve设为新的主broker。类似于注册中心,默认端口10911
    Broker :  定时将borke的Topic信息到注册到Name Server中。Broker以group分开,每个group只允许一个master,多个slave。 只有master才能进行写入操作。默认端口9876
    Producer :   producer从NameServer获取broker的连接信息,通过连接信息连接对应的broker, 发送消息
    Consumer : consumer从NameServer获取broker的连接信息,通过连接信息连接对应的broker, 进行消费 
      
     rocker采用分区存储,将消息分开存放在master节点的分区内,然后slave节点同步对应master的数据。 
     
    Kafka是采用zk实现对生产者、消费者 topic信息存储,而RocketMQ是自己实现叫做nameServer实现去中心化 
     默认一个borker有4个队列,可配置
  2. RocketMQ优点
    a.强调集群无单点,可扩展
    b.任意一点高可用,水平可扩展
    c.海量消息堆积能力,消息堆积后,写入低延迟。
    d.支持上万个队列 
    e.消息失败重试机制 
    f.消息可查询 
    g.开源社区活跃 
    h.成熟度高
  1. 安装rocketmq 
     https://blog.csdn.net/xiaobo5264063/article/details/105082590
  • 整合Rocketmq-console控制台
     
  1. 下载程序包
     
  2. 解压并导入到IDEA
    将解压后的rocketmq-console文件导入到IDEA即可
     
  3. 修改application.properties的nameserver地址
  4. 启动项目
    访问http://127.0.0.1:8080/#/ 

 

  • springboot整合rocketmq
     
  1. 创建springboot项目
    pom.xml引入依赖
    <dependency>
        <groupId>org.apache.rocketmq</groupId>
        <artifactId>rocketmq-spring-boot-starter</artifactId>
        <version>2.0.3</version>
    </dependency>
  2. 在application.yml中配置如下
    rocketmq:
      ###nameServer地址
      name-server: 192.168.2.115:9876
      producer:
        group: pitch_groups
    server:
      port: 9001
  3. 创建UserEntity.java
    import lombok.Data;
    
    @Data
    public class UserEntity {
        private Integer id;
        private String name;
    
        public UserEntity(Integer id, String name) {
            this.id = id;
            this.name = name;
        }
    }

     
  4. 生产者
    import com.pitch.entity.UserEntity;
    import org.apache.rocketmq.spring.core.RocketMQTemplate;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class ProducerController {
    
        @Autowired
        private RocketMQTemplate rocketMQTemplate;
    
        private static int  id = 0;
    
        // 生产者发送消息
        @RequestMapping("/send")
        public String sendMsg() {
            id++;
            UserEntity orderEntity = new UserEntity(id,"张三");
            // my_topic主题  默认会自动创建
            rocketMQTemplate.convertAndSend("my_topic", orderEntity);
            return "success:"+id;
        }
    
    }
    rocket默认会创建主题
     
  5. 消费者
    import com.pitch.entity.UserEntity;
    import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
    import org.apache.rocketmq.spring.core.RocketMQListener;
    import org.springframework.stereotype.Component;
    
    /**
     * @author xiaobo
     * @Description UserConsumer
     * @createTime 2020-03-24 19:59
     */
    @Component
    // topic:主题   pitch_groups:组
    @RocketMQMessageListener(topic = "my_topic", consumerGroup = "pitch_groups")
    public class UserConsumer  implements RocketMQListener<UserEntity> {
        @Override
        public void onMessage(UserEntity o) {
            System.out.println("消费者获取消息:" + o.toString());
        }
    
    }
  6. 启动项目
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class AppRocket {
        public static void main( String[] args ) {
            SpringApplication.run(AppRocket.class);
        }
    }
    
     
  7. 访问测试 
    http://127.0.0.1:9001/send
     

 

  • rocket实现动态扩容


 

  • 如何解决消息顺序问题
     
  1. 产生背景
     rocket默认一个broker有4个队列 
     
     产生背景:  多个队列、或一个队列对应多个消费者。
     
  2. 解决思路
     1. 生产者  指定消息存放的队列 
     @RequestMapping("/sort")
        public String sortMsg() throws Exception{
            String id = System.currentTimeMillis()+"";
            Message message1 = new Message("my_topic", JSONObject.toJSONBytes(new UserEntity(id,"添加用户")));
            Message message2 = new Message("my_topic", JSONObject.toJSONBytes(new UserEntity(id,"更新用户")));
            Message message3 = new Message("my_topic", JSONObject.toJSONBytes(new UserEntity(id,"删除用户")));
            sortSend(message1, id);
            sortSend(message2, id);
            sortSend(message3, id);
            return "success";
        }
    
        void sortSend(Message message, String flag) throws Exception{
            rocketMQTemplate.getProducer().send(message
                    , new MessageQueueSelector() {
                        @Override
                        public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
                            return  mqs.get(0);  // 指定消息存放在第0个队列
                        }
                    }, flag);
        }

     
     2. 消费者  指定一个队列对应一个消费者线程处理 
    import org.apache.rocketmq.common.message.MessageExt;
    import org.apache.rocketmq.spring.annotation.ConsumeMode;
    import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
    import org.apache.rocketmq.spring.core.RocketMQListener;
    import org.springframework.stereotype.Component;
    
    /**
     * @author xiaobo
     * @Description UserConsumer
     * @createTime 2020-03-24 19:59
     */
    @Component
    // topic:主题   pitch_groups:组    ConsumeMode.ORDERLY: 一个队列对应一个线程  consumeThreadMax:消费者最大线程为1
    @RocketMQMessageListener(topic = "my_topic", consumerGroup = "pitch_groups"
            , consumeMode = ConsumeMode.ORDERLY, consumeThreadMax = 1)
    public class UserConsumer  implements RocketMQListener<MessageExt> {
        @Override
        public void onMessage(MessageExt m) {
            String result = new String(m.getBody());
            System.out.println("线程:"+Thread.currentThread().getName()+"--队列:"+m.getQueueId()+"--消息:"+result);
        }
    
    }
    

     
  3. 结果 
     
     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值