網(wǎng)上購物網(wǎng)站開發(fā)英文文獻(xiàn)南寧整合推廣公司
目錄
- 一、為什么需要消息序列化?
- 二、常用的消息序列化方式
- 1)Java原生序列化(默認(rèn))
- 2)JSON格式
- 3)Protobuf 格式
- 4)Avro 格式
- 5)MessagePack 格式
- 三、總結(jié)
RabbitMQ
是一個強(qiáng)大的消息中間件,廣泛應(yīng)用于 分布式系統(tǒng) 中。在使用 RabbitMQ 時,選擇 合適的方式來序列化 消息可以提高:性能
、可靠性
、擴(kuò)展性
。
一、為什么需要消息序列化?
在使用 RabbitMQ 時,消息需要在生產(chǎn)者和消費(fèi)者之間進(jìn)行傳遞。由于網(wǎng)絡(luò)通信只能傳輸二進(jìn)制數(shù)據(jù),因此需要對消息進(jìn)行 序列化
(將對象轉(zhuǎn)換為二進(jìn)制數(shù)據(jù))和反序列化
(將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換回對象)。這樣才能實(shí)現(xiàn)生產(chǎn)者與消費(fèi)者之間的無縫通信。
消息序列化的目標(biāo)是:將對象轉(zhuǎn)換為字節(jié)流。以便于在網(wǎng)絡(luò)上進(jìn)行傳輸。在選擇序列化方式時,我們 需要考慮以下因素:
- 性能: 序列化和反序列化的效率直接 影響消息傳輸?shù)乃俣群脱舆t。
- 空間開銷: 序列化后的字節(jié)流大小會 影響網(wǎng)絡(luò)帶寬的利用 和 存儲空間的占用。
- 可讀性: 序列化后的字節(jié)流是否 易于解析和理解,方便調(diào)試和維護(hù)。
- 兼容性: 序列化方式是否 支持不同的編程語言 和 版本之間的交互。
二、常用的消息序列化方式
RabbitMQ
本身不直接處理消息內(nèi)容的序列化,它主要負(fù)責(zé)消息的路由、存儲和傳遞。當(dāng)發(fā)送或接收消息時,客戶端庫(如:Java 中的 RabbitTemplate
或 Spring AMQP
框架)會根據(jù)內(nèi)部配置或默認(rèn)設(shè)置來決定如何對消息體進(jìn)行序列和反序列化。
1)Java原生序列化(默認(rèn))
- Java 自帶的 Serializable 接口和
ObjectOutputStream
/ObjectInputStream
可以將對象轉(zhuǎn)換為字節(jié)數(shù)組進(jìn)行傳輸。在Java Spring AMQP
中,默認(rèn)的消息序列化方式就是 Java 原生序列化。
優(yōu)點(diǎn):
- 簡單易用: Java 內(nèi)置支持,只需讓需要序列化的類實(shí)現(xiàn) Serializable 接口即可。
缺點(diǎn):
- 效率低: 生成的數(shù)據(jù)流可能比 JSON、Protocol Buffers 等二進(jìn)制格式更大,導(dǎo)致存儲和傳輸效率低。
- 安全風(fēng)險: 由于序列化機(jī)制中包含了類的信息,存在安全風(fēng)險,如:惡意攻擊者可以構(gòu)造特殊序列化數(shù)據(jù)以執(zhí)行任意代碼(例如通過 readObject 方法的重寫)。
- 語言獨(dú)立性差: Java 原生序列化只適用于 Java 環(huán)境,不便于與其他編程語言間的通信。
為了克服這些限制并提供更好的性能和互操作性,開發(fā)者通常會選擇更現(xiàn)代和靈活的方式,如 JSON
或 Protobuf
等。
2)JSON格式
JSON
(JavaScript Object Notation):是一種輕量級的數(shù)據(jù)交換格式,易于閱讀和編寫。它以鍵值對的形式表示數(shù)據(jù),并且在不同的編程語言中都有廣泛的支持。
優(yōu)點(diǎn):
- 易于使用和調(diào)試。
- 兼容性好,支持不同編程語言和版本之間的交互。
缺點(diǎn):
- 性能較差,相比其他序列化方式,JSON 的序列化和反序列化速度較慢。
- 字節(jié)流相對較大,占用網(wǎng)絡(luò)帶寬較多。
在 Spring AMQP 中,可以配置 MessageConverter 來替換默認(rèn)的序列化器,例如使用 Jackson 庫提供的 Jackson2JsonMessageConverter 將消息轉(zhuǎn)換為 JSON 格式。
Spring Boot 可以通過以下方式更改默認(rèn)的消息序列化策略:
spring:rabbitmq:message-converter: org.springframework.amqp.support.converter.Jackson2JsonMessageConverter
或者在 Java 配置類中定義:
@Bean
public MessageConverter jsonMessageConverter() {return new Jackson2JsonMessageConverter();
}@Autowired
public void configureRabbitTemplate(RabbitTemplate rabbitTemplate) {rabbitTemplate.setMessageConverter(jsonMessageConverter());
}
這樣,消息體就會被自動轉(zhuǎn)換成 JSON 字符串發(fā)送到 RabbitMQ,并在接收端反序列化回對應(yīng)的 Java 對象。
補(bǔ)充:
如果對象中使用了 LocalDateTime,在反序列化的時候會報錯:InvalidDefinitionException: Cannot construct instance of java.time.LocalDateTime
(no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
解決方式:
- 首先,需要引入
jackson-datatype
依賴,如果之前已經(jīng)引入了spring-boot-starter-web
依賴則不需要手動添加。
<!-- LocalDateTime反序列化 -->
<dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-jsr310</artifactId><version>2.4.0</version>
</dependency>
- 需要在 LocalDateTime 類型的字段上面添加
@JsonDeserialize
注解和@JsonSerialize
注解來指定如何序列化和反序列化java.time.LocalDateTime類型的數(shù)據(jù),如下所示:
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
補(bǔ)充: 上述代碼中,@JsonFormat
注解是完善顯示形式。
使用
@JsonFormat
注解前:
使用
@JsonFormat
注解后:
3)Protobuf 格式
Protobuf
(Protocol Buffers)是 Google 開發(fā)的一種高效的數(shù)據(jù)序列化格式。它以 二進(jìn)制格式 存儲數(shù)據(jù),可以通過定義消息結(jié)構(gòu)和 IDL(Interface Description Language)文件來實(shí)現(xiàn)消息的序列化和反序列化。
優(yōu)點(diǎn):
- 高性能,比 JSON 和 XML 等方式更快速和高效。
- 字節(jié)流較小,占用網(wǎng)絡(luò)帶寬和存儲空間較小。
缺點(diǎn):
- 由于二進(jìn)制格式存儲,不易讀和調(diào)試。
4)Avro 格式
Avro
是一種基于 Schema 的數(shù)據(jù)序列化系統(tǒng),由 Apache 開發(fā)。Avro 使用簡單的動態(tài) Schema 來定義消息格式,并支持多種編程語言。它具有高效的壓縮和快速的序列化/反序列化性能。
優(yōu)點(diǎn):
- 高性能,支持快速的序列化和反序列化。
- 字節(jié)流小,占用網(wǎng)絡(luò)帶寬和存儲空間較小。
缺點(diǎn):
- Schema 管理較為復(fù)雜,需要定義并維護(hù) Schema。
5)MessagePack 格式
MessagePack
是一種快速、緊湊且可讀寫的二進(jìn)制序列化格式。它以鍵值對的形式表示數(shù)據(jù),并支持多種編程語言。MessagePack的主要目標(biāo)是提供高性能的序列化和反序列化。
優(yōu)點(diǎn):
- 高性能,比 JSON 和 XML 等方式更快速和高效。
- 字節(jié)流較小,占用網(wǎng)絡(luò)帶寬和存儲空間較小。
缺點(diǎn):
- 不易讀和調(diào)試。
三、總結(jié)
RabbitMQ消息序列化
是構(gòu)建 分布式系統(tǒng) 的關(guān)鍵環(huán)節(jié)之一。在選擇序列化方式時,需要綜合考慮性能、空間開銷、可讀性和兼容性等因素。根據(jù)具體需求 選擇合適的序列化方式,并遵循最佳時間,可以提高系統(tǒng)的性能、可靠性和擴(kuò)展性。通過測試、優(yōu)化和監(jiān)控,不斷改進(jìn)序列化方案,使其更好地 適應(yīng)實(shí)際應(yīng)用場景。
整理完畢,完結(jié)撒花~ 🌻
參考地址:
1.Spring boot使用Rabbitmq注解及消息序列化,https://blog.csdn.net/cristianoxm/article/details/114883340
2.RabbitMQ消息序列化的終極指南,https://baijiahao.baidu.com/s?id=1773630009654004953&wfr=spider&for=pc