参数解析系列不会写太多,看到哪儿写到哪儿
根据RocketMQ3.2.4的开发手册定义,compressMsgBodyOverHowmuch 是指 “消息 Body 超过多大开始压缩(Consumer
收到消息会自动解压缩),单位字节”,默认是1024*4即4096
此参数在 FiltersrvConfig.java和DefaultMQProducer.java 中均有定义
前者是DefaultRequestProcessor.java调用 FiltersrvController时使用,后者是 DefaultMQProducerImpl.java使用。
DefaultMQProducerImpl.java
//org.apache.rocketmq.filtersrv.processor.DefaultRequestProcessor.java
private ByteBuffer messageToByteBuffer(final MessageExt msg) throws IOException {
int sysFlag = MessageSysFlag.clearCompressedFlag(msg.getSysFlag());
if (msg.getBody() != null) {
if (msg.getBody().length >= this.filtersrvController.getFiltersrvConfig().getCompressMsgBodyOverHowmuch()) {
byte[] data = UtilAll.compress(msg.getBody(), this.filtersrvController.getFiltersrvConfig().getZipCompressLevel());
if (data != null) {
msg.setBody(data);
sysFlag |= MessageSysFlag.COMPRESSED_FLAG;
}
}
}
//此方法还有代码未写完 略。。。
}
DefaultMQProducerImpl.java的调用
//org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.java
private boolean tryToCompressMessage(final Message msg) {
if (msg instanceof MessageBatch) {
//batch dose not support compressing right now
return false;
}
byte[] body = msg.getBody();
if (body != null) {
if (body.length >= this.defaultMQProducer.getCompressMsgBodyOverHowmuch()) {
try {
byte[] data = UtilAll.compress(body, zipCompressLevel);
if (data != null) {
msg.setBody(data);
return true;
}
} catch (IOException e) {
log.error("tryToCompressMessage exception", e);
log.warn(msg.toString());
}
}
}
return false;
}
由上可知 完成压缩消息的是
UtilAll.compress(final byte[] src, final int level)
方法
再看其定义
//org.apache.rocketmq.common.UtilAll.java
public static byte[] compress(final byte[] src, final int level) throws IOException {
byte[] result = src;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(src.length);
java.util.zip.Deflater defeater = new java.util.zip.Deflater(level);
DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream, defeater);
try {
deflaterOutputStream.write(src);
deflaterOutputStream.finish();
deflaterOutputStream.close();
result = byteArrayOutputStream.toByteArray();
} catch (IOException e) {
defeater.end();
throw e;
} finally {
try {
byteArrayOutputStream.close();
} catch (IOException ignored) {
}
defeater.end();
}
return result;
}
此处默认level=5(在FiltersrvConfig.java中有定义
综上所述,当配置参数compressMsgBodyOverHowmuch后,RocketMQ按照规则判定消息body大小时,使用 jdk自带的java.util.zip.Deflater 对body进行压缩处理。