Java 使用armeria或asynchttpclient代理大型文件

Java 使用armeria或asynchttpclient代理大型文件,java,asynchronous,proxy,asynchttpclient,armeria,Java,Asynchronous,Proxy,Asynchttpclient,Armeria,我有一个用Armeria制作的代理服务器,它应该从一个源开始下载,同时将其向外传输到一个目的地。该文件应该是流式的,因为这是一个代理服务器,我不想让它存储和转发。此应用程序应能处理大量流量 有什么建议我应该在哪里寻找在Armeria做这件事 我尝试使用AsyncHttpClient,但我认为它锁定了主线程或其他东西,因为请求开始累积 下面的所有代码都在CompletableFuture.SupplySync()中 有没有办法解决这个问题,或者更好的办法,完全在Armeria做 public Ht

我有一个用Armeria制作的代理服务器,它应该从一个源开始下载,同时将其向外传输到一个目的地。该文件应该是流式的,因为这是一个代理服务器,我不想让它存储和转发。此应用程序应能处理大量流量

有什么建议我应该在哪里寻找在Armeria做这件事

我尝试使用AsyncHttpClient,但我认为它锁定了主线程或其他东西,因为请求开始累积

下面的所有代码都在CompletableFuture.SupplySync()中

有没有办法解决这个问题,或者更好的办法,完全在Armeria做

public HttpResponse doLogic(URL getUrl, String requestId, String key, Lock lock, String token) {
    // ----
    PipedOutputStream pout = new PipedOutputStream();
    BodyDeferringAsyncHandler bodyDeferringAsyncHandler = new BodyDeferringAsyncHandler(pout);
    Future<Response> respFuture = asyncHttpClient.prepareGet(getUrl.toString()).execute(bodyDeferringAsyncHandler);

    CompletableFuture<HttpResponse> r = CompletableFuture.supplyAsync(() -> {
        try (PipedInputStream pin = new PipedInputStream(pout)) {
            Response resp = bodyDeferringAsyncHandler.getResponse();
            if (resp.getStatusCode() == 200) {
                try (InputStream is = new BodyDeferringAsyncHandler.BodyDeferringInputStream(respFuture, bodyDeferringAsyncHandler, pin)) {
                    HttpHeaders headers = translateHeaders(resp.getHeaders());
                    if (headers.get("etag").contains("-")) {
                        // We remove the etag, since it comes from a multipart upload, it isn't an md5 hash of the file.
                        headers.remove("etag");
                    }

                    PipedOutputStream pout2 = new PipedOutputStream();
                    BodyDeferringAsyncHandler bodyDeferringAsyncHandler2 = new BodyDeferringAsyncHandler(pout2);
                    Future<Response> putResp = asyncHttpClient.preparePut(Config.getString("swift.proxy.base.url") + "v1/" + key)
                            .setHeaders(headers)
                            .addHeader("x-auth-token", token)
                            .setBody(is).execute(bodyDeferringAsyncHandler2);

                    Response putR = null;
                    try {
                        putR = bodyDeferringAsyncHandler2.getResponse();
                        if (putR.getStatusCode() != 201 && putR.getStatusCode() != 202) {
                            log.error("[requestId: " + requestId + "] swift returned " + putR.getStatusCode());
                            return unlockingResponse(putR.getStatusCode(), lock, key);
                        }
                        log.info("[requestId: " + requestId + "] File: " + key + " rollbacked!");
                        return unlockingResponse(200, lock, key);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return unlockingResponse(422, lock, key);
                }
            } else {
                log.warn("[requestId: " + requestId + "] s3 came back with status code: " + resp.getStatusCode());
                return unlockingResponse(200, lock, key);
            }
        } catch (InterruptedException | IOException e) {
            e.printStackTrace();
            return unlockingResponse(500, lock, key);
        }
    });

    return HttpResponse.from(r);
}
public HttpResponse-doLogic(URL-getUrl、String-requestId、String-key、Lock-Lock、String-token){
// ----
PipedOutputStream pout=新的PipedOutputStream();
BodyDeferringAsyncHandler BodyDeferringAsyncHandler=新BodyDeferringAsyncHandler(pout);
Future respFuture=asyncHttpClient.prepareGet(getUrl.toString()).execute(bodyDeferringAsyncHandler);
CompletableFuture r=CompletableFuture.SupplySync(()->{
try(PipedInputStream pin=new PipedInputStream(pout)){
Response resp=bodyDeferringAsyncHandler.getResponse();
如果(分别为getStatusCode()==200){
try(InputStream=new BodyDeferringAsyncHandler.BodyDeferringInputStream(respFuture,BodyDeferringAsyncHandler,pin)){
HttpHeaders=translateHeaders(resp.getHeaders());
if(headers.get(“etag”)包含(“-”){
//我们删除了etag,因为它来自多部分上传,它不是文件的md5散列。
标题。删除(“etag”);
}
PipedOutputStream pout2=新的PipedOutputStream();
BodyDeferringAsyncHandler bodyDeferringAsyncHandler2=新BodyDeferringAsyncHandler(pout2);
Future putResp=asyncHttpClient.preparePut(Config.getString(“swift.proxy.base.url”)+“v1/”+键)
.setHeaders(标题)
.addHeader(“x-auth-token”,token)
.setBody(is).execute(bodyDeferringAsyncHandler2);
响应putR=null;
试一试{
putR=bodyDeferringAsyncHandler2.getResponse();
if(putR.getStatusCode()!=201和&putR.getStatusCode()!=202){
log.error(“[requestId:+requestId+”]swift返回“+putR.getStatusCode());
返回解锁响应(putR.getStatusCode(),锁,键);
}
log.info(“[requestId:+requestId+”]文件:“+key+”rollbacked!”);
返回解锁响应(200,锁,钥匙);
}捕捉(中断异常e){
e、 printStackTrace();
}
返回解锁响应(422,锁,钥匙);
}
}否则{
log.warn(“[requestId:+requestId+”]s3返回时状态代码为:“+resp.getStatusCode()”);
返回解锁响应(200,锁,钥匙);
}
}捕获(中断异常| IOE异常){
e、 printStackTrace();
返回解锁响应(500,锁,钥匙);
}
});
从(r)返回HttpResponse;
}
我希望它能够将文件从源流传输到目标,并能够处理大量流量