camel-jetty http 代理对大型请求流(文件上传)花费太多时间
camel-jetty http proxy taking too much time for large request streams (file upload)
我已经为文档 download/upload 的项目 restful 服务创建了一个 camel-jetty http 代理桥。这些服务被调用到 get/upload 不同类型的文档,大多数时候文件大小超过 100MB。
当我直接调用上传休息服务(HTTP POST)(不通过 camel-jetty http 代理路由)上传 100MB 的文档时,只需要大约 2-3 分钟即可完成上传并收到回复,但是当我通过骆驼路线路由请求时,它需要超过 15 分钟,这有点奇怪,因为游戏中的骆驼路线只不过是一个 HTTP 代理。
以下是一些信息:
骆驼版:2.15.1
骆驼路线定义:
<route>
<from uri="jetty:http://0.0.0.0:8383/sqidds/document?disableStreamCache=true&matchOnUriPrefix=true&enableMultipartFilter=false&continuationTimeout=-1" />
<log id="incomingMessage" message="incomingMessage - \n[id = ${id}]\n [headers = ${headers}]" />
<to uri="jetty:http://somehost:8080/sqidds/document?bridgeEndpoint=true&throwExceptionOnFailure=false&httpClient.timeout=3200000" />
<log id="outgoingMessage" message="outgoingMessage - \n[id = ${id}]\n [headers = ${headers}]" />
</route>
Camel 项目 POM 摘录:
.
.
.
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.15.1.redhat-621084</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>2.15.1.redhat-621084</version>
</dependency>
.
.
.
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jetty</artifactId>
<version>2.15.1.redhat-621084</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http</artifactId>
<version>2.15.1.redhat-621084</version>
<!-- use the same version as your Camel core version -->
</dependency>
.
.
.
休息服务(Spring MVC)代码:
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public @ResponseBody String saveFile(@RequestPart("file") MultipartFile file) throws IOException, DocumentNotSavedException {
String targetPath = null;
if (file != null) {
String repoDirectoryPath = "SOME_REPO_PATH";
String uniqueFileName = FileUtil.getUniqueFileName(repoDirectoryPath, file.getOriginalFilename());
File targetFile = new File(repoDirectoryPath, uniqueFileName);
targetPath = targetFile.getCanonicalPath();
FileUtils.copyInputStreamToFile(file.getInputStream(), targetFile);
} else {
log.error("File is null");
throw new DocumentNotSavedException("File data could not be saved");
}
return targetPath;
}
RestClient代码:
public String putDocument(File file,String fileName) throws RestClientException{
ResponseEntity<String> response = null;
try {
File file = new File("SOME_100MB_FILE.pdf");
byte[] fileBytes = new byte[(int)file.length()];
LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap();
ByteArrayResource contentsAsResource = new ByteArrayResource(fileBytes, fileName) {
@Override
public String getFilename() {
return this.getDescription();
}
};
map.add("file", contentsAsResource);
httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<LinkedMultiValueMap<String, Object>>(map, httpHeaders);
response = restTemplate.exchange(serverUri, HttpMethod.POST, requestEntity, String.class);
} catch (Exception e) {
logger.error("Exception in put document service", e);
throw new RestClientException("Exception in put document service :",e);
}
return response.getBody();
}
注意: 对于 100MB 的文件,传入消息的骆驼路由日志会在调用服务后的一秒内记录下来,但是我会在大约 15 分钟后看到传出日志.我觉得producer camel路线可能有问题
camel 2.17.0 有改进,可以use response input stream directly in http producer。
你能用你的路线试用最新的 Camel 2.17.x 版本 (2.17.3) 吗?
我已经为文档 download/upload 的项目 restful 服务创建了一个 camel-jetty http 代理桥。这些服务被调用到 get/upload 不同类型的文档,大多数时候文件大小超过 100MB。
当我直接调用上传休息服务(HTTP POST)(不通过 camel-jetty http 代理路由)上传 100MB 的文档时,只需要大约 2-3 分钟即可完成上传并收到回复,但是当我通过骆驼路线路由请求时,它需要超过 15 分钟,这有点奇怪,因为游戏中的骆驼路线只不过是一个 HTTP 代理。
以下是一些信息:
骆驼版:2.15.1
骆驼路线定义:
<route>
<from uri="jetty:http://0.0.0.0:8383/sqidds/document?disableStreamCache=true&matchOnUriPrefix=true&enableMultipartFilter=false&continuationTimeout=-1" />
<log id="incomingMessage" message="incomingMessage - \n[id = ${id}]\n [headers = ${headers}]" />
<to uri="jetty:http://somehost:8080/sqidds/document?bridgeEndpoint=true&throwExceptionOnFailure=false&httpClient.timeout=3200000" />
<log id="outgoingMessage" message="outgoingMessage - \n[id = ${id}]\n [headers = ${headers}]" />
</route>
Camel 项目 POM 摘录:
.
.
.
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.15.1.redhat-621084</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>2.15.1.redhat-621084</version>
</dependency>
.
.
.
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jetty</artifactId>
<version>2.15.1.redhat-621084</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http</artifactId>
<version>2.15.1.redhat-621084</version>
<!-- use the same version as your Camel core version -->
</dependency>
.
.
.
休息服务(Spring MVC)代码:
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public @ResponseBody String saveFile(@RequestPart("file") MultipartFile file) throws IOException, DocumentNotSavedException {
String targetPath = null;
if (file != null) {
String repoDirectoryPath = "SOME_REPO_PATH";
String uniqueFileName = FileUtil.getUniqueFileName(repoDirectoryPath, file.getOriginalFilename());
File targetFile = new File(repoDirectoryPath, uniqueFileName);
targetPath = targetFile.getCanonicalPath();
FileUtils.copyInputStreamToFile(file.getInputStream(), targetFile);
} else {
log.error("File is null");
throw new DocumentNotSavedException("File data could not be saved");
}
return targetPath;
}
RestClient代码:
public String putDocument(File file,String fileName) throws RestClientException{
ResponseEntity<String> response = null;
try {
File file = new File("SOME_100MB_FILE.pdf");
byte[] fileBytes = new byte[(int)file.length()];
LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap();
ByteArrayResource contentsAsResource = new ByteArrayResource(fileBytes, fileName) {
@Override
public String getFilename() {
return this.getDescription();
}
};
map.add("file", contentsAsResource);
httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<LinkedMultiValueMap<String, Object>>(map, httpHeaders);
response = restTemplate.exchange(serverUri, HttpMethod.POST, requestEntity, String.class);
} catch (Exception e) {
logger.error("Exception in put document service", e);
throw new RestClientException("Exception in put document service :",e);
}
return response.getBody();
}
注意: 对于 100MB 的文件,传入消息的骆驼路由日志会在调用服务后的一秒内记录下来,但是我会在大约 15 分钟后看到传出日志.我觉得producer camel路线可能有问题
camel 2.17.0 有改进,可以use response input stream directly in http producer。
你能用你的路线试用最新的 Camel 2.17.x 版本 (2.17.3) 吗?