我正在开发一个项目,其中一个主设备与多个从设备进行通信。为此,它必须与网络中的主机建立连接。但有时会挂起。
我认为背后的原因是额外的时间消耗反向 DNS 查找。因此,请告诉我任何检查或创建列表的命令或脚本反向 DNS 查找时间。
编辑编号。 1
还告诉我可以在 rsh 源代码中的哪里添加该命令,以便我获得每个请求在连接到其他主机时所消耗的时间列表。
这样我就可以找到服务器挂起的原因。
答案1
其中一些取决于正在使用的存根解析器。您还可能遇到 IPv6 问题,例如,如果返回 IPv6 AAAA 记录,但没有 IPv6 连接。
假设软件(呃,rsh
?真的吗?这个答案并不rsh
具体)正在使用系统解析器(如ping
),而不是它自己的实现(如dig
或host
),那么您可以使用它getent
来查看可能发生的情况:
$ time getent ahostsv4 www.google.com
$ time getent ahostsv6 www.google.com
上面将执行正向和反向查找(尽管您不能强制getent
查找反向 PTR 或其他类型,但它只关心 A/AAAA 记录)。
有几个方便的脚本这个答案到https://serverfault.com/questions/7056/whats-the-reverse-dns-command-line-utility,这些允许您像 一样进行正向反向查找(仅限 IPv4)getent hosts
,但在 Perl 中,这样您就可以修改它们。
以上两种可能性都使用了你的系统解析器,包括nsswitch中涉及的所有秋千和回旋处,所以它们应该行为方式与大多数应用程序相同。
不要忘记在客户端进行测试和服务器,其中一个或两个将进行反向查找。
您还可以一一检查您本地的解析器:
$ while read opt p1 ; do
[ "$opt" = "nameserver" ] && dig @$p1 www.google.com +short +identify;
done < /etc/resolv.conf
并检查反向 DNS:
$ dig www.google.com +short | xargs -n1 -i dig -x {} PTR +short +identify
要进一步调试此问题,您需要检查:
/etc/host.conf
(各种选项,包括通过反向 DNS 进行欺骗检查)/etc/resolv.conf
(您的解析器)/etc/nsswitch.conf
(要检查哪些数据库,例如/etc/hosts
DNS、LDAP 等)- 的输出
dnstrace
和/或dig +trace
/etc/gai.conf
,如果存在的话。其中,这可以控制 IPV6 AAAA 记录是否排序在 A 记录之前。/etc/nscd.conf
如果nscd
正在使用
如果您有wireshark和root访问权限,您可以在线观看DNS请求:
# tshark -w dns.cap "port 53"
# tshark -V -ta -n -r dns.cap
(该-V
选项过于冗长,但是开发人员没有想到将时间戳放入协议解析输出中-O dns
。也许这在新版本中已修复。)
即使您nscd
现在没有使用,您也可以轻松看到一些如果您使用选项-dd
或交互启动它会发生什么-ddd
。请注意,nscd
仅缓存主机 (A/AAAA) 记录,因此 PTR 记录最终将以较短(默认 20 秒)的生命周期进行负缓存。
glibc 解析器(和其他)支持“ options debug
”/etc/resolv.conf
以及RES_OPTIONS
可用于启用调试的环境变量。遗憾的是,这个有用的功能要求在构建 glibc 时启用 DEBUG,因此您不太可能使用它......
对于繁重的工作,最好的选择是ltrace
,这使您可以跟踪库调用并为其添加时间戳,就像strace
跟踪系统调用的方式一样,例如gethostbyname()
或gethostbyaddr()
。缺点:提供了多层间接NS开关,您可能会迷失在大量的输出中。在 telnet 上进行一次简单的运行得到了 3000 多行输出,其中隐藏了两个对gethostbyname()
.
$ ltrace -ttT -e "getaddr*+gethost*+getname*" getent ahosts www.google.com
13:42:06.118718 getent->getaddrinfo("www.google.com", nil, { 0x2a, 0, 0, 0, 0, nil,
nil, nil }, { 0x2a, 0x2, 0x3, 0, 16, { 2, 0, { 0x69187d4a } }, "www.google.com", {
0x2a, 0x2, 0x2, 0x11, 16, { 2, 0, { 0x93187d4a } }, nil, { 0x2a, 0x2, 0x3, 0, 16, {
2, 0, { 0x67187d4a } }, nil, { 0x2a, 0x2, 0x2, 0x11, 16, { 2, 0, { 0x68187d4a } },
nil, ... } } } }) = 0 <0.042561>
理解发生了什么有点困难,因为它不输出人类可读的 IP 地址 ( 0x69187d4a
= 105,24,125,74 -> 74.125.24.105)。不过,这可能是追踪本地问题的最佳方法,因为您可以通过 NSS 查看所有调用。
我在上述内容中使用了这些修改~/.ltrace.conf
,可能需要进一步的修改:
typedef size_t = int;
typedef sockaddr = struct(short, short, in_addr);
typedef addrinfo = struct;
typedef addrinfo = struct(hex(int), hex(int), hex(int), hex(int), size_t, sockaddr*, string, addrinfo *);
int getaddrinfo(string, string, addrinfo *, +addrinfo**);
int getnameinfo(sockaddr*, uint, +string, +uint, +string, +uint, uint);
答案2
如果您对反向查询响应缓慢有疑问,可以尝试以下任一方法来纠正:
- 如果可能的话,请在应用程序中禁用反向查找并查看差异
您可以使用名称服务缓存守护进程 (nscd),它也缓存 PTR,但存在一些安全问题:
名称服务缓存守护程序 (nscd) 的默认行为不允许应用程序根据 “A”记录
验证 DNS“PTR”记录。特别是,nscd 会缓存对“PTR”记录的请求,当稍后收到对“A”记录的请求时,nscd 只是泄露
缓存的“PTR”记录中的信息,而不是
向权威 DNS 查询“A”记录。 “ 记录。
参考关联