使用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"; }
eurekaProcessor
从eurekaProcessor
服务器获取相应的服务,并将其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]
以防万一你想知道… bean1
和bean2
不显示在我的示例路线代码,以保持尽可能简单。
当我运行没有任何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设置中需要时间…