当前位置: 首页 > 知识库问答 >
问题:

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

谷奕
2023-03-14

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

该服务有两个APIalive

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

调用计数

@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

live返回一个空的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创建图像。

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)-结果相同
  • spring文档中的全局CORS配置
  • 将这两种方法合并到AliveController中
  • 删除了每个容器和图像,docker从头开始重新构建

Udates:

Spring没有注册callcountAPI。我添加了另一个testAPI来验证这一点,这也是通过curl无法访问的<代码>活动仍然可以正常工作,并显示在日志中。

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

我在本地使用JDK1.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 spall-start: run时,调用计数是正确注册的。如果使用

java-Djava。安全egd=文件:/dev//urandom-jar我的服务。jar

java-jar我的服务。jar。这就是为什么不能从Docker容器中访问它的原因。

知道为什么会这样吗?2015年末的另一个项目也是如此。

共有1个答案

松正阳
2023-03-14

在@daniel的帮助下,我解决了这个问题。Eichden和@ShawnClark,但我不明白这为什么失败/有效。T

这不是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容器中运行时也是如此。

 类似资料:
  • https://github.com/confluentinc/cp-docker-images/blob/5.0.0-post/examples/kafka-cluster/docker-compose.yml 我已经编辑了该文件,并将选项添加到docker组合文件中,以便可以在主机之外访问它们。 我已经运行了以下命令: kafka-1、kafka-2、kafka-3的docker日志(均相同)

  • 我在Amazon linux ec2上安装了dd-agent。如果我直接在主机上运行我的python脚本(我使用了名为"dogstatsd-python"的SDK),所有指标都可以发送到datadog(我登录到datadoghq.com并在那里看到了指标)。脚本类似: 然而,我启动了一个docker容器,并从容器内部运行相同的脚本: '172.14.0.1'是主机的IP,它是用命令提取的 根本没有

  • 问题内容: 我想阻止从外部直接访问docker容器。我使用haproxy,并且只希望访问端口80、443。 我在iptables中添加了以下规则。但是我仍然可以通过不同的端口访问Docker容器。 这可能是由于DOCKER链 我需要创建什么规则来阻止直接访问? 问题答案: 您可以使用命令创建一个网络来连接应用程序和代理,而不必使用IP表来执行此操作。另外,请勿在任何端口上公开应用程序。您应该公开的

  • 我可以对Docker API进行cUrl调用,但是如果我从容器(docker-comals)运行相同的脚本,我就无法到达任何API终结点。 我的请求如下: 原因可能是使用了localhost,但我现在还找不到解决方案。有什么建议吗? 编辑:下面是我正在使用的堆栈(Api平台)的简要摘要https://api-platform.com/).每个容器都连接到“api_默认”网桥网络: 基于php=Sy

  • 我有一个关于这个问题的问题https://hub.docker.com/r/jupyter/scipy-notebook.我正在尝试使用docker compose运行此图像: 组成: Dockerfile 我用手够不着它http://locahost:8888 .... 网址。我使用Windows10作为主机,并尝试从这个docker compose和这些工作中访问其他服务。

  • 外部访问容器 容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。 当使用 -P 标记时,Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口。 使用 docker container ls 可以看到,本地主机的 49155 被映射到了容器的 5000 端口。此时访问本机的 49155 端口即可访问容器内 web 应