我正在使用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]
万一你想知道...... bean1
和bean2
在我的示例路线代码中没有显示,以保持尽可能简单。
当我在没有任何泊坞容器的情况下运行所有内容时的历史记录相同:
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]
答案 0 :(得分:0)
我使用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
,我不需要明确添加。
但是我仍然觉得奇怪,我的docker设置中的restlet协议需要很长时间......