SpringBoot @RestController不能从外部的docker容器访问

tl; dr一个RestController可以正确回答,另一个不会,如果在Docker容器中运行的话。

该服务有两个API alive

 @CrossOrigin(origins = "*", maxAge = 3600) @RestController public class AliveController { @RequestMapping(value = "/alive", method = RequestMethod.GET) public ResponseEntity<?> alive() { return new ResponseEntity<>(HttpStatus.OK); } } 

callcount

 @CrossOrigin @RestController public class CallController { private static int callCount = 0; @RequestMapping(value = "/callcount", method = RequestMethod.GET) public ResponseEntity<?> callCount() { return new ResponseEntity<>(++callCount, HttpStatus.OK); } } 

他们都通过docker合成。

 version: '2' services: service: image: my/service ports: - "4000:4000" 

docker-machine ip返回192.168.99.100

alive返回一个空的200响应。 正如所料。

 $ curl -i http://192.168.99.100:4000/alive HTTP/1.1 200 Content-Length: 0 Date: Mon, 22 Aug 2016 17:33:58 GMT 

callcount应该返回一个200响应和一个每次调用API都会增加的数字。 可悲的是,事实并非如此。

 $ curl -i http://192.168.99.100:4000/callcount HTTP/1.1 404 Content-Type: application/hal+json;charset=UTF-8 Transfer-Encoding: chunked Date: Mon, 22 Aug 2016 17:37:26 GMT {"timestamp":1471887446871,"status":404,"error":"Not Found","message":"No message available","path":"/callcount"} 

在本地运行服务提供了预期的结果。

 $ curl -i http://localhost:4000/callcount HTTP/1.1 200 Content-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked Date: Mon, 22 Aug 2016 17:43:40 GMT 1 

maven-spotify插件用于从以下Dockerfile创build一个映像。

 FROM java:8 EXPOSE 4000 VOLUME /tmp ADD service*.jar app.jar # http://stackoverflow.com/a/33882286/1309035 # Without this, Java uses /dev/random to seed its SecureRandom class, which can cause Java code to block unexpectedly. ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"] 

我正在使用最新的Docker和Docker-Compose版本(下载它们2016年8月22日)。

解决了 ! 见下面的更新部分。 当最终答案被发现时,将会最终确定问题。 – 问题 :为什么不能从Docker容器外部访问callcount

进一步尝试:

  • @CrossOrigin(origins = "*", maxAge = 3600) – 相同的结果
  • 来自spring文档的全球CORSconfiguration。
  • 将两个方法合并到AliveController中。
  • 删除每个容器,图像和docker从头开始重新构build。

Udates

callcount API没有被Spring注册。 我添加了另一个test API来validation这也是无法通过curl访问。 alive仍然正常工作,并出现在日志中。

 bash-3.2$ docker logs asmstack_service_1 | grep callcount bash-3.2$ docker logs asmstack_service_1 | grep test bash-3.2$ docker logs asmstack_service_1 | grep alive 2016-08-23 08:42:06.530 INFO 1 --- [ main] swsmmaRequestMappingHandlerMapping : Mapped "{[/alive],methods=[GET]}" onto public org.springframework.http.ResponseEntity<?> de.bahr.asmstack.AliveController.alive() 

我在本地使用JDK 1.8(java.vm.vendor = Oracle Corporation)。

 $ java -version java version "1.8.0_74" Java(TM) SE Runtime Environment (build 1.8.0_74-b02) Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode) 

启动方法之间的差异

当从IntelliJ运行应用程序并使用mvn spring-boot:run时, callcount被正确注册。 如果运行,它不会被注册

java -Djava.security.egd=file:/dev/./urandom -jar my-service.jar

java -jar my-service.jar 。 这应该是为什么它不能从Docker容器内访问的原因。

任何想法为什么是这样的情况? 它在2015年下半年的另一个项目中就像这样工作。

我能够从@ daniel.eichten和@ShawnClark的帮助下解决问题,但我不明白为什么这个失败/有效。 Ť

这不是Docker问题,而是Spring。

如这里看到的(问题可能不相关),我把Spring应用程序从

 @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 

 @EnableAutoConfiguration @EnableWebMvc @Configuration @ComponentScan public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 

现在所有的API都可以按照预期访问,也可以在Docker容器中运行。

Interesting Posts