Spring 引导应用无法在 docker 中 link 领事
Spring boot app fail to link consul in docker
我正在尝试使用 Consul 作为发现服务,另外两个 spring 引导应用程序向 Consul 注册;并将它们放入 docker;
以下是我的代码:
应用程序:
server:
port: 3333
spring:
application:
name: adder
cloud:
consul:
host: consul
port: 8500
discovery:
preferIpAddress: true
healthCheckPath: /health
healthCheckInterval: 15s
instanceId: ${spring.application.name}:${spring.application.instance_id:${server.port}}
2 docker-compose.yml
consul1:
image: "progrium/consul:latest"
container_name: "consul1"
hostname: "consul1"
command: "-server -bootstrap -ui-dir /ui"
adder:
image: wsy/adder
ports:
- "3333:3333"
links:
- consul1
environment:
WAIT_FOR_HOSTS: consul1:8500
还有一个类似的问题;
答案表明,应用程序应该等待 consul 使用 depends_on 完全工作,我试过了,但没有用;
报错信息如下:
adder_1 | com.ecwid.consul.transport.TransportException: java.net.ConnectException: Connection refused
adder_1 | at com.ecwid.consul.transport.AbstractHttpTransport.executeRequest(AbstractHttpTransport.java:80) ~[consul-api-1.1.8.jar!/:na]
adder_1 | at com.ecwid.consul.transport.AbstractHttpTransport.makeGetRequest(AbstractHttpTransport.java:39) ~[consul-api-1.1.8.jar!/:na]
除了spring boot application.yml和docker-compose.yml,下面是App的Dockerfile
FROM java:8
VOLUME /tmp
ADD adder-0.0.1-SNAPSHOT.jar app.jar
RUN bash -c 'touch /app.jar'
ADD start.sh start.sh
RUN bash -c 'chmod +x /start.sh'
EXPOSE 3333
ENTRYPOINT ["/start.sh", " java -Djava.security.egd=file:/dev/./urandom -jar /app.jar"]
和start.sh
#!/bin/bash
set -e
wait_single_host() {
local host=
shift
local port=
shift
echo "waiting for TCP connection to $host:$port..."
while ! nc ${host} ${port} > /dev/null 2>&1 < /dev/null
do
echo "TCP connection [$host] not ready, will try again..."
sleep 1
done
echo "TCP connection ready. Executing command [$host] now..."
}
wait_all_hosts() {
if [ ! -z "$WAIT_FOR_HOSTS" ]; then
local separator=':'
for _HOST in $WAIT_FOR_HOSTS ; do
IFS="${separator}" read -ra _HOST_PARTS <<< "$_HOST"
wait_single_host "${_HOST_PARTS[0]}" "${_HOST_PARTS[1]}"
done
else
echo "IMPORTANT : Waiting for nothing because no $WAIT_FOR_HOSTS env var defined !!!"
fi
}
wait_all_hosts
exec
你的问题是 depends_on
只控制你的服务的启动顺序。您必须等到 consul 服务器启动并且 运行 才能启动您的 spring 应用程序。您可以使用此脚本执行此操作:
#!/bin/bash
set -e
default_host="database"
default_port="3306"
host="${2:-$default_host}"
port="${3:-$default_port}"
echo "waiting for TCP connection to $host:$port..."
while ! (echo >/dev/tcp/$host/$port) &>/dev/null
do
sleep 1
done
echo "TCP connection ready. Executing command [] now..."
exec
您docker文件中的用法:
COPY wait.sh /wait.sh
RUN chmod +x /wait.sh
CMD ["/wait.sh", "java -jar yourApp-jar" , "consulURL" , "ConsulPort" ]
我只是想说明一下,我到最后还是没有解决办法,看不懂这里的情况;我尝试了 Ohmen 的建议,在 APP 容器中,我能够 ping consul1;但是APP还是连接不上consul;
如果我只通过以下命令启动 consul:
docker-compose -f docker-compose-discovery.yml up discovery
然后我可以直接运行这个APP(通过Main),它可以连接到spring.cloud.consul.host: discovery;
但是如果我尝试在 docker 容器中 运行 APP,如下所示:
docker run --name adder --link discovery-consul:discovery wsy/adder
再次失败,连接被拒绝;
我对 docker & docker-compose 很陌生;我认为这将是一个很好的开始示例,但对我来说似乎并不那么容易;
我可以推断出您的 Consul 配置位于您的 application.yml
而不是 bootstrap.yml
,这就是问题所在。
根据 ,bootstrap.yml
在 application.yml
之前加载,Consul 客户端必须在应用程序本身之前检查其配置,因此查看 bootstrap.yml
。
工作示例 bootstrap.yml :
spring:
cloud:
consul:
host: consul
port: 8500
discovery:
prefer-ip-address: true
运行 Consul 服务器并且不要忘记 name 选项以匹配您的配置:
docker run -d -p 8500:8500 --name=consul progrium/consul -server -bootstrap
Consul 服务器现在 运行ning,运行 您的应用程序映像(之前使用您的工件构建)并且 link 它到 Consul 容器:
docker run -d -name=my-consul-client-app --link consul:consul acme/spring-app
我正在尝试使用 Consul 作为发现服务,另外两个 spring 引导应用程序向 Consul 注册;并将它们放入 docker;
以下是我的代码: 应用程序:
server:
port: 3333
spring:
application:
name: adder
cloud:
consul:
host: consul
port: 8500
discovery:
preferIpAddress: true
healthCheckPath: /health
healthCheckInterval: 15s
instanceId: ${spring.application.name}:${spring.application.instance_id:${server.port}}
2 docker-compose.yml
consul1:
image: "progrium/consul:latest"
container_name: "consul1"
hostname: "consul1"
command: "-server -bootstrap -ui-dir /ui"
adder:
image: wsy/adder
ports:
- "3333:3333"
links:
- consul1
environment:
WAIT_FOR_HOSTS: consul1:8500
还有一个类似的问题
报错信息如下:
adder_1 | com.ecwid.consul.transport.TransportException: java.net.ConnectException: Connection refused
adder_1 | at com.ecwid.consul.transport.AbstractHttpTransport.executeRequest(AbstractHttpTransport.java:80) ~[consul-api-1.1.8.jar!/:na]
adder_1 | at com.ecwid.consul.transport.AbstractHttpTransport.makeGetRequest(AbstractHttpTransport.java:39) ~[consul-api-1.1.8.jar!/:na]
除了spring boot application.yml和docker-compose.yml,下面是App的Dockerfile
FROM java:8
VOLUME /tmp
ADD adder-0.0.1-SNAPSHOT.jar app.jar
RUN bash -c 'touch /app.jar'
ADD start.sh start.sh
RUN bash -c 'chmod +x /start.sh'
EXPOSE 3333
ENTRYPOINT ["/start.sh", " java -Djava.security.egd=file:/dev/./urandom -jar /app.jar"]
和start.sh
#!/bin/bash
set -e
wait_single_host() {
local host=
shift
local port=
shift
echo "waiting for TCP connection to $host:$port..."
while ! nc ${host} ${port} > /dev/null 2>&1 < /dev/null
do
echo "TCP connection [$host] not ready, will try again..."
sleep 1
done
echo "TCP connection ready. Executing command [$host] now..."
}
wait_all_hosts() {
if [ ! -z "$WAIT_FOR_HOSTS" ]; then
local separator=':'
for _HOST in $WAIT_FOR_HOSTS ; do
IFS="${separator}" read -ra _HOST_PARTS <<< "$_HOST"
wait_single_host "${_HOST_PARTS[0]}" "${_HOST_PARTS[1]}"
done
else
echo "IMPORTANT : Waiting for nothing because no $WAIT_FOR_HOSTS env var defined !!!"
fi
}
wait_all_hosts
exec
你的问题是 depends_on
只控制你的服务的启动顺序。您必须等到 consul 服务器启动并且 运行 才能启动您的 spring 应用程序。您可以使用此脚本执行此操作:
#!/bin/bash
set -e
default_host="database"
default_port="3306"
host="${2:-$default_host}"
port="${3:-$default_port}"
echo "waiting for TCP connection to $host:$port..."
while ! (echo >/dev/tcp/$host/$port) &>/dev/null
do
sleep 1
done
echo "TCP connection ready. Executing command [] now..."
exec
您docker文件中的用法:
COPY wait.sh /wait.sh
RUN chmod +x /wait.sh
CMD ["/wait.sh", "java -jar yourApp-jar" , "consulURL" , "ConsulPort" ]
我只是想说明一下,我到最后还是没有解决办法,看不懂这里的情况;我尝试了 Ohmen 的建议,在 APP 容器中,我能够 ping consul1;但是APP还是连接不上consul;
如果我只通过以下命令启动 consul:
docker-compose -f docker-compose-discovery.yml up discovery
然后我可以直接运行这个APP(通过Main),它可以连接到spring.cloud.consul.host: discovery;
但是如果我尝试在 docker 容器中 运行 APP,如下所示:
docker run --name adder --link discovery-consul:discovery wsy/adder
再次失败,连接被拒绝;
我对 docker & docker-compose 很陌生;我认为这将是一个很好的开始示例,但对我来说似乎并不那么容易;
我可以推断出您的 Consul 配置位于您的 application.yml
而不是 bootstrap.yml
,这就是问题所在。
根据 bootstrap.yml
在 application.yml
之前加载,Consul 客户端必须在应用程序本身之前检查其配置,因此查看 bootstrap.yml
。
工作示例 bootstrap.yml :
spring:
cloud:
consul:
host: consul
port: 8500
discovery:
prefer-ip-address: true
运行 Consul 服务器并且不要忘记 name 选项以匹配您的配置:
docker run -d -p 8500:8500 --name=consul progrium/consul -server -bootstrap
Consul 服务器现在 运行ning,运行 您的应用程序映像(之前使用您的工件构建)并且 link 它到 Consul 容器:
docker run -d -name=my-consul-client-app --link consul:consul acme/spring-app