使用Kafka代理的Dockerized Spring Cloud Stream服务无法连接到Zookeeper

我正在使用一个源和一个接收器服务testing一个示例Spring云stream应用程序(运行在Ubuntu Linux机器上)。 我的所有服务都是docker集装箱,我想用卡夫卡作为邮件经纪人。

docker-compose.yml的相关部分下面:

  zookeeper: image: confluent/zookeeper container_name: zookeeper ports: - "2181:2181" kafka: image: wurstmeister/kafka:0.9.0.0-1 container_name: kafka ports: - "9092:9092" links: - zookeeper:zk environment: - KAFKA_ADVERTISED_HOST_NAME=192.168.33.101 - KAFKA_ADVERTISED_PORT=9092 - KAFKA_DELETE_TOPIC_ENABLE=true - KAFKA_LOG_RETENTION_HOURS=1 - KAFKA_MESSAGE_MAX_BYTES=10000000 - KAFKA_REPLICA_FETCH_MAX_BYTES=10000000 - KAFKA_GROUP_MAX_SESSION_TIMEOUT_MS=60000 - KAFKA_NUM_PARTITIONS=2 - KAFKA_DELETE_RETENTION_MS=1000 . . . # not shown: eureka service registry, spring cloud config service, etc. myapp-service-test-source: container_name: myapp-service-test-source image: myapp-h2020/myapp-service-test-source:0.0.1 environment: SERVICE_REGISTRY_HOST: 192.168.33.101 SERVICE_REGISTRY_PORT: 8761 ports: - 8081:8080 . . . 

这里是我的service-test-source服务的application.yml的相关部分:

 spring: cloud: stream: defaultBinder: kafka bindings: output: destination: messages content-type: application/json kafka: binder: brokers: ${SERVICE_REGISTRY_HOST:192.168.33.101} zkNodes: ${SERVICE_REGISTRY_HOST:192.168.33.101} defaultZkPort: 2181 defaultBrokerPort: 9092 

问题是,如果我启动上面的docker-compose ,在test-source容器日志中,我注意到服务无法连接到zookeeper,给出了ZkTimeoutException 拒绝错误,并用ZkTimeoutException结束,这使得服务终止(见下文)。

奇怪的事实是,如果不是运行我的源码(和接收器)testing服务作为docker容器,我通过maven mvn spring-boot:run <etc...>运行它们作为jar文件mvn spring-boot:run <etc...>服务工作正常,能够交换邮件通过kafka。 (请注意,kafka,zookeeper等仍然作为docker集装箱运行)。

 . . . *** THE FOLLOWING REPEATED n TIMES *** 2017-02-14 14:40:09.164 INFO 1 --- [localhost:2181)] org.apache.zookeeper.ClientCnxn : Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error) 2017-02-14 14:40:09.166 WARN 1 --- [localhost:2181)] org.apache.zookeeper.ClientCnxn : Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect java.net.ConnectException: Connection refused at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) ~[na:1.8.0_111] at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717) ~[na:1.8.0_111] at org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:361) ~[zookeeper-3.4.6.jar!/:3.4.6-1569965] at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1081) ~[zookeeper-3.4.6.jar!/:3.4.6-1569965] . . . java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53) at java.lang.Thread.run(Thread.java:745) Caused by: org.springframework.context.ApplicationContextException: Failed to start bean 'outputBindingLifecycle'; nested exception is org.I0Itec.zkclient.exception.ZkTimeoutException: Unable to connect to zookeeper server within timeout: 10000 

任何想法可能是什么问题?

编辑:

我发现在“jar”执行日志中, test-source服务试图通过IP 127.0.0.1连接到zookeeper,正如从下面的日志中可以看到的那样:

 2017-02-15 14:24:04.159 INFO 10348 --- [localhost:2181)] org.apache.zookeeper.ClientCnxn : Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error) 2017-02-15 14:24:04.159 INFO 10348 --- [localhost:2181)] org.apache.zookeeper.ClientCnxn : Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error) 2017-02-15 14:24:04.178 INFO 10348 --- [localhost:2181)] org.apache.zookeeper.ClientCnxn : Socket connection established to localhost/127.0.0.1:2181, initiating session 2017-02-15 14:24:04.201 INFO 10348 --- [localhost:2181)] org.apache.zookeeper.ClientCnxn : Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x15a421fd9ec000a, negotiated timeout = 10000 2017-02-15 14:24:05.870 INFO 10348 --- [ main] org.apache.zookeeper.ZooKeeper : Initiating client connection, connectString=localhost:2181 sessionTimeout=6000 watcher=org.I0Itec.zkclient.ZkClient@72ba68e3 2017-02-15 14:24:05.882 INFO 10348 --- [localhost:2181)] org.apache.zookeeper.ClientCnxn : Opening socket connection to server localhost/0:0:0:0:0:0:0:1:2181. Will not attempt to authenticate using SASL (unknown error) 2017-02-15 14:24:05.883 INFO 10348 --- [localhost:2181)] org.apache.zookeeper.ClientCnxn : Socket connection established to localhost/0:0:0:0:0:0:0:1:2181, initiating session 

这就解释了为什么一切工作在jar执行上,而不是docker(zookeeper容器将它的2181端口输出到主机,所以在主机上直接运行时,它对于服务进程是localhost),但是并没有解决问题:显然,spring云streamkafkaconfiguration忽略了spring.cloud.stream.kafka.binder.zkNodes中设置的属性spring.cloud.stream.kafka.binder.zkNodes (注意,如果我从服务中logging这样的环境variables的值,我会看到为了debugging的目的,我在那里硬编码了192.168.33.101的正确值)。

在尝试使用Kafka联编程序configuration时,您已将defaultBinder设置为rabbit 。 你的应用程序的类path中是否有rabbitkafka粘合剂? 在这种情况下,你可以在这里启用

饲养员:

图片:wurstmeister / zookeeper

 container_name: 'zookeeper' ports: - 2181:2181 

——————— kafka —————————- —-

卡夫卡:

 image: wurstmeister/kafka container_name: 'kafka' environment: - KAFKA_ADVERTISED_HOST_NAME=kafka - KAFKA_ADVERTISED_PORT=9092 - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 - KAFKA_CREATE_TOPICS=kafka_docker_topic:1:1 ports: - 9092:9092 depends_on: - zookeeper 

弹簧:

configuration文件:dev

云:

stream:

defaultBinder:kafka

 kafka: binder: brokers: kafka # i added brokers and zkNodes property zkNodes: zookeeper # bindings: input: destination: message content-type: application/json