You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot通过SSL连接Docker Kafka失败,求排查解决

Kafka SSL连接问题:SpringBoot应用连接失败但Offset Explorer正常

Docker Compose配置(启用SSL的Kafka集群)

version: '2'
services:
  zookeeper:
    image: confluentinc/cp-zookeeper:6.2.0
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
    ports:
      - 2181:2181
    volumes:
      - ./data/zookeeper/data:/data
      - ./data/zookeeper/datalog:/datalog
  kafka:
    image: confluentinc/cp-kafka:6.2.0
    depends_on:
      - zookeeper
    ports:
      - 9093:9093
      - 9092:9092
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:19092,SSL://localhost:9093
      KAFKA_SSL_CLIENT_AUTH: 'required'
      KAFKA_SSL_KEYSTORE_FILENAME: 'certs/server.keystore.jks'
      KAFKA_SSL_KEYSTORE_CREDENTIALS: 'certs/kafka_keystore_credentials'
      KAFKA_SSL_KEY_CREDENTIALS: 'certs/kafka_sslkey_credentials'
      KAFKA_SSL_TRUSTSTORE_FILENAME: 'certs/server.truststore.jks'
      KAFKA_SSL_TRUSTSTORE_CREDENTIALS: 'certs/kafka_truststore_credentials'
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'true'
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
    volumes:
      - ./certs:/etc/kafka/secrets/certs
      - ./data/kafka1/data:/var/lib/kafka/data

SpringBoot应用配置(application.yml)

server:
  port: 8888
spring:
  kafka:
    consumer:
      security:
        protocol: "SSL"
      bootstrap-servers: localhost:9093
      group-id: group-tenant2-id
      auto-offset-reset: earliest
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      ssl:
        trust-store-location: classpath:client.truststore.jks
        trust-store-password: test123


    producer:
      security:
        protocol: "SSL"
      bootstrap-servers: localhost:9093
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
      ssl:
        trust-store-location: classpath:client.truststore.jks
        trust-store-password: test123

报错信息

org.apache.kafka.common.errors.SslAuthenticationException: Failed to process post-handshake messages
Caused by: javax.net.ssl.SSLException: Tag mismatch!
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:133) ~[na:na]
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:370) ~[na:na]
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:313) ~[na:na]
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308) ~[na:na]
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:123) ~[na:na]
at java.base/sun.security.ssl.SSLEngineImpl.decode(SSLEngineImpl.java:736) ~[na:na]
at java.base/sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:691) ~[na:na]
at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:506) ~[na:na]
at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:482) ~[na:na]
at java.base/javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:679) ~[na:na]
at org.apache.kafka.common.network.SslTransportLayer.read(SslTransportLayer.java:569) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.common.network.NetworkReceive.readFrom(NetworkReceive.java:95) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.common.network.KafkaChannel.receive(KafkaChannel.java:452) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.common.network.KafkaChannel.read(KafkaChannel.java:402) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.common.network.Selector.attemptRead(Selector.java:674) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.common.network.Selector.pollSelectionKeys(Selector.java:576) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.common.network.Selector.poll(Selector.java:481) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:560) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:265) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:236) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:215) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.clients.consumer.internals.AbstractCoordinator.ensureCoordinatorReady(AbstractCoordinator.java:246) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.clients.consumer.internals.ConsumerCoordinator.coordinatorUnknownAndUnready(ConsumerCoordinator.java:459) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.clients.consumer.internals.ConsumerCoordinator.poll(ConsumerCoordinator.java:487) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.clients.consumer.KafkaConsumer.updateAssignmentMetadataIfNeeded(KafkaConsumer.java:1262) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1231) ~[kafka-clients-3.1.1.jar:na]
at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1211) ~[kafka-clients-3.1.1.jar:na]
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.pollConsumer(KafkaMessageListenerContainer.java:1529) ~[spring-kafka-2.8.8.jar:2.8.8]
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doPoll(KafkaMessageListenerContainer.java:1519) ~[spring-kafka-2.8.8.jar:2.8.8]
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.pollAndInvoke(KafkaMessageListenerContainer.java:1343) ~[spring-kafka-2.8.8.jar:2.8.8]
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.run(KafkaMessageListenerContainer.java:1255) ~[spring-kafka-2.8.8.jar:2.8.8]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[na:na]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

问题现象

Offset Explorer可正常通过SSL连接该Kafka集群:
Offset Explorer连接成功截图

解决方案

问题根源在于Kafka Broker配置了KAFKA_SSL_CLIENT_AUTH: 'required',要求客户端必须提供SSL证书完成双向认证,但当前SpringBoot配置仅配置了信任库(truststore),缺少客户端密钥库(keystore)的相关配置。

需要在SpringBoot的consumer和producer的ssl节点下添加以下配置:

key-store-location: classpath:client.keystore.jks
key-store-password: 你的密钥库密码
key-password: 你的密钥密码

修改后的完整配置示例:

spring:
  kafka:
    consumer:
      security:
        protocol: "SSL"
      bootstrap-servers: localhost:9093
      group-id: group-tenant2-id
      auto-offset-reset: earliest
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      ssl:
        trust-store-location: classpath:client.truststore.jks
        trust-store-password: test123
        key-store-location: classpath:client.keystore.jks
        key-store-password: test123
        key-password: test123

    producer:
      security:
        protocol: "SSL"
      bootstrap-servers: localhost:9093
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
      ssl:
        trust-store-location: classpath:client.truststore.jks
        trust-store-password: test123
        key-store-location: classpath:client.keystore.jks
        key-store-password: test123
        key-password: test123

同时确保client.keystore.jks已放置在SpringBoot项目的resources目录下,且配置中的密码与实际密钥库、密钥密码一致。

内容的提问来源于stack exchange,提问作者Tom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 14:54:08