簡體   English   中英

在 kafka-avro-console-consumer 中檢索 Avro 架構時出現錯誤 40101

[英]Error 40101 when retrieving Avro schema in kafka-avro-console-consumer

嘗試使用 Confluent Platform CLI 工具從 Kafka 讀取消息時出現以下錯誤。

[2023-01-17T18:00:14.960189+0100] [2023-01-17 18:00:14,957] ERROR Unknown error when running consumer:  (kafka.tools.ConsoleConsumer$:105)
[2023-01-17T18:00:14.960210+0100] org.apache.kafka.common.errors.SerializationException: Error retrieving Avro schema for id 119
[2023-01-17T18:00:14.960230+0100] Caused by: io.confluent.kafka.schemaregistry.client.rest.exceptions.RestClientException: Unauthorized; error code: 40101
[2023-01-17T18:00:14.960249+0100]   at io.confluent.kafka.schemaregistry.client.rest.RestService.sendHttpRequest(RestService.java:170)
[2023-01-17T18:00:14.960272+0100]   at io.confluent.kafka.schemaregistry.client.rest.RestService.httpRequest(RestService.java:188)
[2023-01-17T18:00:14.960293+0100]   at io.confluent.kafka.schemaregistry.client.rest.RestService.getId(RestService.java:330)
[2023-01-17T18:00:14.960312+0100]   at io.confluent.kafka.schemaregistry.client.rest.RestService.getId(RestService.java:323)
[2023-01-17T18:00:14.960332+0100]   at io.confluent.kafka.schemaregistry.client.CachedSchemaRegistryClient.getSchemaByIdFromRegistry(CachedSchemaRegistryClient.java:63)
[2023-01-17T18:00:14.960353+0100]   at io.confluent.kafka.schemaregistry.client.CachedSchemaRegistryClient.getBySubjectAndID(CachedSchemaRegistryClient.java:118)
[2023-01-17T18:00:14.960372+0100]   at io.confluent.kafka.serializers.AbstractKafkaAvroDeserializer.deserialize(AbstractKafkaAvroDeserializer.java:121)
[2023-01-17T18:00:14.960391+0100]   at io.confluent.kafka.serializers.AbstractKafkaAvroDeserializer.deserialize(AbstractKafkaAvroDeserializer.java:92)
[2023-01-17T18:00:14.960412+0100]   at io.confluent.kafka.formatter.AvroMessageFormatter.writeTo(AvroMessageFormatter.java:120)
[2023-01-17T18:00:14.960431+0100]   at io.confluent.kafka.formatter.AvroMessageFormatter.writeTo(AvroMessageFormatter.java:112)
[2023-01-17T18:00:14.960449+0100]   at kafka.tools.ConsoleConsumer$.process(ConsoleConsumer.scala:137)
[2023-01-17T18:00:14.960468+0100]   at kafka.tools.ConsoleConsumer$.run(ConsoleConsumer.scala:75)
[2023-01-17T18:00:14.960487+0100]   at kafka.tools.ConsoleConsumer$.main(ConsoleConsumer.scala:50)
[2023-01-17T18:00:14.960506+0100]   at kafka.tools.ConsoleConsumer.main(ConsoleConsumer.scala)

我正在使用 Kafka 3.2(客戶端和服務器),以及 Aiven 的 Karapace 模式注冊表。 我可以通過在 URL 中包含憑據,使用curl手動查詢架構注冊表:

(base) me@my-laptop:~$ curl https://$SCHEMA_REGISTRY_USER:$SCHEMA_REGISTRY_PASSWORD@$SCHEMA_REGISTRY_HOST:$SCHEMA_REGISTRY_PORT/subjects
["my-topic-" <redacted>

或者作為 header 中的基本身份驗證:

(base) me@my-laptop:~$ curl -u "$SCHEMA_REGISTRY_USER:$SCHEMA_REGISTRY_PASSWORD" https://$SCHEMA_REGISTRY_HOST:$SCHEMA_REGISTRY_PORT/subjects
["my-topic-" <redacted>

當憑證未傳遞到架構注冊表時,似乎會發生錯誤:

(base) me@my-laptop:~$ curl https://$SCHEMA_REGISTRY_HOST:$SCHEMA_REGISTRY_PORT/subjects
{"error_code": 40101, "message": "Unauthorized"}

根據kafka-avro-console-consumer官方文檔,我可以使用身份驗證源URLUSER_INFO ,它應該將這些憑據傳遞給架構注冊表。 這不起作用,並導致上述錯誤。

kafka-avro-console-consumer \
          --bootstrap-server $KAFKA_HOST:$KAFKA_PORT \
          --consumer.config /home/guido/.tls/kafka/client-tls.properties \
          --property schema.registry.url=https://$SCHEMA_REGISTRY_USER:$SCHEMA_REGISTRY_PASSWORD@$SCHEMA_REGISTRY_HOST:$SCHEMA_REGISTRY_PORT \
          --property basic.auth.credentials.source=URL \
          --topic my-topic

我已經嘗試了我能想到的每一種組合,URL,USER_INFO,單獨的憑據,前綴為schema.registry和沒有,但都會導致相同的錯誤。 當我使用常規的kafka-console-consumer.sh時,相同的設置起作用,但我看到 Kafka 消息是字節 stream,而不是我正在尋找的反序列化 Avro 消息。

編輯:問題似乎出在 java.net.HttpURLConnection 上。 它從 URL 中剝離憑證,並且與 Confluent Platform 打包的 schema-registry-client 版本不支持任何其他版本的基本身份驗證。

import java.net.URL
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class ExampleTest extends AnyFlatSpec with Matchers {
  
  behavior.of("Example")

  it should "work" in {
    val url = "https://username:p4ssw0rd@kafka.example.com:12345"

    val connection = new URL(url).openConnection()

    noException shouldBe thrownBy {
      connection.getInputStream
    }
  }
}

測試失敗

找到了。 我的問題有三個原因。

  1. 我安裝了舊版本的 Confluent Platform,即confluent-platform-2.11 除了 URL 中的用戶名和密碼外,此版本尚不支持任何模式注冊表身份驗證。
  2. 我以為我已經有了最新版本 (3.3.x) 但那實際上是 Kafka 的最新版本,而不是 Confluent Platform 的最新版本。
  3. Java 的默認 web 請求實現sun.net.www.protocol.http.HttpURLConnection不支持 URL 中的憑據。盡管 URL 正確包含憑據,但在發出請求之前它們會被剝離。

正確的解決方案是升級到更高版本的 Confluent Platform。

參見https://docs.confluent.io/platform/current/installation/installing_cp/deb-ubuntu.html#configure-cp

暫無
暫無

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

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