class LogWriter implements Runnable {
Socket client;
private static ThreadLocal<Date> date = new ThreadLocal<Date>() {
@Override
protected Date initialValue() {
return new Date();
};
};
private static ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy_MM_dd");
};
};
public LogWriter(Socket client) {
this.client = client;
}
public void run() {
try {
write(this.client.getInputStream(), new File(
CentralizedLogging.logsDir + File.separator
+ client.getInetAddress().getHostName() + "_"
+ getFormattedDate() + ".log"));
this.client.close();
} catch (Exception e) {
try {
e.printStackTrace();
write(new ByteArrayInputStream(e.getMessage().getBytes()),
new File(CentralizedLogging.logsDir + File.separator
+ "centralLoggingError.log"));
} catch (IOException io) {
}
}
}
public synchronized void write(InputStream in, File file)
throws IOException {
RandomAccessFile writer = new RandomAccessFile(file, "rw");
writer.seek(file.length()); // append the file content into existing if it not exist creating a new one.
writer.write(read(in));
writer.close();
}
public static byte[] read(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
int read = -1;
byte[] buffer = new byte[1024];
read = in.read(buffer);
do {
out.write(buffer, 0, read);
} while((read = in.read(buffer)) > -1);
return out.toByteArray();
}
主要方法
public static void main(String[] args) throws InterruptedException,
IOException {
// CentralizedLogging centralLogServer = new CentralizedLogging(args[0],Integer.parseInt(args[1]));
// new Thread(centralLogServer).start();
long start = System.currentTimeMillis() + 1000 * 20 * 60;
while(start >= System.currentTimeMillis()) {
Socket client = new Socket("bharathi-1397", 10000);
OutputStream os = client.getOutputStream();
DataOutputStream outToServer = new DataOutputStream(os);
outToServer
.write("Centralized Logging is working......".getBytes());
client.close();
}
}
我正确关闭连接。但是time_wait连接正在增加。我从我的终端拍了一个快照,我发布了它的一部分。我遗失了什么?
tcp6 0 0 127.0.0.1:46146 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:57645 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:47961 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:56716 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:49469 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:54078 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:51626 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:50143 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:59214 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:54192 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:53436 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:54547 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:55032 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:51273 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:48381 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:47532 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:56811 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:55293 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:56664 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:49242 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:51225 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:59265 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:59378 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:47997 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:47955 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:59453 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:48092 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:52462 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:59579 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:54921 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:55675 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:51140 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:57321 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:51656 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:54740 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:53600 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:59862 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:54766 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:59062 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:55702 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:50942 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:53732 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:52757 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:56430 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:49179 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:48689 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:53313 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:51161 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:57033 127.0.0.1:10000 TIME_WAIT -
tcp6 0 0 127.0.0.1:58607 127.0.0.1:10000 TIME_WAIT -
它会给我的服务器带来任何问题吗?这是什么原因? 。
答案 0 :(得分:3)
我正在关闭连接,但time_wait连接正在增加。我错过了什么吗?
内核使用TIME_WAIT
来确保您的TCP流不会重新使用仍可能从远程端发送数据包的端口。 TIME_WAIT
时间通常设置为根据网络设置将数据包最大年龄加倍。
如果您获得了许多新连接,那么您将看到TIME_WAIT
中的端口数量增加但在某些时候它应该稳定,除非连接速率也在增加。要做的一件事就是grep所有TIME_WAIT
行,对它们进行排序,看看端口号是否在变化。如果新的端口被添加而旧的端口掉落则一切都很好。
要尝试的一件事是确保您的客户正在发起close()
电话。这将使TIME_WAIT
保留在客户端上,不在服务器上。请参阅这个关于TCP
and the implications of TIME_WAIT
on the server的优秀页面。
由于您的服务器似乎正在向客户端发送文件(如果我正确地读取您的代码),您应该考虑将协议更改为以下内容。这将导致客户端先关闭,因此大多数TIME_WAIT
将在每个客户端上。
您是否看到有关客户端首先close()
@kannan的问题?如果服务器正在发送文件,那么我会让它发送文件,然后等待客户端发送“获取”消息。然后客户端可以读取文件,读取EOF标记,发送“得到它”,然后立即关闭。
另外,您应该在代码中使用try ... finally
模式。类似的东西:
public void run() {
try {
write(this.client.getInputStream(), new File(
CentralizedLogging.logsDir + File.separator
+ client.getInetAddress().getHostName() + "_"
+ getFormattedDate() + ".log"));
} catch (Exception e) {
try {
e.printStackTrace();
write(new ByteArrayInputStream(e.getMessage().getBytes()),
new File(CentralizedLogging.logsDir + File.separator
+ "centralLoggingError.log"));
} catch (IOException io) {
}
} finally {
// always close in the finally
this.client.close();
}
}