RocketMQ消息发送及消费

1 消息发送

生产者向消息队列里写入消息,不同的业务场景需要生产者采用不同的写入策略。比如同步发送、异步发送、Oneway发送、延迟发送、发送事务消息等。默认使用的是DefaultMQProducer类,发送消息要经过五个步骤:

1)设置Producer的GroupName。

2)设置InstanceName,当一个vm需要启动多个Producer的时候,通过设置不同的InstanceName来区分,不设置的话系统使用默认名称"DEFAULT"。

3)设置发送失败重试次数,当网络出现异常的时候,这个次数影响消息的重复投递次数。想保证不丢消息,可以设置多重试几次。

4)设置NameServer地址

5)组装消息并发送。

消息发生返回状态(SendResult#SendStatus) 有如下四种:

FLUSH_DISK_TIMEOUT

FLUSH_SL AVE_TIMEOUT

SLAVE_NOT_ AVAILABLE

SEND_OK

不同状态在不同的刷盘策略和同步策略的配置下含义是不同的:

(1)FLUSH DISK TIMEOUT:表示没有在规定时间内完成刷盘(需要Broker的刷盘策略被设置成

SYNC_ FLUSH才会报这个错误)。

(2)FLUSH _SLAVE TIMEOUT:表示在主备方式下,并且Broker被设置成SYNC. MASTER方式,没有在设定时间内完成主从同步。

(3) SLAVE_NOT_AVAILABLE:这个状态产生的场景和FLUSH_SLAVE_TIMEOUT类似,表示在主备方式下,并且Broker被设置成SYNC_MASTER,但是没有找到被配置成Slave的Broker。

(4)SEND_OK:表示发送成功,发送成功的具体含义,比如消息是否已经被存储到磁盘?消息是否被同步到了Slave上?消息在Slave上是否被写入磁盘?需要结合所配置的刷盘策略、主从策略来定。这个状态还可以简单理解为,没有发生上面列出的三个问题状态就是SEND_OK。

写一个高质量的生产者程序,重点在于对发送结果的处理,要充分考虑各种异常,写清对应的处理逻辑。

提升写入的性能

发送条消息出去要经过三步

(1)客户端发送请求到服务器。

(2)服务器处理该请求。

(3)服务器向客户端返回应答

一次消息的发送耗时是上述三个步骤的总和。

在一些对速度要求高,但是可靠性要求不高的场景下,比如日志收集类应用,可以采用Oneway方式发送

Oneway方式只发送请求不等待应答,即将数据写入客户端的Socket缓冲区就返回,不等待对方返回结果。

用这种方式发送消息的耗时可以缩短到微秒级。

另一种提高发送速度的方法是增加Producer的并发量,使用多个Producer同时发送,我们不用担心多Producer同时写会降低消息写磁盘的效率,RocketMQ引入了一个并发窗口,在窗口内消息可以并发地写入DirectMem中,然后异步地将连续一段无空洞的数据刷入文件系统当中。

顺序写CommitLog可让RocketMQ无论在HDD还是SSD磁盘情况下都能保持较高的写入性能。

目前在阿里内部经过调优的服务器上,写入性能达到90万+的TPS,我们可以参考这个数据进行系统优化。

在Linux操作系统层级进行调优,推荐使用EXT4文件系统,IO调度算法使用deadline算法。

2 消息消费

简单总结消费的几个要点:

(1)消息消费方式(Pull和Push)

(2)消息消费的模式(广播模式和集群模式)

(3)流量控制(可以结合sentinel来实现)

(4)并发线程数设置

(5)消息的过滤(Tag、Key) TagA| |TagB | |TagC * null

当Consumer的处理速度跟不上消息的产生速度,会造成越来越多的消息积压,这个时候首先查看消费逻辑本身有没有优化空间,除此之外还有3种方法可以提高Consumer的处理能力。

(1)提高消费并行度

在同一个ConsumerGroup下(Clustering方式),可以通过增加Consumer实例的数量来提高并行度。

通过加机器,或者在已有机器中启动多个Consumer进程都可以增加Consumer实例数。

注意:总的Consumer数量不要超过Topic下Read Queue数量,超过的Consumer实例接收不到消息。

此外,通过提高单个Consumer实例中的并行处理的线程数,可以在同一个Consumer内加并行度来提高吞吐量(设置方法是修改consumeThreadMin和consumeThreadMax)。

(2)以批量方式进行消费

某些业务场景下,多条消息同时处理的时间会大大小于逐个处理的时间总和,比如消费消息中涉及update某个数据库,一次update10条的时间会大大小于十次update1条数据的时间。

可以通过批量方式消费来提高消费的吞吐量。实现方法是设置Consumer的consumeMessageBatchMaxSize这个参数,默认是1,如果设置为N,在消息多的时候每次收到的是个长度为N的消息链表。

(3)检测延时情况,跳过非重要消息

Consumer在消费的过程中,如果发现由于某种原因发生严重的消息堆积,短时间无法消除堆积,这个时候可以选择丢弃不重要的消息,使Consumer尽快追上Producer的进度。

你可能感兴趣的:(中间件,java-rocketmq,rocketmq,java)