我正在实现一个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);
}
}
它实际上会导致一些问题:
到端口1463的总网络连接(划线服务器的默认端口)将增加很多,并且始终处于CLOSE_WAIT状态。
因为我的应用程序卡住而没有抛出任何错误,我认为这可能是网络连接的问题。
答案 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_Xxx
和recv_Xxx
方法中的任何一个都不是公开的。这就是为什么它们通常是private
或protected
方法的原因。 不应该直接调用,除非你确定你知道自己在做什么(很明显后者不是这里的情况)。
因为真正的问题是性能:为什么不直接将呼叫委托给辅助线程?这样I / O就不会阻止UI。