3
 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   - 

それは私のサーバーに問題を引き起こしますか?. この理由は何ですか?.

4

1 に答える 1

3

接続を適切に閉じていますが、time_wait 接続が増加しています。何か不足していますか?

これTIME_WAITはカーネルによって使用され、TCP ストリームが、リモート側からパケットが送信されている可能性があるポートを再利用しないようにします。このTIME_WAIT時間は通常、ネットワーク設定に基づいて、パケットの最大経過時間の 2 倍に設定されます。

多数の新しい接続を取得している場合、ポート数がTIME_WAIT 増加していることがわかりますが、接続速度も増加していない限り、ある時点で安定するはずです。やるべきことの 1 つは、すべてのTIME_WAIT行を grep してソートし、ポート番号が変更されているかどうかを確認することです。新しいポートが追加され、古いポートが落ちる場合は、すべて問題ありません。

試してみるべきことの 1 つは、クライアントがclose()通話を開始していることを確認することです。これにより、サーバーではなくTIME_WAITクライアントに残ります。この優れたページを参照してください。サーバー上での影響について。TCPTIME_WAIT

サーバーがクライアントにファイルを送信しているように見えるため (コードを正しく読んでいれば)、プロトコルを次のようなものに変更することを検討する必要があります。これにより、クライアントが最初に閉じられるため、ほとんどの がTIME_WAIT各クライアント上にあります。

  1. サーバーは最初にファイルの長さを送信します
  2. サーバーがファイルを送信します
  3. クライアントは長さを読み取ります
  4. クライアントはファイルバイトを読み取ります
  5. クライアントは「了解」を送信します
  6. クライアントが閉じます
  7. サーバーはクライアントの「了解」メッセージを読み取ります
  8. サーバーが閉じます

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();
    }
}
于 2012-05-23T19:20:11.007 に答える