RocketMQ开发模型

2、RocketMQ的编程模型然后RocketMQ的生产者和消费者的编程模型都是有个比较固定的步骤的,掌握这个固定的步骤,对于我们学习源码以及以后使用都是很有帮助的。消息发送者的固定步骤1.创建消息生产者producer,并制定生产者组名2.指定Nameserver地址3.启动producer4.创建消息对象,指定主题Topic、Tag和消息体5.发送消息6.关闭生产者producer消息消费者的固定步骤1.创建消费者Consumer,制定消费者组名2.指定Nameserver地址3.订阅主题Topic和Tag4.设置回调函数,处理消息5.启动消费者consumer

3、RocketMQ的消息样例那我们来逐一连接下RocketMQ都支持哪些类型的消息:3.1 基本样例基本样例部分我们使用消息生产者分别通过三种方式发送消息,同步发送、异步发送以及单向发送。然后使用消费者来消费这些消息。1、同步发送消息的样例见:org.apache.rocketmq.example.simple.Producer等待消息返回后再继续进行下面的操作。2、异步发送消息的样例见:org.apache.rocketmq.example.simple.AsyncProducer这个示例有个比较有趣的地方就是引入了一个countDownLatch来保证所有消息回调方法都执行完了再关闭Producer。所以从这里可以看出,RocketMQ的Producer也是一个服务端,在往Broker发送消息的时候也要作为服务端提供服务

关键点就是使用producer.sendOneWay方式来发送消息,这个方法没有返回值,也没有回调。就是只管把消息发出去就行了。4、使用消费者消费消息。消费者消费消息有两种模式,一种是消费者主动去Broker上拉取消息的拉模式,另一种是消费者等待Broker把消息推送过来的推模式。拉模式的样例见:org.apache.rocketmq.example.simple.PullConsumer推模式的样例见:org.apache.rocketmq.example.simple.PushConsumer通常情况下,用推模式比较简单。实际上RocketMQ的推模式也是由拉模式封装出来的。4.7.1版本中DefaultMQPullConsumerImpl这个消费者类已标记为过期,但是还是可以使用的。替换的类是DefaultLitePullConsumerImpl。3.2 顺序消息顺序消息生产者样例见:org.apache.rocketmq.example.order.Producer顺序消息消费者样例见:org.apache.rocketmq.example.order.Consumer验证时,可以启动多个Consumer实例,观察下每一个订单的消息分配以及每个订单下多个步骤的消费顺序。不管订单在多个Consumer实例之前是如何分配的,每个订单下的多条消息顺序都是固定从0~5的。RocketMQ保证的是消息的局部有序,而不是全局有序。先从控制台上看下List mqs是什么。再回看我们的样例,实际上,RocketMQ也只保证了每个OrderID的所有消息有序(发到了同一个queue),而并不能保证所有消息都有序。所以这就涉及到了RocketMQ消息有序的原理。要保证最终消费到的消息是有序的,需要从Producer、Broker、Consumer三个步骤都保证消息有序才行。producer.setNamesrvAddr(“localhost:9876”);//Launchtheinstance.producer.start();for(inti=0;i<100;i++){//Createamessageinstance,specifyingtopic,tagandmessagebody.Messagemsg=newMessage(“TopicTest”/Topic/,“TagA”/Tag/,(“HelloRocketMQ”+i).getBytes(RemotingHelper.DEFAULT_CHARSET)/Messagebody/);//Callsendmessagetodelivermessagetooneofbrokers.producer.sendOneway(msg);}//WaitforsendingtocompleteThread.sleep(5000);producer.shutdown();}}67891011121314151617181920212223
首先在发送者端:在默认情况下,消息发送者会采取Round Robin轮询方式把消息发送到不同的MessageQueue(分区队列),而消费者消费的时候也从多个MessageQueue上拉取消息,这种情况下消息是不能保证顺序的。而只有当一组有序的消息发送到同一个MessageQueue上时,才能利用MessageQueue先进先出的特性保证这一组消息有序。而Broker中一个队列内的消息是可以保证有序的。然后在消费者端:消费者会从多个消息队列上去拿消息。这时虽然每个消息队列上的消息是有序的,但是多个队列之间的消息仍然是乱序的。消费者端要保证消息有序,就需要按队列一个一个来取消息,即取完一个队列的消息后,再去取下一个队列的消息。而给consumer注入的MessageListenerOrderly对象,在RocketMQ内部就会通过锁队列的方式保证消息是一个一个队列来取的。MessageListenerConcurrently这个消息监听器则不会锁队列,每次都是从多个Message中取一批数据(默认不超过32条)。因此也无法保证消息有序。3.3 广播消息广播消息的消息生产者样例见:org.apache.rocketmq.example.broadcast.PushConsumer广播消息并没有特定的消息消费者样例,这是因为这涉及到消费者的集群消费模式。在集群状态(MessageModel.CLUSTERING)下,每一条消息只会被同一个消费者组中的一个实例消费到(这跟kafka和rabbitMQ的集群模式是一样的)。而广播模式则是把消息发给了所有订阅了对应主题的消费者,而不管消费者是不是同一个消费者组

开源版本的RocketMQ中,对延迟消息并不支持任意时间的延迟设定(商业版本中支持),而是只支持18个固定的延迟级别,1到18分别对应messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m6m 7m 8m 9m 10m 20m 30m 1h 2h。这从哪里看出来的?其实从rocketmq-console控制台就能看出来。而这18个延迟级别也支持自行定义,不过一般情况下最好不要自定义修改。那这么好用的延迟消息是怎么实现的?这18个延迟级别除了在延迟消息中用,还有什么地方用到了?别急,我们会在后面部分进行详细讲解。3.5 批量消息批量消息是指将多条消息合并成一个批量消息,一次发送出去。这样的好处是可以减少网络IO,提升吞吐量。批量消息的消息生产者样例见:org.apache.rocketmq.example.batch.SimpleBatchProducer和org.apache.rocketmq.example.batch.SplitBatchProducer相信大家在官网以及测试代码中都看到了关键的注释:如果批量消息大于1MB就不要用一个批次发送,而要拆分成多个批次消息发送。也就是说,一个批次消息的大小不要超过1MB实际使用时,这个1MB的限制可以稍微扩大点,实际最大的限制是4194304字节,大概4MB。但是使用批量消息时,这个消息长度确实是必须考虑的一个问题。而且批量消息的使用是有一定限制的,这些消息应该有相同的Topic,相同的waitStoreMsgOK。而且不能是延迟消息、事务消息等。3.6 过滤消息在大多数情况下,可以使用Message的Tag属性来简单快速的过滤信息。使用Tag过滤消息的消息生产者案例见:org.apache.rocketmq.example.filter.TagFilterProducer使用Tag过滤消息的消息消费者案例见:org.apache.rocketmq.example.filter.TagFilterConsumer主要是看消息消费者。consumer.subscribe(“TagFilterTest”, “TagA || TagC”); 这句只订阅TagA和TagC的消息。TAG是RocketMQ中特有的一个消息属性。RocketMQ的最佳实践中就建议,使用RocketMQ时,一个应用可以就用一个Topic,而应用中的不同业务就用TAG来区分。但是,这种方式有一个很大的限制,就是一个消息只能有一个TAG,这在一些比较复杂的场景就有点不足了。这时候,可以使用SQL表达式来对消息进行过滤。SQL过滤的消息生产者案例见:org.apache.rocketmq.example.filter.SqlFilterProducerSQL过滤的消息消费者案例见:org.apache.rocketmq.example.filter.SqlFilterConsumer这个模式的关键是在消费者端使用MessageSelector.bySql(String sql)返回的一个MessageSelector。这里面的sql语句是按照SQL92标准来执行的。sql中可以使用的参数有默认的TAGS和一个在生产者中加入的a属性。SQL92语法:RocketMQ只定义了一些基本语法来支持这个特性。你也可以很容易地扩展它。数值比较,比如:>,>=,<,<=,BETWEEN,=;字符比较,比如:=,<>,IN;IS NULL或者IS NOT NULL;逻辑符号AND,OR,NOT;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术学习分享

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值