簡體   English   中英

由於模式類型錯誤(JSON 而不是 AVRO),Pulsar 函數無法反序列化消息

[英]Pulsar function fails to deserialize message because of wrong schema type (JSON instead of AVRO)

當在 docker 中獨立運行 Pulsar 時,在特定情況下反序列化消息時,我們會面臨這個奇怪的問題。 我們使用的是 2.7.1 版。

我們有一個創建主題和函數的腳本,然后為 JSON 類型的麻煩主題創建模式。 整個模式是正確的,但類型不是。 這是發送任何消息之前的全部內容。 我們還啟用了set-is-allow-auto-update-schema

我們稱之為trouble-topic ,它由 2 個來源填充: ValidationFunction和 Spring Boot 微服務。

ValidationFunction驗證消息,如果消息有效,則將映射的消息發送到 Spring Boot 微服務使用的主題,然后在其上執行一些邏輯並將其發送到trouble-topic ,但如果驗證失敗,則直接向trouble-topic發送消息trouble-topic

當使用 Spring Boot 微服務的sendAsync和以下生產者時,模式會更新,將 AVRO 作為類型,並且TroubleFunction讀取trouble-topic之后工作正常:

pulsarClient
    .newProducer(AvroSchema.of(OurClass.class))
    .topic(troubleTopicName))
    .create()

但是如果在此之前一些消息驗證失敗,並且在使用上述 Producer 之前將消息直接發送到trouble-topic ,我們會得到解析異常。 我們通過以下方式從函數發送消息:

context.newOutputMessage(troubleTopicName, AvroSchema.of(OurClass.class))
    .value(value)
    .sendAsync();

由於某種原因,這不會更新架構類型,並且架構類型仍然是 JSON。 我使用 pulsar admin CLI 驗證了每個步驟的模式類型。 當這種情況發生在微服務生產者第一次更新模式類型之前, TroubleFunction讀取trouble-topic失敗並出現以下錯誤:

11:43:49.322 [tenant/namespace/TroubleFunction-0] ERROR org.apache.pulsar.functions.instance.JavaInstanceRunnable - [tenant/namespace/TroubleFunction:0] Uncaught exception in Java Instance
org.apache.pulsar.client.api.SchemaSerializationException: com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 2)): only regular white space (\r, \n, \t) is allowed between tokens
 at [Source: (byte[])avro-serialized-msg-i-have-to-hide Parsing exception: cvc-complex-type.2.4.a: Invalid content was found starting with element 'ElementName'. One of '{"foo:bar":ElementName}' is expected."; line: 1, column: 2]

所以我的問題是這兩者之間有什么區別,為什么從函數發送消息沒有正確更新架構類型? 下面不是使用同一個Producer嗎? 還有沒有辦法解決這個問題,以便在初始化時設置模式類型或至少在從函數發送消息時更新?

首先,信用到期的信用。 我想有一天這會被很好地記錄下來,但現在不是。 我很幸運有一個 EAP 版本的 Apache Pulsar in Action 書,這個示例存儲庫用於展示一些 Pulsar 功能: https : //github.com/david-streamlio/GottaEat

我強烈推薦這本書,並為每個與 Pulsar 一起工作的人閱讀這些例子,在 pulsar slack 社區上有人提到它昨天剛從 MEAP 畢業,它應該很快就會有印刷版,所以看看吧。 也可以考慮加入 Pulsar slack。


回答:

這是一段代碼,讓我了解它應該如何工作:

Map<String, ConsumerConfig> inputSpecs = new HashMap<String, ConsumerConfig> ();
inputSpecs.put("persistent://orders/inbound/food-orders", 
    ConsumerConfig.builder().schemaType("avro").build());
FunctionConfig functionConfig = 
    FunctionConfig.builder()
        ...
        .inputSpecs(inputSpecs)
        ...
        .build();

使用LocalRunner時可以使用Java代碼來設置該功能,但使用pulsar admin cli(我們使用的)和rest api可以實現相同的配置。 您也可以使用函數配置文件,並在配置 yaml 中按以下方式指定它:

inputSpecs:
 $topicName:
  schemaType: AVRO

$topicName始終采用以下格式: persistent://tenant/namespace/topic

一旦您為TroubleFunction指定輸入規范,將使用正確的模式類型有效地創建模式,反序列化也將正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM