我有一个小的Java程序,每秒循环调用InetAddress.getByName(“example.com”)。 当我使用'strace -f'在CentOS 6.4盒子上运行它时,我发现/etc/resolv.conf被打开并读取一次:
$ grep /etc/resolv.conf strace.out [pid 24810] open("/etc/resolv.conf", O_RDONLY) = 6
当我在Debian 7上运行它时,我发现/etc/resolv.conf被重复打开或stat()'d:
$ 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
两个系统都configuration了/etc/nsswitch.conf
主机:文件dns
这两个系统都没有名称caching守护进程运行。
我在两台机器上都使用了相同版本的Oracle HotSot Java JVM,以排除任何Java差异。
CentOS 6.4框安装了glibc 2.12。 Debian 7中安装了glibc 2.13。
什么说明了两个操作系统在打开和读取/etc/resolv.conf方面的不同行为?
RedHat的glibc开发人员认为软件中的一些错误不是bug。 其中一个错误是更改后重新读取resolv.conf。 glibc认为应用程序的责任,所以每个应用程序都需要为此创build自己的逻辑。
因为这绝对是疯狂的,eglibc开发者已经解决了这个问题。 因此,在非eglibc系统上,您的应用程序需要有自己的逻辑来重新初始化nss_dns,否则需要在resolv.conf更改后重新启动。 在eglibc系统(Debian和基于Debian的东西),你得到一个较less的错误libc。
在改变resolv.conf,退役旧的DNS服务器,然后重新启动1200多台mysql服务器之后,我们发现了这个难题。 不用说,这不好玩。
不仅C库版本不同,而且CentOS使用GNU C库( glibc
),而Debian使用embedded式GLIBC( eglibc
),所以名称查询系统调用的实际实现是完全不同的。
这可能会解释这两个发行版之间不同的系统调用行为。
我假设InetAddress.getByName
翻译成getaddrinfo()
。 您可以从相关C库实现和版本中的每个系统调用的源头开始。
确保你从你正在使用的软件包版本中读取源代码。 与原来的上游版本相比,EL 6.4中的软件包已经有了2年多的改进。 我认为Debian软件包也是如此。