问题
I'm trying to introduce a Spring Boot REST service in our development setup. The development setup is using docker-compose and an API gateway to expose the individual services on the same domain (ie. localhost).
When I try to make a HTTP request to my service from inside another container via the service name in the shared docker-compose file, the service returns a 400.
The setup
I've edited our docker-compose file, so it looks like the below to introduce the Spring Boot Java service. The service is based on spring-boot-starter-parent (2.0.3.RELEASE) and spring-boot-starter-web. I haven't configured anything related to the web server (except adding the server.server-header property to ensure myself that the request is hitting my service).
version: '3'
services:
...
hello_java:
build:
context: ../hello-java/
dockerfile: Dockerfile
depends_on:
- postgres
- castle_black
ports:
- "8301:8080"
castle_black:
build: ../castle-black/tyk-gateway
ports:
- "8191:8080"
depends_on:
- redis
The behaviour
If I request the hello service from outside the containers (e.g. in my browser on localhost:8301) it replies back correctly. If I'm inside a container, but obtain the IP that the container with my new service gets in the docker network and use that the new service also responds correctly back.
Below I have shown a request from inside the API gateway container to the Java service, first by using the service name and then afterwards with the IP that was resolved. It only replies with a correct response in the IP case.
# curl -v http://hello_java:8080/hello-java/greet?username=Java
* Hostname was NOT found in DNS cache
* Trying 172.19.0.6...
* Connected to hello_java (172.19.0.6) port 8080 (#0)
> GET /hello-java/greet?username=Java HTTP/1.1
> User-Agent: curl/7.35.0
> Host: hello_java:8080
> Accept: */*
>
< HTTP/1.1 400
< Transfer-Encoding: chunked
< Date: Wed, 01 Aug 2018 11:34:34 GMT
< Connection: close
* Server MySpringBootApp is not blacklisted
< Server: MySpringBootApp
<
* Closing connection 0
# curl -v http://172.19.0.6:8080/hello-java/greet?username=Java
* Hostname was NOT found in DNS cache
* Trying 172.19.0.6...
* Connected to 172.19.0.6 (172.19.0.6) port 8080 (#0)
> GET /hello-java/greet?username=Java HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 172.19.0.6:8080
> Accept: */*
>
< HTTP/1.1 200
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 10
< Date: Wed, 01 Aug 2018 11:34:55 GMT
* Server MySpringBootApp is not blacklisted
< Server: MySpringBootApp
<
* Connection #0 to host 172.19.0.6 left intact
Hello Java
The questions
Is there something in the standard spring-boot-starter-web setup that prevents the web server from servicing the request, when the client adds the "Host: hello_java:8080" header? Or why is the web server behaving differently in the two scenarios? And what can I do about it?
回答1:
After some experimentation it turned out that the it was the underscore in the service name that caused the issue. Changing the service name to not have an underscore solved the problem.
回答2:
RFC 952 stipulates that "name" (Net, Host, Gateway, or Domain name) is a text string up to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus sign (-), and period (.)
It seems that the _ is not a valid component for host names. It's a bit confusing because I had the same problem and when I ping app_server it's fine but when I wget from app_server I got bad request.
Changing the underscore to minus fixed it for me.
来源:https://stackoverflow.com/questions/51632753/spring-boot-rest-app-returns-400-when-requested-from-other-docker-compose-servic