なんか遅いを解決する
開発環境やその他の環境と比べて特定の別環境で実行したら「なんか遅くなる…」という場合に陥る話です。
1.Nagleアルゴリズムを切る
大雑把に言えば、細かい粒度の書き込みデータをある程度遅延(バッファ)して送信するというTCPのオプション機能。
https://ja.wikipedia.org/wiki/Nagle%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
アプリケーションが繰り返し1バイトなど小さな粒度で送信する問題を取り上げている。IPv4 で 20バイト、TCP自体で20バイトのヘッダーがあり、合計40バイトになるため、1バイトを送信するのに合計41バイト送信しなくてはならなく、オーバーヘッドが大きい。
Wikipediaの記載の通り、オーバーヘッドが大きいため細かい粒度はある程度まとめて送るほうが効率がいい場合があるため、デフォルトではこのオプションが有効になっていることが多い。
アプリケーション側で意味のあるバッファしている場合など、Nagleアルゴリズムが無駄な遅延となることがあるためオプションを無効にすると改善される場合1がある。
java.net.Socketだと無効にする場合はこいつ→Socket.setTcpNoDelay(boolean on)
2.DNSの逆引きをしない
サーバー側で接続元の情報が欲しいとき、例えばログに接続元情報を出力したい場合など
接続されたSocketに対してjava.net.InetSocketAddress.getHostName()
を呼ぶとIPアドレスからホスト名の逆引きが行われます。
IPアドレスからホスト名の逆引きに失敗すると、DNSの応答までに数ミリ秒~数秒と結構時間がかかるため、その分遅くなります。
逆引きに失敗する環境でしか起こりえないので、この場合のパフォーマンス低下には気づきにくいですが接続元の情報をなにかしらする実装がある場合か、getHostName()
などでgrepすることで原因特定ができる場合があります。
もう少し色々あったきがするけど思いつく範囲だと2つしかなかった……。
-
Nagleを無効にする場合はレイテンシは低下するけどスループットも低下する可能性もあるので、アプリケーションの特性と相談する必要があります。 ↩