MQ - 队列数据压缩
MQ - Data Compression on queue
问题:MQ7 有最大 100MB jms 消息的硬性限制。对于接近那个的大负载 ( xml ),是否可以在队列上对其进行压缩以缩短数据长度?
我尝试在 svr.def.conn 通道上使用 MQ ZLIB 压缩来压缩 7MB 的 jms 字符串消息,但它对 jms 消息的数据长度没有任何影响。我只设置了一个通道,并期望使用的通道会压缩进入队列的数据。
MQ 服务器:7.5
客户:JAVA
消息类型:字符串
通道级压缩用于压缩在通道两端之间传输的数据,在您的例子中是在 JMS 客户端和 MQ SVRCONN 通道之间。消息本身在通过网络传输时会被压缩,但在队列中时不会。
我建议压缩负载并使用 ByteMessage。消息属性可用于限定负载类型,类似于 HTTP,例如"Content-Encoding"、"Content-Type"
String payload = ...; // the xml
Session session = ...;
BytesMessage bytesMessage = session.createBytesMessage();
bytesMessage.writeBytes(compressGZIP(payload, StandardCharsets.UTF_8));
bytesMessage.setStringProperty("Content-Encoding", "gzip");
bytesMessage.setStringProperty("Content-Type", "text/xml; charset=utf-8");
这里是压缩GZIP的方法:
private byte[] compressGZIP(String string, Charset charset) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try (GZIPOutputStream out = new GZIPOutputStream(byteArrayOutputStream)) {
StringReader stringReader = new StringReader(string);
// IOUtils from apache commons-io
IOUtils.copy(stringReader, out, charset);
}
return byteArrayOutputStream.toByteArray();
}
消费者然后可以请求消息属性,根据 "Content-Encoding" 和 "Content-Type" 消息属性解压缩并重新创建 xml。
像这样
public void onMessage(Message message) {
BytesMessage bytesMessage = (BytesMessage) message;
long bodyLength = bytesMessage.getBodyLength();
byte[] rawPayload = new byte[(int) bodyLength];
InputStream payloadInputStream = new ByteArrayInputStream(rawPayload);
String contentEncoding = bytesMessage.getStringProperty("Content-Encoding");
if("gzip".equals(contentEncoding)) {
payloadInputStream = new GZIPInputStream(payloadInputStream);
}
String contentType = bytesMessage.getStringProperty("Content-Type");
MimeType mimeType = new MimeType(contentType); // from javax.activation
if("text".equals(mimeType.getPrimaryType())) {
if("xml".equals(mimeType.getSubType())) {
Charset charset;
String charsetString = mimeType.getParameter("charset");
if(charsetString != null) {
charset = Charset.forName(charsetString);
} else {
charset = StandardCharsets.UTF_8; // default
}
Reader reader = new InputStreamReader(payloadInputStream, charset);
String xml = IOUtils.toString(reader);
IOUtils.closeQuietly(reader);
}
}
}
此解决方案的优点是您可以使用标准 JMS api,而不是使用提供程序特定的配置。
缺点是发送方和接收方必须实现内容类型处理。
因此您必须在可移植性和实施工作之间做出决定。
问题:MQ7 有最大 100MB jms 消息的硬性限制。对于接近那个的大负载 ( xml ),是否可以在队列上对其进行压缩以缩短数据长度?
我尝试在 svr.def.conn 通道上使用 MQ ZLIB 压缩来压缩 7MB 的 jms 字符串消息,但它对 jms 消息的数据长度没有任何影响。我只设置了一个通道,并期望使用的通道会压缩进入队列的数据。
MQ 服务器:7.5 客户:JAVA 消息类型:字符串
通道级压缩用于压缩在通道两端之间传输的数据,在您的例子中是在 JMS 客户端和 MQ SVRCONN 通道之间。消息本身在通过网络传输时会被压缩,但在队列中时不会。
我建议压缩负载并使用 ByteMessage。消息属性可用于限定负载类型,类似于 HTTP,例如"Content-Encoding"、"Content-Type"
String payload = ...; // the xml
Session session = ...;
BytesMessage bytesMessage = session.createBytesMessage();
bytesMessage.writeBytes(compressGZIP(payload, StandardCharsets.UTF_8));
bytesMessage.setStringProperty("Content-Encoding", "gzip");
bytesMessage.setStringProperty("Content-Type", "text/xml; charset=utf-8");
这里是压缩GZIP的方法:
private byte[] compressGZIP(String string, Charset charset) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try (GZIPOutputStream out = new GZIPOutputStream(byteArrayOutputStream)) {
StringReader stringReader = new StringReader(string);
// IOUtils from apache commons-io
IOUtils.copy(stringReader, out, charset);
}
return byteArrayOutputStream.toByteArray();
}
消费者然后可以请求消息属性,根据 "Content-Encoding" 和 "Content-Type" 消息属性解压缩并重新创建 xml。
像这样
public void onMessage(Message message) {
BytesMessage bytesMessage = (BytesMessage) message;
long bodyLength = bytesMessage.getBodyLength();
byte[] rawPayload = new byte[(int) bodyLength];
InputStream payloadInputStream = new ByteArrayInputStream(rawPayload);
String contentEncoding = bytesMessage.getStringProperty("Content-Encoding");
if("gzip".equals(contentEncoding)) {
payloadInputStream = new GZIPInputStream(payloadInputStream);
}
String contentType = bytesMessage.getStringProperty("Content-Type");
MimeType mimeType = new MimeType(contentType); // from javax.activation
if("text".equals(mimeType.getPrimaryType())) {
if("xml".equals(mimeType.getSubType())) {
Charset charset;
String charsetString = mimeType.getParameter("charset");
if(charsetString != null) {
charset = Charset.forName(charsetString);
} else {
charset = StandardCharsets.UTF_8; // default
}
Reader reader = new InputStreamReader(payloadInputStream, charset);
String xml = IOUtils.toString(reader);
IOUtils.closeQuietly(reader);
}
}
}
此解决方案的优点是您可以使用标准 JMS api,而不是使用提供程序特定的配置。
缺点是发送方和接收方必须实现内容类型处理。
因此您必须在可移植性和实施工作之间做出决定。