CentOS 和 Debian 之间的名称解析差异

CentOS 和 Debian 之间的名称解析差异

我有一个小 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():

$ 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

两个系统都没有运行名称缓存守护进程。

我在两台机器上使用相同版本的 Oracle HotSot Java JVM 来排除任何 Java 差异。

CentOS 6.4 盒安装了 glibc 2.12。Debian 7 盒安装了 glibc 2.13。

什么原因导致两个操作系统在打开和读取 /etc/resolv.conf 时的行为不同?

答案1

RedHat glibc 开发人员认为他们软件中的一些错误不算是错误。这些错误之一就是在更改 resolv.conf 后重新读取。glibc 认为这是应用程序的责任,因此每个应用程序都需要为此创建自己的逻辑。

因为这绝对是疯了,所以 eglibc 开发人员已经修复了这个问题。因此在非 eglibc 系统上,您的应用程序需要有自己的逻辑来重新初始化 nss_dns,否则在 resolv.conf 更改后需要重新启动。在 eglibc 系统(Debian 和基于 Debian 的东西)上,您可以获得错误较少的 libc。

我们在更改 resolv.conf、停用旧 DNS 服务器并重新启动 1200 多个 mysql 服务器后才发现了这一点。不用说,这可不是什么好事。

答案2

不仅 C 库版本不同,而且 CentOS 使用 GNU C 库(glibc),而 Debian 使用嵌入式 GLIBC(eglibc),因此名称查找系统调用的实际实现完全不同。

这可能解释了这两个发行版之间不同的系统调用行为。

我假设InetAddress.getByName翻译成getaddrinfo()。您可以先阅读相关 C 库实现和版本中每个系统调用的源代码。

确保阅读您正在使用的实际软件包版本的源代码。与原始上游版本相比,EL 6.4 中的软件包已经进行了超过 2 年的改进。我认为 Debian 软件包也是如此。

相关内容