今回は軽い話(笑)
2013年の2月にこんな記事を書いたのを思い出した。
「TCPの再送タイムアウトを制御したい」
ざっくり、Webサーバのインターネット側とバックエンド側で、TCPの再送タイムアウトを変えたいような場合に便利に使える機能である。TCPのコネクション単位で、ミリ秒単位で再送をあきらめるタイムアウトを指定できる。
この機能以外では、/proc/sys/net/ipv4/tcp_retries2 に値を設定して調整するしかなかった。これはシステム全体に一様に効いてしまうほか、だんだん長くなるリトライ間隔を足しあげて調整するしかない。
ちなみに、tcp_retries2 については int128 さんのすばらしい記事があるので、興味があれば読んでみてほしい。
「TCPカーネルパラメータによる障害復旧時間の短縮」(by int128さん)
さて、この機能はlinux 2.6.37 から利用できるようになった(もちろんLinux固有機能)のだが、setsockopt() に指定する当該機能のオプションの TCP_USER_TIMEOUT が、当時は kernel header にしかなくて...という話があったのだった。
それでは今はどうかと言えば、以下のように Ubuntu Xenial でも CentOS7 でも普通に利用できるようになっているようだ。
Ubuntu Xenial の場合
stack@xenial-work:~$ uname -a
Linux xenial-work 4.4.0-64-generic #85-Ubuntu SMP Mon Feb 20 11:50:30 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
stack@xenial-work:~$ find /usr/include/ -type f | xargs grep TCP_USER_TIMEOUT
/usr/include/netinet/tcp.h:#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */
/usr/include/linux/tcp.h:#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */
stack@xenial-work:~$
CentOS7 の場合
[stack@centos7-work ~]$ uname -a
Linux centos7-work 3.10.0-514.10.2.el7.x86_64 #1 SMP Fri Mar 3 00:04:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
[stack@centos7-work ~]$ find /usr/include/ -type f | xargs grep TCP_USER_TIMEOUT
/usr/include/netinet/tcp.h:#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */
/usr/include/linux/tcp.h:#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */
[stack@centos7-work ~]$
余談だが、ひとつ前の記事で書いた例は、このオプションを使い、とあるサービスがDBサーバに向かって作成するTCPコネクションのみ、DBサーバの障害時にすばやく切れるようにしたかったのだった。
「とあるサービス」や、それが依存するライブラリ等には手を加えられない事情があったので、connect(2)をhookしてDBサーバ向けのコネクションの場合のみ TCP_USER_TIMEOUT を設定するというえぐいことをしていたのだった...(とおいめ