图解系列 DNS查找过程和DNS缓存

news2024/12/23 6:47:43

DNS 充当地址簿。它将人类可读的域名 (google.com) 转换为机器可读的 IP 地址 (142.251.46.238)。

开局一张图

img

来自:https://xiaolishen.medium.com/the-dns-lookup-journey-240e9a5d345c

寻址流程

  1. 查询浏览器缓存:当你输入一个域名后,浏览器会首先检查自己的缓存,看是否已经解析过该域名的IP地址。
  2. 查询操作系统的DNS缓存:如果在浏览器缓存中找不到对应的IP地址,浏览器会向操作系统发出DNS解析请求。操作系统会检查自己的DNS缓存,看是否已经解析过该域名。
  3. 查询OS的hosts文件:如果在操作系统的DNS缓存中找不到对应的IP地址,操作系统会检查自己的hosts文件,看是否有该域名的映射信息。hosts文件是一个本地的文本文件,可以手动添加域名和IP地址的映射关系。
  4. 查询家庭路由器缓存:如果在操作系统的hosts文件中找不到对应的IP地址,操作系统会将DNS解析请求发送给家庭路由器。家庭路由器也有一个DNS缓存,用于存储最近解析过的域名和IP地址。
  5. 查询ISP的DNS服务器:如果在家庭路由器的缓存中找不到对应的IP地址,家庭路由器会将DNS解析请求发送给配置的ISP的DNS服务器。
  6. 查询ISP缓存:ISP的DNS服务器收到解析请求后,会检查自己的DNS缓存,看是否已经解析过该域名。
  7. DNS服务器递归查询:如果在ISP的缓存中找不到对应的IP地址,ISP的DNS服务器会根据域名的层级结构,从根域名服务器开始递归查询,直到找到负责该域名的权威域名服务器。(这里也有可能是迭代查询
    1. 解析器向根名称服务器询问域名,假设它是example.com
    2. 根名称服务器知道所有TLD(顶级域)名称服务器。由于我们附带了.com域,因此它将我们的查询转发到处理.com域的 TLD 名称服务器。
    3. .com TLD 名称服务器知道存储example.com域的 DNS 记录的权威名称服务器,因此它会提前转发查询。
    4. 权威名称服务器响应映射到域名的A 记录(地址记录,即 IP 地址)。
  8. 然后,IP 地址一路传回我们的浏览器,中间每个拥有 DNS 缓存的浏览器都会在途中缓存它,因此下次当我们或其他人询问 example.com 时,会更快的响应。
  9. 浏览器打开与 IP 地址(即托管example.com的服务器的地址)的 TCP/IP 连接,然后发送 HTTP 请求。如果服务器已启动并正在运行,它会将 HTTP 响应发送回我们的浏览器。

DNS 查询类型

递归查询 - 客户端向 ISP DNS 服务器发送请求后,它必须响应客户端请求的答案,即: www.example.com 的 IP 地址。如果ISP的DNS服务器没有答案,它必须不断地自行寻找答案,直到得到答案,然后它回复客户端。

迭代查询 - 当ISP DNS服务器向远程DNS服务器发送请求后,远程DNS服务器不需要响应应答,它可以响应另一个DNS服务器的IP地址来进行引用。 ISP DNS 服务器查看响应并向另一台服务器重新发出新请求。它不断重复这个过程,直到找到答案。

DNS zone

img

DNS缓存

  • 浏览器DNS缓存

    在 Chrome 浏览器中,您可以转到 chrome://net-internals/#dns 查看 DNS 缓存的状态。

  • 本地DNS缓存

    在 Windows 中查看 DNS 缓存条目 ipconfig /displaydns

    刷新 DNS 缓存ipconfig /flushdns

    并非所有 Linux 发行版都启用或默认安装 DNS 缓存

    Debian 或 Ubuntu 系统,则 DNS 缓存文件存储在目录中 /var/cache/nscd/hosts

    sudo strings /var/cache/nscd/hosts

  • hosts文件

  • 路由器DNS缓存

  • ISP(运营商)DNS缓存

  • Java DNS Cache

高级

Java DNS Cache

相关代码在InetAddressCachePolicy.java

public final class InetAddressCachePolicy {

    // 成功寻址的缓存策略
    // 安全属性
    private static final String cachePolicyProp = "networkaddress.cache.ttl";
    // 系统属性
    private static final String cachePolicyPropFallback =
        "sun.net.inetaddr.ttl";

    // 失败寻址的无效缓存策略
    // 安全属性
    private static final String negativeCachePolicyProp =
        "networkaddress.cache.negative.ttl";
    // 系统属性
    private static final String negativeCachePolicyPropFallback =
        "sun.net.inetaddr.negative.ttl";

    public static final int FOREVER = -1;
    public static final int NEVER = 0;

    /* default value for positive lookups */
    public static final int DEFAULT_POSITIVE = 30;

解析成功缓存策略

        Integer tmp = java.security.AccessController.doPrivileged(
          new PrivilegedAction<Integer>() {
            public Integer run() {
                	// 读取参数 networkaddress.cache.ttl 作为缓存 ttl
                try {
                    String tmpString = Security.getProperty(cachePolicyProp);
                    if (tmpString != null) {
                        return Integer.valueOf(tmpString);
                    }
                } catch (NumberFormatException ignored) {
                    // Ignore
                }
				// 读取启动参数 sun.net.inetaddr.ttl 作为缓存 ttl
                try {
                    String tmpString = System.getProperty(cachePolicyPropFallback);
                    if (tmpString != null) {
                        return Integer.decode(tmpString);
                    }
                } catch (NumberFormatException ignored) {
                    // Ignore
                }
                return null;
            }
          });

        if (tmp != null) {
            cachePolicy = tmp < 0 ? FOREVER : tmp;
            propertySet = true;
        } else {
			// 如果以上参数均未读取到,并且未开启 SecurityManager,则会使用默认值 30s.
            if (System.getSecurityManager() == null) {
                cachePolicy = DEFAULT_POSITIVE;
            }
            // 否则使用初始值 -1,表示永久生效
        }
  1. 如果开启了 SecurityManager,优先从 ${java.home}/jre/lib/security/java.security 中读取参数 networkaddress.cache.ttl,单位为秒。
  2. 如果未读取到,则会读取启动参数 sun.net.inetaddr.ttl 作为缓存 ttl.
  3. 如果以上参数均未读取到,并且未开启 SecurityManager,则会使用默认值 30s.(默认是未启用,即默认是30s有效期
  4. 否则使用初始值 -1,表示永久生效。

SecurityManager是一个允许应用实现一种安全策略的类。应用在执行一个安全或敏感的操作之前,可以明确此操作是否在一个安全的上下文中被执行。

默认是未启用状态

1.系统启动开启

JVM参数-Djava.security.manager

2.程序手动开启

// 创建SecurityManager实例
SecurityManager securityManager = new SecurityManager();
// 设置启动
System.setSecurityManager(securityManager);

寻址失败无效的DNS缓存时间

        tmp = java.security.AccessController.doPrivileged (
          new PrivilegedAction<Integer>() {
            public Integer run() {
                // 读取 networkaddress.cache.negative.ttl 默认10s
                try {
                    String tmpString = Security.getProperty(negativeCachePolicyProp);
                    if (tmpString != null) {
                        return Integer.valueOf(tmpString);
                    }
                } catch (NumberFormatException ignored) {
                    // Ignore
                }
  				 // 读取 sun.net.inetaddr.negative.ttl
                try {
                    String tmpString = System.getProperty(negativeCachePolicyPropFallback);
                    if (tmpString != null) {
                        return Integer.decode(tmpString);
                    }
                } catch (NumberFormatException ignored) {
                    // Ignore
                }
                return null;
            }
          });

        if (tmp != null) {
            negativeCachePolicy = tmp < 0 ? FOREVER : tmp;
            propertyNegativeSet = true;
        }

当DNS解析无效的时候,默认10S,目的是为了帮助提升性能

总结

可查看源码InetAddress 和 InetAddressCachePolicy

  • java dns解析缓存之源码解析
    • 如果打开Java中的SecurityManagerDNS缓存将不会失效。
    • 否则,可访问的DNS解析缺省缓存30秒,不可访问的DNS解析缺省缓存10秒。
  • 关于jvm dns cache(域名缓存时间),给出“对于多条A记录是采用什么策略返回IP的结论:
    • 在缓存有效期内,取到的IP永远是缓存中全部A记录的第一条,并没有轮循之类的策略。
    • 缓存失效之后重新进行DNS解析,因为每次域名解析返回的A记录顺序会发生变化(nslookup www.google.com测试可见),所以缓存中的数据顺序也变了,取到的IP也变化。

如何设置 JVM TTL

要修改 JVM 的 TTL,请设置 networkaddress.cache.ttl 属性值。根据您的需求,使用下列方法之一:

  • 全局 (针对所有使用 JVM 的应用程序)networkaddress.cache.ttl在 Java 8 $JAVA_HOME/jre/lib/security/java.security 的文件或适用于 Java 11 或更高版本$JAVA_HOME/conf/security/java.security的文件中设置:

    networkaddress.cache.ttl=60
    
  • 仅针对应用程序,在应用程序的初始化代码中设置 networkaddress.cache.ttl

    java.security.Security.setProperty("networkaddress.cache.ttl" , "60");
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/825398.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VS创建QT项目的几个注意点

前提是已经安装好了VS、QT和Qt VS Tool。 一、创建项目无法找到头文件&#xff0c;点击编译运行又可以执行。虽然可以编译运行&#xff0c;但是无法找不到头文件显示是红色并且在开发时无法出现相关代码提示&#xff0c;并且无法导入QT相关头文件。 解决方法&#xff1a; 1、…

Android多线程编程、异步消息处理机制以及new Handler()被标记为过时的解决办法,解决Handler内存泄漏问题和AsyncTask的基本用法

一、Android多线程编程 1、异步消息处理机制 1.1 弱引用 WeakReference&#xff08;弱引用&#xff09;是一种在Java中用于管理对象的引用的特殊引用类型。它的作用是在垃圾回收过程中&#xff0c;允许对象在没有强引用指向它时被回收&#xff08;当一个对象只有弱引用指向它…

如何防止亚马逊买家号关联?

防止亚马逊买家号关联是指避免在同一家亚马逊账户下使用多个买家号。有时&#xff0c;卖家或买家会创建多个买家号来规避亚马逊的规则和限制。然而&#xff0c;这样的行为违反了亚马逊的政策&#xff0c;并可能导致账户被封禁或其他严重的后果。 而想要防关联&#xff0c;可以从…

【Linux】IO 篇:文件调用原理,文件描述符,FILE的内涵,解析重定向,理解缓冲区

文章目录 一、系统调用接口二、文件调用1. 文件描述符 fd2. 文件调用原理3. FILE 三、重定向dup2 四、缓冲区简易 FILE 的代码实现 文件被加载之前&#xff0c;被存在磁盘上&#xff0c;操作文件&#xff0c;文件的部分内容则会被调度到 内存中。 要分析文件&#xff0c;我们也…

问道管理:沪指震荡跌0.84%,银行、医药等板块走弱,地产板块逆市拉升

2日早盘&#xff0c;沪指盘中震动下探&#xff0c;深成指、创业板指亦走低&#xff1b;两市半日成交约5400亿元&#xff0c;北向资金净卖出约35亿元。 到午间收盘&#xff0c;沪指跌0.84%报3263.2点&#xff0c;深成指跌0.42%&#xff0c;创业板指跌0.27%&#xff0c;上证50指数…

UPnP是什么?有什么更好的连接方案?快解析内网穿透

一、UPnP是什么 有些小伙伴对于UPnP并不了解&#xff0c;其实UPnP只是一种网络协议&#xff0c;主要作用就是简化家庭和企业网络中设备之间的连接和通信过程&#xff0c;它的主要目标是实现网络的无缝连接&#xff0c;并简化相关网络操作。 二、UPnP有什么主要作用&#xff1…

激光切割机好不好?激光切割与线切割应该怎么选择对比

在选择激光切割机与线切割机进行比较时&#xff0c;我们首先需要理解两者的特性与特点。 激光切割机&#xff1a;现阶段主流的激光切割设备主要包括光纤激光切割机和CO2激光切割机。其中CO2激光切割机主要用于切割厚板&#xff0c;但也可完成非金属材料的切割。光纤激光切割机则…

面试题:JS中的String常见方法有哪些?

面试题&#xff1a;说不出五个就尴尬了&#xff01;我目前只写了几个方法&#xff0c;待更新中。。。 1、length2、slice()3、substr()4、substring()5、split()6、indexOf() 1、length 作用&#xff1a;检测字符串的长度。 let str abcde console.log(str.length) // 52、sl…

深入解读Gartner 2023中国数据、分析与AI技术成熟度曲线报告

近日&#xff0c;国际权威研究机构Gartner发布了《Hype Cycle for Data, Analytics and AI in China, 2023》&#xff08;2023中国数据、分析与AI技术成熟度曲线报告&#xff09;。作为业内的权威报告&#xff0c; Gartner 每年针对技术、应用和行业创建的技术成熟度曲线&#…

【WebRTC---源码篇】(二:一)PeerConnection详解

Track的添加 上图是整体流程图 RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(rtc::scoped_refptr<MediaStreamTrackInterface> track,const std::vector<std::string>& stream_ids) {RTC_DCHECK_RUN_ON(signal…

Linux(三)---------网络路由命令(route路由命令)

一.route路由命令 1.什么是route路由&#xff1f; 计算机之间的数据传输必须经过网络&#xff0c;网络可以直接两台计算机&#xff0c;也可以通过一个一个的节点去连接。路由可以理解为互联网的中转站&#xff0c;网络中的数据包就是通过一个一个的路由器转发到目的地的。 路…

【枚举边+树的直径】CF14D

Problem - 14D - Codeforces 题意&#xff1a; 思路&#xff1a; 两条链不相交&#xff0c;说明是在不同连通分量中&#xff0c;我们可以枚举边来把树分为两个连通分量&#xff0c;然后分别计算直径即可 Code&#xff1a; #include <bits/stdc.h>#define int long lo…

目标检测与跟踪 (1)- 机器人视觉与YOLO V8

目录 1、研究背景 2. 算法原理及对比 2.1 点对特征&#xff08;Point Pairs&#xff09; 2.2 模板匹配 2.3 霍夫森林 2.4 深度学习 3、YOLO家族模型演变 4、YOLO V8 1、研究背景 机器人视觉识别技术是移动机器人平台十分关键的技术&#xff0c;代表着机器人智能化、自动化…

XGBoost的参数空间与超参数优化

目录 1. 确定XGBoost的参数空间 2. 基于TEP对XGBoost进行优化 1. 确定XGBoost的参数空间 对任意集成算法进行超参数优化之前&#xff0c;我们需要明确两个基本事实&#xff1a;①不同参数对算法结果的影响力大小&#xff1b;②确定用于搜索的参数空间。对XGBoost来说&#x…

什么?仅使用配合功能就能让内燃机运动起来

配合作为SOLIDWORKS中装配体的重要命令&#xff0c;拥有着非常强大的功能。根据应用场合的不同软件将其分类为标准配合、高级配合和机械配合&#xff0c;按照这个顺序功能也越来越强大。本次使用内燃机的模型&#xff0c;将三个配合依次进行展示。 标准配合包含了常见的自由度约…

redis安装,开启自启动(Windows)

1、下载redis包 Releases tporadowski/redis GitHub 2、配置环境变量 path中添加redis解压后的路径&#xff1b; 3、配置文件修改 注释掉 bind 127.0.0.1 使其他ip可以远程访问&#xff1b; 修改redis密码 4、启动Redis服务 redis-server.exe --service-install redis.w…

如何让win10开机默认开启小键盘?

一、背景 省流版&#xff1a;直接看最后。 如题。 随便搜一搜&#xff0c;就会发现&#xff0c;有大量雷同&#xff0c;甚至内容完全相同的文章&#xff0c;然而并无卵用。 如&#xff1a; 如何让win10开机默认开启小键盘&#xff1f;【知乎】 如何让win10开机默认开启小键盘…

【网络】网络层(IP协议)

目录 一、基本概念 二、协议头格式 三、网段划分 四、特殊的IP地址 五、IP地址的数量限制 六、私有IP地址和公网IP地址 七、路由 一、基本概念 IP协议&#xff1a;提供一种能力&#xff0c; 将数据从A主机送到B主机&#xff0c;&#xff08;TCP协议&#xff1a;确保IP协议…

python去除重复图片(数据清洗)

其中1文件夹中有重复出现的图片,只是图片名不同。 2文件夹为空文件夹,用于保存去除的重复图。运行py文件。 import shutil import numpy as np from PIL import Image import osdef 比较图片大小(dir_image1, dir_image2):with open(dir_image1, "rb") as f1:size1…

postgresql 查询:查询是否在该列:一个字符串以“|”分割的列

上面是section 表中的link_laneid 的字段描述。 需求是&#xff1a;查询一个值是否在link_laneId 中存在&#xff08;注意这个值是个复合类型&#xff0c;以“|”分割的字符串&#xff09;。 sql语句&#xff1a; select * from section where 162243 any((string_to_arr…