如果只在我的Thrift客户端中没有recv发送会怎么样?

时间:2017-04-28 04:42:25

标签: networking thrift

我正在实现一个Thrift客户端,以便连接到内置的scribe服务器。

如果我使用标准的Log方法,一切都会好的,如下所示:

public boolean log(List<LogEntry> messages) {
    boolean ret = false;
    PooledClient client = borrowClient();
    try {
        if ((client != null) && (client.getClient() != null)) {
            ResultCode result = client.getClient().Log(messages);
            ret = (result != null && result.equals(ResultCode.OK));
            returnClient(client);
        }
    } catch (Exception ex) {
        logger.error(LogUtil.stackTrace(ex));
        invalidClient(client);
    }
    return ret;
}

但是,当我使用send_Log时:

public void send_Log(List<LogEntry> messages) {
    PooledClient client = borrowClient();
    try {
        if ((client != null) && (client.getClient() != null)) {
            client.getClient().send_Log(messages);
            returnClient(client);
        }
    } catch (Exception ex) {
        logger.error(LogUtil.stackTrace(ex));
        invalidClient(client);
    }
}

它实际上会导致一些问题:

  1. 到端口1463的总网络连接(划线服务器的默认端口)将增加很多,并且始终处于CLOSE_WAIT状态。

  2. 因为我的应用程序卡住而没有抛出任何错误,我认为这可能是网络连接的问题。

2 个答案:

答案 0 :(得分:0)

  

如果没有recv发送怎么办

由于这显然是TCP,发送方将阻止(在阻止模式下),或在非阻塞模式下发生EAGAIN / EWOULDBLOCK。 编辑现在很清楚,您希望在未收到回复的情况下发送。你可以通过发送然后关闭套接字来做到这一点,但这可能会导致对等体产生ECONNRESET,这可能会扰乱它。你应该真正正确地实现应用程序协议。

  

1 /到端口1463的总网络连接(划线服务器的默认端口)将增加太多,并且始终处于CLOSE_WAIT状态。

CLOSE_WAIT状态下的许多端口表示本地应用程序部分存在套接字泄漏。

  

2 /导致我的应用程序卡住而没有丢失任何错误。我认为这可能是网络连接的问题。

这是发送和不接收的问题。

答案 1 :(得分:0)

由于您将此标记为与Thrift相关的问题,因此答案为oneway

service foo {
   oneway void FireAndForget(1: some args)
}

oneway关键字正如名称所示。您获得的客户端实现只发送并且不等待从服务器返回任何内容。此规则还包括例外情况。因此,oneway方法必须始终为void,并且不能抛出任何异常。

  

然而,当我使用send_Log时......

  client.getClient().send_Log(messages);

Thrift生成的send_Xxxrecv_Xxx方法中的任何一个都不是公开的。这就是为什么它们通常是privateprotected方法的原因。 不应该直接调用,除非你确定你知道自己在做什么(很明显后者不是这里的情况)。

因为真正的问题是性能:为什么不直接将呼叫委托给辅助线程?这样I / O就不会阻止UI。