使用Apache Camel在Docker容器中调用服务时的响应时间很长

我使用Spring Boot(v1.2.8)运行Apache Camel v2.17,在四个独立的Docker容器中运行三个微服务(也是Spring Boot)。

我的骆驼应用程序公开一个REST服务,接受三个请求参数(每个微服务一个)。 然后将每个参数发送到相应的微服务。 然后将每个微服务的响应汇总在Camel REST服务的响应主体中。

在这里我的路线更好的理解:

public void configure() { restConfiguration().component("restlet").port(8080).bindingMode(RestBindingMode.auto); rest("/api/v0.1").get("/aggregated") .param().name("service1Id").dataType("long").required(false).endParam() .param().name("service2Id").dataType("long").required(false).endParam() .param().name("service3Id").dataType("long").required(false).endParam() .route() .split(header(Exchange.HTTP_QUERY).tokenize("&"), new ServiceResultAggregator()) .choice() .when().method("routingHelper", "isRequiredIdKey(*, 'service1Id')") .to("direct:dynamic") .when().method("routingHelper", "isRequiredIdKey(*, 'service2Id')") .to("direct:dynamic") .when().method("routingHelper", "isRequiredIdKey(*, 'service3Id')") .to("direct:dynamic") .otherwise() .bean("routingHelper", "clearBody") .endChoice() .end(); from("direct:dynamic").process("eurekaProcessor") .toD("restlet:${header.serviceUrl}${header.serviceValue}?bridgeEndpoint=true&throwExceptionOnFailure=false"; } 

eurekaProcessoreurekaProcessor服务器获取相应的服务,并将其url写入消息头。

现在我的问题:

当我用docker设置调用Camel REST服务时,每个服务的请求时间大约需要5秒。 链接到日志文件

但是,如果我在没有docker的情况下在本地机器上运行所有服务,响应时间要短得多。 还直接调用服务,像他们的docker IP curl:

 curl http://172.18.0.5:8080/api/service1/1234 

奇迹般有效。

所有的Dockerfiles看起来都差不多:

 FROM ubuntu-image COPY target/service.jar app.jar EXPOSE 8080 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] 

我用docker-compose构build我的docker容器:

 version: '2' services: eureka: build: ../EurekaServer/ ports: - "8761:8761" service1: build: ../Microservice1/ service2: build: ../Microservice2/ service3: build: ../Microservice3/ camel: build: ../CamelAPIGateway/ ports: - "8080:8080" 

有没有人遇到同样的问题和/或知道这种行为的原因(希望解决scheme)?

编辑:

当我在我的本地机器(无docker容器)上用Camel调用微服务(在docker容器中)时,响应时间与Camel将在Docker容器内运行的响应时间相同。

此外,我logging了我的ServiceResultAggregator类中的每个交换logging整齐的消息历史logging (当骆驼获取未捕获的exception时):

 Message History --------------------------------------------------------------------------------------------------------------------------------------- RouteId ProcessorId Processor Elapsed (ms) [route1 ] [route1 ] [http://0.0.0.0:8080/api/aggregated?restletMethods=GET ] [ 5196] [route1 ] [choice1 ] [when[bean{routingHelper}]choice[when[bean{routingHelper}]choice[when[bean{rout] [ 5106] [route1 ] [bean1 ] [bean[ref:routingHelper method:prepareHeader] ] [ 0] [route1 ] [to1 ] [direct:dynamic ] [ 5087] [route5 ] [process1 ] [ref:eurekaProcessor ] [ 24] [route5 ] [log1 ] [log ] [ 1] [route5 ] [toD1 ] [ ] [ 5061] [route1 ] [bean2 ] [bean[ref:responseWrapper method:wrapServiceResponse] ] [ 1] 

以防万一你想知道… bean1bean2不显示在我的示例路线代码,以保持尽可能简单。

当我运行没有任何docker容器的所有的历史相同的历史logging:

 Message History --------------------------------------------------------------------------------------------------------------------------------------- RouteId ProcessorId Processor Elapsed (ms) [route1 ] [route1 ] [http://0.0.0.0:8079/api/aggregated?restletMethods=GET ] [ 13] [route1 ] [choice1 ] [when[bean{routingHelper}]choice[when[bean{routingHelper}]choice[when[bean{rout] [ 13] [route1 ] [bean1 ] [bean[ref:routingHelper method:prepareHeader] ] [ 0] [route1 ] [to1 ] [direct:dynamic ] [ 10] [route5 ] [process1 ] [ref:eurekaProcessor ] [ 0] [route5 ] [log1 ] [log ] [ 0] [route5 ] [toD1 ] [ ] [ 10] [route1 ] [bean2 ] [bean[ref:responseWrapper method:wrapServiceResponse] ] [ 1] 

我通过使用servlet的restConfiguration和http作为微服务端点的协议来解决我的问题:

 restConfiguration().component("servlet").port(8080).bindingMode(RestBindingMode.auto); // [...] from("direct:dynamic").process("eurekaProcessor") .toD("${header.serviceUrl}${header.serviceValue}?bridgeEndpoint=true&throwExceptionOnFailure=false"); 

由于${header.serviceUrl}的协议已经是http我不需要明确地添加它。

但我仍然觉得奇怪,restlet协议在我的docker设置中需要时间…