无法从外部Docker容器访问SpringBoot @RestController [英] SpringBoot @RestController not accessible from outside docker container

查看:315
本文介绍了无法从外部Docker容器访问SpringBoot @RestController的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

tl; dr一个RestController如果在Docker容器中运行,则可以正确回答,而另一个则不能.

tl;dr One RestController answers properly, the other doesn't, if run inside a Docker container.

该服务有两个API alive

The service has two APIs 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-compose运行.

They are both run through docker-compose.

version: '2'

services:
  service:
    image: my/service
    ports:
      - "4000:4000"

docker-machine ip返回192.168.99.100.

alive返回一个空的200响应.符合预期.

alive returns an empty 200 response. As expected.

$ 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时数字都会增加.遗憾的是没有.

callcount should return a 200 response and a number that increases every time the API is called. Sadly it does not.

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

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

Running the service locally provides the expected result.

$ 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创建图像.

The maven-spotify plugin is used to create an image from the following 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日下载).

I am using the latest Docker and Docker-Compose versions (downloaded them 22. August 2016).

已解决!请参阅下面的更新部分.找到最终答案后将确定问题. -问题:为什么无法从Docker容器外部访问callcount?

Solved! See updates section below. Will finalize question when final answer ist found. - Question: Why is callcount not accessible from outside the Docker container?

进一步尝试:

  • @CrossOrigin(origins = "*", maxAge = 3600) - same result
  • Global CORS configurations from the spring docs.
  • Merging the two methods into the AliveController.
  • Deleted every container and image and docker built again from scratch.

日期:

Spring未注册callcount API.我添加了另一个test API来验证这一点,它也无法通过curl访问. alive仍然可以正常工作并显示在日志中.

The callcount API is not registered by Spring. I added another test API to verify this which is also not accessible through curl. alive still works fine and shows up in the logs.

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


I use JDK 1.8 locally (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已正确注册.如果使用

The callcount is properly registered when running the app out of IntelliJ and with mvn spring-boot:run. It does not get registered if run with

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

java -jar my-service.jar.这应该是为什么无法从Docker容器中访问它的原因.

java -jar my-service.jar. This should be the cause why it is not accessible from within the Docker container.

知道为什么会这样吗?在2015年末的另一个项目中,它的工作原理如此.

Any idea why this is the case? It worked like that in another project from late 2015.

推荐答案

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

I was able to solve the problem with help from @daniel.eichten and @ShawnClark, but I don't understand why this fails/works. T

这不是Docker问题,而是Spring.

It was not a Docker problem, but with Spring.

在此处所示(问题可能无关),我从

As seen here (question might be unrelated), I changed the Spring-Application from

@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.

Now all APIs are accessible as expected, also when running inside a Docker container.

这篇关于无法从外部Docker容器访问SpringBoot @RestController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆