无法从docker容器外部访问SpringBoot @RestController

时间:2016-08-22 17:50:25

标签: maven docker spring-boot dockerfile spring-restcontroller

tl;如果在Docker容器内运行,则一个RestController正确回答,另一个不回答。

该服务有两个API arguments

alive

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

callcount

它们都通过docker-compose运行。

@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);
    }
}

version: '2' services: service: image: my/service ports: - "4000:4000" 返回docker-machine ip

192.168.99.100返回空200响应。正如所料。

alive

$ 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 应该返回200响应和每次调用API时都会增加的数字。可悲的是,它没有。

callcount

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

$ 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"}

maven-spotify插件用于创建以下$ 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 的图片。

Dockerfile

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

解决!请参阅下面的更新部分在找到最终答案时将最终确定问题。 - 问题:为什么无法从Docker容器外部访问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"]

进一步尝试:

  • callcount - 结果相同
  • 来自the spring docs的全球CORS配置。
  • 将两种方法合并到AliveController中。
  • 删除了从头开始重新构建的每个容器和图像以及docker。

Udates

Spring未注册@CrossOrigin(origins = "*", maxAge = 3600) API。我添加了另一个callcount API来验证这个,这也是无法通过curl访问的。 test仍能正常运行并显示在日志中。

alive

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

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()

启动方法之间的差异

从IntelliJ和$ 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) 运行应用程序时,callcount已正确注册。如果使用

运行,则不会注册

mvn spring-boot:run

java -Djava.security.egd=file:/dev/./urandom -jar my-service.jar。这应该是无法从Docker容器中访问它的原因。

知道为什么会这样吗?从2015年底开始,它就像在另一个项目中那样工作。

1 个答案:

答案 0 :(得分:1)

我能够在@ daniel.eichten和@ShawnClark的帮助下解决问题,但我不明白为什么这会失败/工作。 Ť

这不是Docker的问题,而是Spring。

如所见here(问题可能无关),我从

更改了Spring-Application
@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容器内运行时使用。