gpt4 book ai didi

java - 使用 Netty HTTP 客户端重试请求

转载 作者:可可西里 更新时间:2023-11-01 16:32:09 35 4
gpt4 key购买 nike

在基于 Netty 的 HTTP 客户端中应该如何重试 HTTP 请求?

考虑以下处理程序,如果收到 HTTP 响应代码 503,它会在 1 秒后尝试重试 HTTP 请求:

public class RetryChannelHandler extends ChannelDuplexHandler {
List<HttpObject> requestParts;

@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
if (msg instanceof HttpRequest) {
requestParts = new ArrayList<>();
requestParts.add((HttpRequest)msg);
} else if (msg instanceof HttpObject) {
requestParts.add((HttpObject)msg);
}

super.write(ctx, msg, promise);
}

@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof HttpResponse) {
HttpResponse res = (HttpResponse)msg;
if (res.status().code() == 503) {
ctx.executor().schedule(new Runnable() {
@Override
public void run() {
for (HttpObject obj : requestParts) {
ctx.channel().write(obj);
}
}
}, 1000, TimeUnit.MILLISECONDS);
} else {
super.channelRead(ctx, msg);
}
} else {
super.channelRead(ctx, msg);
}
}
}

当我在这个例子中写入 channel 时,管道中的其他处理程序看到 HttpObjects,但 HttpRequest 实际上并没有再次执行——只收到一个 HttpResponse。

我认为在这种情况下我只是误用了 Channel,我需要创建一个新的 Channel(表示与服务器的新连接)来执行重试。我不清楚的是如何从处理程序的上下文中创建新的 channel ,以及我是否真的在正确的 Netty 层中执行这种逻辑。

任何关于如何实现我所描述的行为的指导都将不胜感激。

最佳答案

您还需要在调用 write(...) 之后调用 flush(),否则它不会被刷新到 Channel。此外,您还需要确保您可能 retain() 和 duplicate() HttpContent,否则您最终可能会尝试编写已发布的 HttpContent 对象。

像这样(未测试):

public class RetryChannelHandler extends ChannelDuplexHandler {
Queue<HttpObject> requestParts;

@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
if (msg instanceof HttpRequest) {
requestParts = new ArrayDeque<>();
requestParts.add((HttpRequest)msg);
} else if (msg instanceof HttpContent) {
requestParts.add(((HttpContent)msg).duplicate().retain());
}

super.write(ctx, msg, promise);
}

@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof HttpResponse) {
HttpResponse res = (HttpResponse)msg;
if (res.status().code() == 503) {
ctx.executor().schedule(new Runnable() {
@Override
public void run() {
HttpObject obj;
while ((obj = requestParts.poll()) != null) {
ctx.write(obj);
}
ctx.flush();
}
}, 1000, TimeUnit.MILLISECONDS);
} else {
HttpObject obj;
while ((obj = requestParts.poll()) != null) {
ReferenceCountUtil.release(obj);
}
super.channelRead(ctx, msg);
}
} else {
super.channelRead(ctx, msg);
}
}
}

关于java - 使用 Netty HTTP 客户端重试请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45515671/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com