繁体   English   中英

如何在netty中设置不关闭连接的读取超时?

[英]How to set a read timeout in netty that does not close the connection?

我有一个netty服务器接收来自客户端的请求,向另一个服务器发出请求,然后在响应原始客户端请求时使用第二个请求的响应。 我希望对第二个服务器的请求有一个短暂的超时(~40ms),因此我可以在超时的情况下发送一般响应,但我不想关闭与第二个服务器的连接。 相反,我只是在它到达时丢弃对超时请求的响应,然后将连接返回到我的池中。

在netty中执行此操作的最佳方法是什么? 我已经尝试过ReadTimeoutHandler,但是当发生超时时,这似乎会关闭与第二台服务器的连接。

看来根据您的要求,您需要围绕与第二台服务器的连接编写自己的时序管理。 此外,既然你提到了一个连接池,这可能意味着你也可以限制你可以同时建立到第二台服务器的连接数量(好吧,总有一个限制,它只取决于你是否真的要担心它或不)。

对于您不担心排队出站请求的简单情况,您应该能够创建ReadTimeoutHandler的副本并根据需要进行修改,最有可能的方法是让它从上下文中获取回调,以便调用而不是关闭readTimedOut()方法中的连接。

在您要对出站请求进行排队的情况下,您应该考虑在队列上花费的时间以及接收响应的时间,因此您的解决方案需要您自己的计时器,只要您将项目放入出站队列。 此外,您需要一种在计时器和返回的有效结果之间进行同步的方法(您只想发送一个响应,而不是在计时器超时时发送一个响应,而在第二个服务器的响应进入时发送一个响应)。 要做到这一点,我想你会想要使用某种类型的管理器对象,它包含对通道的引用,你的回调通过这个管理器写回来。

例如(在伪代码中)

MyStateManager manager = new MyStateManager(channel);
// Scheduled a timer task for 40ms from now to invoke the callback
// method of your ReadTimedOutCallback and send a message through the manager
myTimer.schedule(new ReadTimedOutCallback(manager),40);
// Send an outbound request to server 2 through a class that queues
// and manages such requests asynchronously.  When the request is complete
// it invokes the callback method of RequestCompletedCallback which then
// sends a response through the manager.
myAsyncOutboundServerRequester.request(new RequestCompletedCallback(manager));
// ... finish and return the thread to Netty for use with other requests
// while the async tasks process

简单形式的管理器就像(不包括异常处理,通道状态检查等):

public class MyStateManager
{
    private final Channel channel;
    private AtomicBoolean messageSent = new AtomicBoolean(false);
    public MyStateManager(Channel channel)
    {
        this.channel = channel;
    }

    // Called by the ReadTimeoutCallback
    public void sendGenericResponse()
    {
        if (messageSent.getAndSet(true))
        {
           //... write generic response to channel
           ChannelFuture future = channel.write... 
           // Add listeners to future, etc
        } 
    }

    // Called by the RequestCompletedCallback
    public void sendResponse(MyResponseObject response)
    {
        if (messageSent.getAndSet(true))
        {
            // write returned response to channel
            ChannelFuture future = channel.write(response);
            // Add listeners to future, etc
        }
    }

}

您可能仍然希望对第二台服务器的连接进行某种类型的超时检查,以便在连接时间过长(30秒或一分钟等)时无法响应连接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM