我正在尝试使用akka-streams和akka-http以及alpakka库将文件下载/上传到Amazon S3。我看到两个可能相关的问题......
我无法上传较大的文件。它失败并显示消息
处理请求时出错:'Substream Source尚未发生 在5000毫秒内实现。完成500内部 服务器错误响应。要更改默认的异常处理行为, 提供自定义ExceptionHandler。 akka.stream.impl.SubscriptionTimeoutException: 子流源尚未在5000毫秒内实现
这是我的路线
pathEnd {
post {
fileUpload("attachment") {
case (metadata, byteSource) => {
val writeResult: Future[MultipartUploadResult] = byteSource.runWith(client.multipartUpload("bucketname", key))
onSuccess(writeResult) { result =>
complete(result.location.toString())
}
}
}
}
} ~
path("key" / Segment) {
(sourceSystem, sourceTable, sourceId) =>
get {
val result: Future[ByteString] =
client.download("bucketname", key).runWith(Sink.head)
onSuccess(result) {
complete(_)
}
}
}
尝试下载100KB的文件将最终获取文件的截断版本,通常大小约为16-25Kb 任何帮助表示赞赏
编辑:对于下载问题,我接受了Stefano的建议并获得了
[error] found : akka.stream.scaladsl.Source[akka.util.ByteString,akka.NotUsed]
[error] required: akka.http.scaladsl.marshalling.ToResponseMarshallable
这使它起作用
complete(HttpEntity(ContentTypes.`application/octet-stream`, client.download("bucketname", key).runWith(Sink.head)))
答案 0 :(得分:1)
1)关于下载问题:通过调用
val result: Future[ByteString] =
client.download("bucketname", key).runWith(Sink.head)
您将所有数据从S3流式传输到内存中,然后提供结果。
Akka-Http作为流支持,允许您直接从源流式传输字节,而无需在内存中缓冲它们。有关这方面的更多信息,请参阅docs。实际上,这意味着complete
指令可以采用Source[ByteString, _]
,如
...
get {
complete(client.download("bucketname", key))
}
2)关于上传问题:您可以尝试调整Akka HTTP akka.http.server.parsing.max-content-length
设置:
# Default maximum content length which should not be exceeded by incoming request entities.
# Can be changed at runtime (to a higher or lower value) via the `HttpEntity::withSizeLimit` method.
# Note that it is not necessarily a problem to set this to a high value as all stream operations
# are always properly backpressured.
# Nevertheless you might want to apply some limit in order to prevent a single client from consuming
# an excessive amount of server resources.
#
# Set to `infinite` to completely disable entity length checks. (Even then you can still apply one
# programmatically via `withSizeLimit`.)
max-content-length = 8m
测试这个的结果代码将是:
withoutSizeLimit {
fileUpload("attachment") {
...
}
}