当前位置: 首页 > 知识库问答 >
问题:

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

松和璧
2023-03-14

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

在Netty最好的方法是什么?我尝试过ReadTimeoutHandler,但当超时发生时,这似乎会关闭与第二台服务器的连接。

共有1个答案

刘英彦
2023-03-14

根据您的需求,您可能需要围绕与第二台服务器的连接编写自己的定时管理。此外,由于您提到的连接池可能意味着您对可以同时建立到第二台服务器的连接数量也有限制(当然,总是有限制的,这取决于您是否真的需要担心)。

对于一个简单的情况,您不必担心将出站请求排队,您只需要创建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秒或一分钟或其他时间)时关闭连接。

 类似资料:
  • 我正在使用带有连接池的reactor-netty http客户端(0.7.X系列),我想配置池连接的空闲超时,但不知道在哪里。 更准确地说,我需要配置reactor-netty http客户端连接池,使其能够自动关闭在可配置超时内未看到任何活动的连接。这些连接是开放的,但在一段(可配置的)时间内没有传输字节。 如何配置reactory-netty超文本传输协议客户端抢先关闭空闲连接?

  • 我正在尝试关闭nettyreactor.ipc.netty.tcp.TcpClient的传输控制协议,但我找不到简单的方法,没有“断开连接”、“停止”或“关闭”方法。有人能帮我吗?我正在使用reamer-net.0.7.9。RELEASE库。 我的课程结构如下: 我感谢你的帮助,提前非常感谢。

  • 故事是这样的,我有一个远程服务器和一个防火墙后面的客户端。客户端由netty实现,它将建立一个与远程服务器的保活连接。如果200秒内通道中没有消息传输,防火墙将重置连接到远程服务器端的连接,但客户端没有收到任何tcp数据包(例如RST包),因此客户端认为此连接是活的,而事实并非如此。那么如何在防火墙错误处理此保活连接之前强制关闭不寻常的连接呢?顺便说一句:我无法配置防火墙

  • 问题内容: 在jersey 1中,我们在类中具有一个函数setConnectTimeout。 在球衣2中,缺少此功能的地方使用该类。 如何在jersey 2.x中设置连接超时并读取超时? 问题答案: 下面的代码在Jersey 2.3.1中对我有用(灵感在这里找到:https :

  • 在泽西1中,我们在类中有一个函数setConnectTimeout。 在jersey 2中,类用于缺少此函数的地方。 如何设置连接超时和读取超时在泽西2. x?

  • 我知道volley有一个重试策略,但我知道,这是针对套接字超时,而不是连接超时,Apache HttpClient有setConnectionTimeout和setSoTimeout方法,有人知道我是否要为volley framework设置连接超时吗。