毎秒InetAddress.getByName( "example.com")の呼び出しをループする小さなJavaプログラムがあります。'strace-f 'を使用してCentOS6.4ボックスで実行すると、次のように表示されます。 etc/resolve.confが開かれ、一度読み取られます。
$ grep /etc/resolv.conf strace.out
[pid 24810] open("/etc/resolv.conf", O_RDONLY) = 6
Debian 7で実行すると、/ etc/resolv.confが繰り返し開かれるか、stat()されていることがわかります。
$ grep /etc/resolv.conf strace.out
[pid 41821] open("/etc/resolv.conf", O_RDONLY) = 10
[pid 41821] stat("/etc/resolv.conf", {st_mode=S_IFREG|0644, st_size=92, ...}) = 0
[pid 41821] open("/etc/resolv.conf", O_RDONLY) = 10
[pid 41821] stat("/etc/resolv.conf", {st_mode=S_IFREG|0644, st_size=92, ...}) = 0
[pid 41821] stat("/etc/resolv.conf", {st_mode=S_IFREG|0644, st_size=92, ...}) = 0
どちらのシステムにも/etc/nsswitch.confが設定されています
ホスト:ファイルDNS
どちらのシステムでも、名前キャッシュデーモンが実行されていません。
同じバージョンのOracleHotSot Java JVMを両方のマシンで使用して、Javaの違いを除外しました。
CentOS6.4ボックスにはglibc2.12がインストールされています。 Debian7ボックスにはglibc2.13がインストールされています。
/etc/resolv.confを開いたり読んだりすることに関して、2つのオペレーティングシステム間の動作が異なる理由は何ですか?
RedHat glibc開発者は、ソフトウェアのいくつかのバグをバグではないと考えています。これらのバグの1つは、変更後のresolv.confの再読み取りです。 glibcはアプリケーションの責任を考慮しているため、すべてのアプリケーションがこのための独自のロジックを作成する必要があります。
これは絶対に厄介なので、eglibc開発者はこの問題を修正しました。したがって、eglibc以外のシステムでは、アプリケーションにnss_dnsを再初期化するための独自のロジックが必要です。そうでない場合は、resolv.confの変更後に再起動する必要があります。 eglibcシステム(DebianおよびDebianベースのもの)では、バグの少ないlibcが得られます。
Resolv.confを変更し、古いDNSサーバーを廃止し、1200以上のmysqlサーバーを再起動する必要があった後、これは難しい方法であることがわかりました。言うまでもなく、これは面白くありません。
Cライブラリのバージョンが異なるだけでなく、CentOSはGNU Cライブラリ(glibc
)を使用しますが、DebianはEmbedded GLIBC(eglibc
)を使用するため、実際の名前検索システムコールの実装は完全に異なります。
これはおそらく、これら2つのディストリビューション間のシステムコールの動作が異なることを説明しています。
_InetAddress.getByName
_はgetaddrinfo()
に変換されると思います。関連するCライブラリの実装とバージョンで各システムコールのソースを読むことから始めることができます。
使用している実際のパッケージバージョンからソースを必ず読んでください。 EL 6.4のパッケージは、元のアップストリームバージョンと比較して2年以上の改善が行われています。同じことがDebianパッケージにも当てはまると思います。