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

时间:2016-04-25 12:44:20

标签: java rest docker spring-boot apache-camel

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

我的Camel应用程序公开了一个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从eureka服务器获取相应的服务,并将其url写入邮件头。

现在我的问题:

当我使用docker setup调用Camel REST服务时,每个服务的请求时间大约需要5秒。 Link to logfile

但是,如果我在没有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构建我的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"

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

编辑:

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

我还在ServiceResultAggregator类中为每个交换记录了整洁的消息历史记录(当camel获得未捕获的异常时获得):

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在我的示例路线代码中没有显示,以保持尽可能简单。

当我在没有任何泊坞容器的情况下运行所有​​内容时的历史记录相同:

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]

1 个答案:

答案 0 :(得分:0)

我使用servlet作为微服务端点的restConfigurationhttp作为协议解决了我的问题:

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,我不需要明确添加。

但是我仍然觉得奇怪,我的docker设置中的restlet协议需要很长时间......