背景知识 (background)

网络请求的第一步,通常是进行DNS解析,即 InetAddress.getAllByName,解析成功后放入Positive Cache,默认缓存30s(可调整/禁用)。

若DNS解析失败,会放入Negative Cache,默认缓存10秒(可调整/禁用),后续DNS解析直接返回UnknownHostException。也就是说,极端情况下,DNS解析失败会导致10秒不可用。

SRE托管的JVM应用通常禁用了DNS缓存,其他自运维的应用建议禁用Negative Cache。

查看指标 (dashboard)

展开: 网络 / 域名 / DNS这一行,找到监控面板:
[DNS耗时统计]
在这里插入图片描述

其中,近五分钟解析失败是最近五分钟DNS解析失败的次数。

止损措施 (action)

DNS解析通常是偶发的,开发能做的有限,可向运维反馈,持续观察。

事后改进(postmortem)

DNS解析失败未必会产生负面影响,比如,可能当时只有DNS健康检查,没有业务请求在执行。

参考原因(cause)部分,针对性的优化。

可能的原因 (cause)

一、配置文件有误、DNS误操作

用户配置有误的,比如数据库、Redis、第三方域名弄错了,修复后重新发布即可。

DNS误操作的,联系OP及时回滚。

二、网络抖动或DNS解析瓶颈

跨机房请求容易受到网络抖动影响,比如腾讯云访问亦庄机房的。

部分DNS解析在高并发下有性能瓶颈,确保系统的DNS是可靠的,比如,k8s dns解析策略,确保是高性能的,避免无效的查询。

实践中,追求极致的DNS高可用时,可适当引入应用层缓存。比如:ApacheHttpClient 、Netty 在构造时,提供异步DnsResolver,伪代码如下:

    public InetAddress[] resolve(String host) throws UnknownHostException {
        //缓存不存在,则去加载 ; 如果存在,则返回旧解析,同时检查是否到过期时间了,触发异步任务去加载
        DnsCacheEntry record = this.dnsCache.get(host);
        if (record == null) {
            InetAddress[] addresses = InetAddress.getAllByName(host);
            if (addresses != null && addresses.length > 0) {
                this.dnsCache.put(host, new DnsCacheEntry(addresses));
            }
            return addresses;
        } else {
            // 检查下是否应该触发异步刷新
            if (record.isExpired(this.dnsTtlMs)) {
                try {
                    this.dnsAsyncResolveExecutor.submit(new DnsResolveTask(host, (domain, ipList) -> {
                        dnsCache.put(domain, new DnsCacheEntry(ipList));
                    }));
                } catch (Exception e) {
                    // ignore , 如果异常抛出,比如队列满了等,则返回之前的数据
                }
            }
            return record.getIpList();
        }
    }

除了应用层的缓存外,也可尝试 JVM自身的DNS缓存 (这个是全局的),通过命令行来控制缓存过期时间, see Networking Properties - Oracle

#0 = 禁用, -1 = 永久缓存,>0 缓存多少秒
-Dsun.net.inetaddr.ttl= 10
#禁用掉negative缓存, 0 = 禁用, -1 = 永久缓存,>0 缓存多少秒
-Dsun.net.inetaddr.negative.ttl=0

警告:请设置合理的缓存ttl ,兼顾运维变更的实时性和性能,目前 Redis / 数据库等基础设施的灾备切换是通过调整DNS指向来实现的 。

另外,部分域名可能会启用 DNS 负载均衡,即每次解析返回的多个IP地址的顺序不同,过大的ttl会影响负载均衡效果。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐