tl; dr一个RestController如果在Docker容器中运行,则可以正确回答,而另一个则不能。
该服务有两个API alive
alive
@CrossOrigin(origins = "*", maxAge = 3600) @RestController public class AliveController { @RequestMapping(value = "/alive", method = RequestMethod.GET) public ResponseEntity<?> alive() { return new ResponseEntity<>(HttpStatus.OK); } }
和callcount。
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-compose运行。
version: '2' services: service: image: my/service ports: - "4000:4000"
docker-machine ip返回192.168.99.100。
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。
Dockerfile
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日下载)。
解决了 !请参阅下面的更新部分。找到最终答案后将确定问题。- 问题 :为什么callcount无法从Docker容器外部访问?
进一步尝试:
@CrossOrigin(origins = "*", maxAge = 3600)
Udates :
该callcountAPI未由Spring注册。我添加了另一个testAPI来验证这一点,它也无法通过curl访问。alive仍然可以正常工作并显示在日志中。
test
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] s.w.s.m.m.a.RequestMappingHandlerMapping : 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)
启动方法之间的差异
使用callcountIntelliJ和以外的方式运行应用程序时,已正确注册mvn spring-boot:run。如果运行,它不会被注册
mvn spring-boot:run
java -Djava.security.egd=file:/dev/./urandom -jar my-service.jar 要么
java -Djava.security.egd=file:/dev/./urandom -jar my-service.jar
java -jar my-service.jar。这应该是为什么不能从Docker容器中访问它的原因。
java -jar my-service.jar
知道为什么会这样吗? 从2015年末开始,它在另一个项目中的运作方式就与之类似。
我可以在@ daniel.eichten和@ShawnClark的帮助下解决问题,但是我不明白 为什么 它会失败/起作用。Ť
这不是Docker问题,而是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); } }
现在,即使在Docker容器中运行时,也可以按预期访问所有API。