对于我们开发人员和系统管理员来说,压缩传输中的数据是提高应用程序性能的一个微不足道的方法。如今,我们的大部分网络流量都经过了压缩,尤其是在涉及网络浏览器的情况下,因为网页的大部分内容或多或少都符合压缩条件。
然而,我们通常会忽略其他一些不太明显的使用案例,比如微服务之间的数据交换,例如使用消息代理。在本文中,我将以 RabbitMQ 为例重点介绍这一点。在这个概念验证中,我还使用了 Spring,以充分利用其强大的简洁性。
为什么要压缩?
压缩通过报文代理发送的报文似乎有违直觉:报文通常是通过高速网络链接发送的,何必呢?关于网络速度,你可能是对的,而且整个想法可能只对那些通过互联网使用消息代理的人有用,但你仍然应该考虑这种方法:这是一种低成本的方法。
只需花费一些用于压缩的 CPU 周期,你就能获得以下好处:
- 提高带宽使用率:优化网络利用率非常重要,尤其是在多个微服务频繁通信的情况下
- 缩短传输时间:即使在高速网络上,较小的有效负载也能加快传输速度。这有助于提高整体性能,减少微服务通信的延迟。
- 降低延迟:压缩有效载荷有助于缩短数据在微服务之间的传输时间,从而提高系统的响应速度。
- 可扩展性:压缩有效载荷可以优化资源利用率,最大限度地减少网络瓶颈,从而提高微服务架构的可扩展性,使系统能够更高效地处理不断增加的负载。
哦,关于 CPU 成本:Deflate 算法对 CPU 的要求很低,你还可以配置压缩级别,并根据自己的需要进行调整。
权衡
在大多数工程学科中,我们都会不断地进行权衡,这也不例外。如前所述,由于优化了压缩算法,CPU 的开销大多微不足道。那么,下一个问题就是:需要花费多少精力?需要花费多少精力?
得益于 Spring 框架,并不需要太多!只需一个带有 MessageConverter 的 RabbitTemplate 即可。
如何压缩
以我的参考实现 RabbitZip 为例,假设您已经拥有一个使用标准 RabbitTemplate 的 Spring Boot 应用程序(我稍后将解释 @Primary 注解):
@Bean
@Primary
RabbitTemplate template(ConnectionFactory connectionFactory) {
return new RabbitTemplate(connectionFactory);
}
现在,让我们创建另一个 RabbiTemplate,它将为我们压缩其有效载荷:
@Bean("compressed")
RabbitTemplate compressedTemplate(
ConnectionFactory connectionFactory,
CompressedMessageConverter compressedMessageConverter) {
final RabbitTemplate rabbitTemplate =
new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(compressedMessageConverter);
return rabbitTemplate;
有两点不同: 我们使用限定符(压缩)来区分此 RabbitTemplate,而且还使用了 MessageConverter。CompressedMessageConverter 的实现非常简单。它主要是压缩消息有效载荷,并添加消息头 Use-Gzip。这部分在反序列化有效负载时非常重要,因为我们需要知道何时需要在反序列化前对消息进行解压缩。
一旦实施到位,使用起来就更容易了:
- 要发送压缩消息,您只需注入 RabbitTemplate 限定的 compressed,然后像往常一样发送消息即可。我们需要在默认 RabbitTemplate 上使用 @Primary 注解,以便任何不使用限定符的现有注入点仍能正常工作。
- 在 @RabbitListener 一侧,您只需定义 messageConverter 属性
结论
在微服务通信中压缩消息(如使用 RabbitMQ 和 Spring)可显著提高性能,同时将开销降至最低。它可以优化带宽、加快传输速度、减少延迟并增强可扩展性。像 Deflate 这样的现代压缩算法是轻 CPU 算法。使用 Spring 的 RabbitTemplate 和 MessageConverter 实现这一功能非常简单,可为微服务架构提供高影响、低成本的优化。
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/47761.html