前面已经讲了消息是怎么发送给broker的,那broker接收到消息后,是怎么处理的?
为了保证消息不丢失,RocketMQ会把消息进行持久化,也就是说,会把消息写入commitlog的日志,这个目录是在store下面。每个日志大小为1G,所以commitlog会有多个磁盘文件,每个文件名是消息的物理偏移量。
当broker接收到消息的时候,首先会进行一些判断,比如只能master可以写入,Topic的长度限制为256个字符,消息属性长度限制为65536个字符等。
等验证通过后,开始进行写数据,由于可能存在并发问题,所以每次写的时候,都需要申请锁。
申请到锁后,开始往commitlog里写数据,如果是刚开始写入日志文件的时候,此时commitlog并没有文件,所以就会创建一个大小为1G名字为00000000000000000000的日志文件。如果已经存在多个日志文件,那直接取最后一个日志文件,因为日志文件写完才会创建一个新的日志文件,那最后一个日志文件就是当前需要写入的。
拿到日志文件后,我们需要将消息追加到这个文件里,此时需要知道当前文件的写指针,如果是刚创建的文件,那写指针就是0。
这个写指针是不能大于文件的大小,如果超过了,说明文件已写满,那是不能往里面写数据的。
另外一个还需要判断的是,当前消息是否够放这个文件,也就写指针+消息的长度(mq还会预留其他空间),是否会超过这个文件的大小,如果不会,就写入这个文件,如果会,那就会创建一个新的文件进行写入。
写入后,就更新上面的写指针,也就是说,最后的写指针就是当前写指针+消息的大小。最后释放锁,让其他线程进行写入。
其实到了这一个步骤,消息并没有写到磁盘上,还只是追加到内存,后续再来提刷屏的过程。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。