各開發語言DNS快取配置建議
作者:翟賀龍
一、背景
在電腦領域,涉及效能最佳化動作時首先應被考慮的原則之一是使用緩存,合理的資料快取機制能夠帶來以下收益:
1.縮短資料擷取路徑,熱點資料就近快取以便後續快速讀取,從而明顯提升處理效率;
2.降低資料遠端取得頻次,緩解後端資料服務壓力、減少前端與後端之間的網路頻寬成本;
從CPU 硬體的多層快取設計,到瀏覽器快速展示頁面,再到大行其道的CDN、雲端儲存閘道等商業產品,處處應用了快取概念。
在公有網路領域,如作業系統、瀏覽器和行動裝置APP 等成熟產品所具備的快取機制,極大的消解了網路供應商如電信行動聯通、內容提供者如各大門戶平台和CDN 廠商直面的服務壓力,運營商的DNS 才能從容面對每秒億萬級的DNS 解析,網絡設備集群才能輕鬆承擔每秒Tbit 級的互聯網頻寬,CDN 平台才能快速處理每秒億萬次的請求。
面對公司目前龐大且仍在不斷成長的網域存取規模,筆者團隊在不斷優化叢集架構、提升DNS 軟體效能的同時,也迫切需要推動各類別客戶端環境進行域名解析請求機制的最佳化,因此,特組織團隊成員研究、編寫了這篇指南文章,以期為公司、客戶及合作方的前端開發維運人員給出合理建議,優化DNS 整體請求流程,為業務增效。
本文主要圍繞在不同業務和開發語言背景下,客戶端本地如何實現DNS 解析記錄緩存進行探討,同時基於筆者所在團隊對DNS 本身及公司網絡環境的掌握,給予一些其他措施,最終致力於客戶端一側的DNS 解析請求規範化。
二、名詞解釋
1. 客戶端
#本文所述客戶端,泛指所有主動發起網路請求的對象,包括但不限於伺服器、PC、行動終端、作業系統、命令列工具、腳本、服務軟體、使用者APP 等。
2. DNS
Domain Name System(Server/Service),網域名稱系統(伺服器/服務),可理解為一種類別資料庫服務;
客戶端同服務端進行網路通信,是靠IP 位址識別對方;而作為客戶端的使用者,人類很難記住大量IP 位址,所以發明了易於記憶的網域如www. jd.com,將網域名稱和IP 位址的對應關係,儲存到DNS 可供客戶端查詢;
#客戶端只有透過向DNS 發起網域名稱解析請求從而取得到服務端的IP位址後,才能向IP 位址發起網路通訊要求,真正取得網域所承載的服務或內容。
參考:網域系統網域解析流程
3. LDNS
Local DNS,本地網域名稱伺服器;公網路存取環境通常由所在網路供應商自動指派(供應商有控制權,甚至可作DNS 劫持,即篡改解析網域所得到的IP),內網環境由IT 部門設定自動指派;
通常Unix、類別Unix、MacOS系統可透過/etc/resolv.conf 查看自己的LDNS,在nameserver 後聲明,該檔案也支援用戶自助編輯修改,從而指定LDNS,如公網常見的公共DNS 如GoogleDNS、114DNS 等;純內網環境通常不建議未諮詢IT部門的情況下擅自修改,可能導致服務不可用;可參考 man resolv.conf 指令結果。
當網域解析出現異常時,同樣應考慮 LDNS 服務異常或發生解析劫持情況的可能。
參考:windows系統修改TCP/IP設定(含DNS);
##4. hostsDNS 系統可以動態的提供網域名稱和IP的映射關係,普遍存在於各類作業系統的hosts文件則是網域名稱和IP映射關係的靜態記錄文件,且通常hosts 記錄優先於DNS 解析,即本地無快取或快取未命中時,則優先透過hosts 查詢對應網域記錄,若hosts 無相關映射,則繼續發起DNS 請求。關於 Linux 環境下此邏輯的控制,請參考下文 C/C 語言 DNS 快取介紹部分。
所以在實際工作中,常利用上述預設特性,將特定網域名稱和特定IP 映射關係寫到hosts 檔案中(俗稱「固定hosts」),用於繞開DNS 解析過程,對目標IP作針對性存取(其效果與curl 的-x選項,或wget 的-e 指定proxy 選項,異曲同工);
5. TTL
Time-To -Live,生存時間值,此概念在多領域適用且可能有不同意義。
本文涉及到TTL 描述均針對資料快取而言,可直白理解為已快取資料的“有效期限”,從資料被快取開始計,在快取中存在時長超過TTL 規定時長的數據被視為過期數據,數據被再次調用時會立刻同權威數據源進行有效性確認或重新獲取。
因快取機制通常是被動觸發和更新,故在客戶端的快取有效期限內,後端原始權威資料若發生變更,客戶端不會感知,表現為業務上一定程度的資料更新延遲、快取資料與權威資料短時不一致。
對於客戶端側DNS 記錄的快取TTL,我們建議值為60s;同時如果是低敏感度業務例如測試、或網域解析調整不頻繁的業務,可適當延長,甚至達到小時或天級別;
三、DNS 解析最佳化建議
#1. 各語言網路庫對DNS 快取的支援研究
#以下調查結果,推薦開發人員參考,以實現自研客戶端DNS 快取。各開發語言對 DNS 快取支援可能不一樣,在此逐一分析。
C/C 語言
(1)glibc 的getaddrinfo 函數
Linux環境下的glibc 函式庫提供兩個網域解析的函數:gethostbyname 函數和getaddrinfo 函數,gethostbyname 是曾經常用的函數,但隨著向IPv6 和執行緒化程式設計模型的轉移,getaddrinfo 顯得更有用,因為它既解析IPv6 位址,又符合執行緒安全,建議使用getaddrinfo 函數。
函數原型:
int getaddrinfo( const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
getaddrinfo 函數是比較底層的基礎函式庫函數,許多開發語言的網域解析函數都依賴這個函數,因此我們在此介紹一下這個函數的處理邏輯。透過 strace 指令追蹤這個函式系統呼叫。
1)找出nscd 快取(nscd 介紹見後文)
我們在linux 環境下透過strace 指令可以看到如下的系統呼叫
//连接nscd socket(PF_LOCAL, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3 connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory) close(3)
透過unix socket 介面"/var/run/nscd/socket"連接nscd服務查詢DNS快取。
2)查詢/etc/hosts 文件
#如果nscd服務未啟動或快取未命中,繼續查詢hosts文件,我們應該可以看到如下的系統呼叫
//读取 hosts 文件 open("/etc/host.conf", O_RDONLY)= 3 fstat(3, {st_mode=S_IFREG|0644, st_size=9, ...}) = 0 ... open("/etc/hosts", O_RDONLY|O_CLOEXEC)= 3 fcntl(3, F_GETFD) = 0x1 (flags FD_CLOEXEC) fstat(3, {st_mode=S_IFREG|0644, st_size=178, ...}) = 0
3)查詢DNS 服務
從/etc/resolv.conf 配置中查詢到DNS 伺服器( nameserver)的IP位址,然後做DNS 查詢取得解析結果。我們可以看到如下系統呼叫
//获取 resolv.conf 中 DNS 服务 IP open("/etc/resolv.conf", O_RDONLY)= 3 fstat(3, {st_mode=S_IFREG|0644, st_size=25, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fef2abee000 read(3, "nameserver 114.114.114.114nn", 4096) = 25 ... //连到 DNS 服务,开始 DNS 查询 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("114.114.114.114")}, 16) = 0 poll([{fd=3, events=POLLOUT}], 1, 0)= 1 ([{fd=3, revents=POLLOUT}])
而關於客戶端是優先查找/etc/hosts 文件,還是優先從/etc/resolv.conf 中取得DNS 伺服器作查詢解析,是由/etc/nsswitch.conf 控制:
#/etc/nsswitch.conf 部分配置 ... #hosts: db files nisplus nis dns hosts:files dns ...
實際透過strace 指令可以看到,系統呼叫nscd socket 之後,讀取/etc/resolv.conf 之前,會讀取該檔案
newfstatat(AT_FDCWD, "/etc/nsswitch.conf", {st_mode=S_IFREG|0644, st_size=510, ...}, 0) = 0 ... openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
4)驗證
#include <sys/socket.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <unistd.h> int gethostaddr(char * name); int main(int argc, char *argv[]){ if (argc != 2) { fprintf(stderr, "%s $host", argv[0]); return -1; } int i = 0; for(i = 0; i < 5; i++) { int ret = -1; ret = gethostaddr(argv[1]); if (ret < 0) { fprintf(stderr, "%s $host", argv[0]); return -1; } //sleep(5); } return 0; } int gethostaddr(char* name){ struct addrinfo hints; struct addrinfo *result; struct addrinfo *curr; int ret = -1; char ipstr[INET_ADDRSTRLEN]; struct sockaddr_in*ipv4; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; ret = getaddrinfo(name, NULL, &hints, &result); if (ret != 0) { fprintf(stderr, "getaddrinfo: %sn", gai_strerror(ret)); return ret; } for (curr = result; curr != NULL; curr = curr->ai_next) { ipv4 = (struct sockaddr_in *)curr->ai_addr; inet_ntop(curr->ai_family, &ipv4->sin_addr, ipstr, INET_ADDRSTRLEN); printf("ipaddr:%sn", ipstr); } freeaddrinfo(result); return 0; }
綜上分析,getaddrinfo 函數結合nscd ,是可以實作DNS 快取的。
(2)libcurl 函式庫的網域解析函數
#libcurl 函式庫是c/c 語言下,客戶端比較常用的網路傳輸庫,curl 指令就是基於這個函式庫實作。這個函式庫也是呼叫 getaddrinfo 函式庫函數實作 DNS 網域解析,也是支援 nscd DNS 快取的。
int Curl_getaddrinfo_ex(const char *nodename, const char *servname, const struct addrinfo *hints, Curl_addrinfo **result) { ... error = getaddrinfo(nodename, servname, hints, &aihead); if(error) return error; ... }
Java
Java 語言是許多公司業務系統開發的主要語言,透過編寫簡單的HTTP 用戶端程式測試來驗證Java 的網路庫是否支援DNS 緩存。測試驗證了 Java 標準函式庫中 HttpURLConnection 和 Apache httpcomponents-client 這兩個元件。
(1)Java 標準函式庫 HttpURLConnection
#import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; public class HttpUrlConnectionDemo { public static void main(String[] args) throws Exception { String urlString = "http://example.my.com/"; int num = 0; while (num < 5) { URL url = new URL(urlString); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setDoOutput(true); OutputStream os = conn.getOutputStream(); os.flush(); os.close(); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream is = conn.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder sb = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { sb.append(line); } System.out.println("rsp:" + sb.toString()); } else { System.out.println("rsp code:" + conn.getResponseCode()); } num++; } } }
测试结果显示 Java 标准库 HttpURLConnection 是支持 DNS 缓存,5 次请求中只有一次 DNS 请求。
(2)Apache httpcomponents-client
import java.util.ArrayList; import java.util.List; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.entity.UrlEncodedFormEntity; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.core5.http.HttpEntity; import org.apache.hc.core5.http.NameValuePair; import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.message.BasicNameValuePair; public class QuickStart { public static void main(final String[] args) throws Exception { int num = 0; while (num < 5) { try (final CloseableHttpClient httpclient = HttpClients.createDefault()) { final HttpGet httpGet = new HttpGet("http://example.my.com/"); try (final CloseableHttpResponse response1 = httpclient.execute(httpGet)) { System.out.println(response1.getCode() + " " + response1.getReasonPhrase()); final HttpEntity entity1 = response1.getEntity(); EntityUtils.consume(entity1); } } num++; } } }
测试结果显示 Apache httpcomponents-client 支持 DNS 缓存,5 次请求中只有一次 DNS 请求。
从测试中发现 Java 的虚拟机实现一套 DNS 缓存,即实现在 java.net.InetAddress 的一个简单的 DNS 缓存机制,默认为缓存 30 秒,可以通过 networkaddress.cache.ttl 修改默认值,缓存范围为 JVM 虚拟机进程,也就是说同一个 JVM 进程中,30秒内一个域名只会请求DNS服务器一次。同时 Java 也是支持 nscd 的 DNS 缓存,估计底层调用 getaddrinfo 函数,并且 nscd 的缓存级别比 Java 虚拟机的 DNS 缓存高。
# 默认缓存 ttl 在 jre/lib/security/java.security 修改,其中 0 是不缓存,-1 是永久缓存 networkaddress.cache.ttl=10 # 这个参数 sun.net.inetaddr.ttl 是以前默认值,目前已经被 networkaddress.cache.ttl 取代
Go
随着云原生技术的发展,Go 语言逐渐成为云原生的第一语言,很有必要验证一下 Go 的标准库是否支持 DNS 缓存。通过我们测试验证发现 Go 的标准库 net.http 是不支持 DNS 缓存,也是不支持 nscd 缓存,应该是没有调用 glibc 的库函数,也没有实现类似 getaddrinfo 函数的功能。这个跟 Go语言的自举有关系,Go 从 1.5 开始就基本全部由 Go(.go) 和汇编 (.s) 文件写成的,以前版本的 C(.c) 文件被全部重写。不过有一些第三方 Go 版本 DNS 缓存库,可以自己在应用层实现,还可以使用 fasthttp 库的 httpclient。
(1)标准库net.http
package main import ( "flag" "fmt" "io/ioutil" "net/http" "time" ) var httpUrl string func main() { flag.StringVar(&httpUrl, "url", "", "url") flag.Parse() getUrl := fmt.Sprintf("http://%s/", httpUrl) fmt.Printf("url: %sn", getUrl) for i := 0; i < 5; i++ { _, buf, err := httpGet(getUrl) if err != nil { fmt.Printf("err: %vn", err) return } fmt.Printf("resp: %sn", string(buf)) time.Sleep(10 * time.Second)# 等待10s发起另一个请求 } } func httpGet(url string) (int, []byte, error) { client := createHTTPCli() resp, err := client.Get(url) if err != nil { return -1, nil, fmt.Errorf("%s err [%v]", url, err) } defer resp.Body.Close() buf, err := ioutil.ReadAll(resp.Body) if err != nil { return resp.StatusCode, buf, err } return resp.StatusCode, buf, nil } func createHTTPCli() *http.Client { readWriteTimeout := time.Duration(30) * time.Second tr := &http.Transport{ DisableKeepAlives: true,//设置短连接 IdleConnTimeout: readWriteTimeout, } client := &http.Client{ Timeout: readWriteTimeout, Transport: tr, } return client }
从测试结果来看,net.http 每次都去 DNS 查询,不支持 DNS 缓存。
(2)fasthttp 库
fasthttp 库是 Go 版本高性能 HTTP 库,通过极致的性能优化,性能是标准库 net.http 的 10 倍,其中一项优化就是支持 DNS 缓存,我们可以从其源码看到
//主要在fasthttp/tcpdialer.go中 type TCPDialer struct { ... // This may be used to override DNS resolving policy, like this: // var dialer = &fasthttp.TCPDialer{ //Resolver: &net.Resolver{ //PreferGo: true, //StrictErrors: false, //Dial: func (ctx context.Context, network, address string) (net.Conn, error) { //d := net.Dialer{} //return d.DialContext(ctx, "udp", "8.8.8.8:53") //}, //}, // } Resolver Resolver // DNSCacheDuration may be used to override the default DNS cache duration (DefaultDNSCacheDuration) DNSCacheDuration time.Duration ... }
可以参考如下方法使用 fasthttp client 端
func main() { // You may read the timeouts from some config readTimeout, _ := time.ParseDuration("500ms") writeTimeout, _ := time.ParseDuration("500ms") maxIdleConnDuration, _ := time.ParseDuration("1h") client = &fasthttp.Client{ ReadTimeout: readTimeout, WriteTimeout:writeTimeout, MaxIdleConnDuration: maxIdleConnDuration, NoDefaultUserAgentHeader:true, // Don't send: User-Agent: fasthttp DisableHeaderNamesNormalizing: true, // If you set the case on your headers correctly you can enable this DisablePathNormalizing:true, // increase DNS cache time to an hour instead of default minute Dial: (&fasthttp.TCPDialer{ Concurrency:4096, DNSCacheDuration: time.Hour, }).Dial, } sendGetRequest() sendPostRequest() }
(3)第三方DNS缓存库
这个是 github 中的一个 Go 版本 DNS 缓存库
可以参考如下代码,在HTTP库中支持DNS缓存
r := &dnscache.Resolver{} t := &http.Transport{ DialContext: func(ctx context.Context, network string, addr string) (conn net.Conn, err error) { host, port, err := net.SplitHostPort(addr) if err != nil { return nil, err } ips, err := r.LookupHost(ctx, host) if err != nil { return nil, err } for _, ip := range ips { var dialer net.Dialer conn, err = dialer.DialContext(ctx, network, net.JoinHostPort(ip, port)) if err == nil { break } } return }, }
Python
(1)requests 库
#!/bin/python import requests url = 'http://example.my.com/' num = 0 while num < 5: headers={"Connection":"close"} # 开启短连接 r = requests.get(url,headers = headers) print(r.text) num +=1
(2)httplib2 库
#!/usr/bin/env python import httplib2 http = httplib2.Http() url = 'http://example.my.com/' num = 0 while num < 5: loginHeaders={ 'User-Agent': 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.0 Chrome/30.0.1599.101 Safari/537.36', 'Connection': 'close'# 开启短连接 } response, content = http.request(url, 'GET', headers=loginHeaders) print(response) print(content) num +=1
(3)urllib2 库
#!/bin/python import urllib2 import cookielib httpHandler = urllib2.HTTPHandler(debuglevel=1) httpsHandler = urllib2.HTTPSHandler(debuglevel=1) opener = urllib2.build_opener(httpHandler, httpsHandler) urllib2.install_opener(opener) loginHeaders={ 'User-Agent': 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.0 Chrome/30.0.1599.101 Safari/537.36', 'Connection': 'close' # 开启短连接 } num = 0 while num < 5: request=urllib2.Request('http://example.my.com/',headers=loginHeaders) response = urllib2.urlopen(request) page='' page= response.read() print response.info() print page num +=1
Python 测试三种库都是支持 nscd 的 DNS 缓存的(推测底层也是调用 getaddrinfo 函数),以上测试时使用 HTTP 短连接,都在 python2 环境测试。
总结
针对 HTTP 客户端来说,可以优先开启 HTTP 的 keep-alive 模式,可以复用 TCP 连接,这样可以减少 TCP 握手耗时和重复请求域名解析,然后再开启 nscd 缓存,除了 Go 外,C/C++、Java、Python 都可支持 DNS 缓存,减少 DNS查询耗时。
这里只分析了常用 C/C++、Java、Go、Python 语言,欢迎熟悉其他语言的小伙伴补充。
2. Unix/类 Unix 系统常用 dns 缓存服务:
在由于某些特殊原因,自研或非自研客户端本身无法提供 DNS 缓存支持的情况下,建议管理人员在其所在系统环境中部署DNS缓存程序;
现介绍 Unix/类 Unix 系统适用的几款常见轻量级 DNS 缓存程序。而多数桌面操作系统如 Windows、MacOS 和几乎所有 Web 浏览器均自带 DNS 缓存功能,本文不再赘述。
P.S. DNS 缓存服务请务必确保随系统开机启动;
nscd
name service cache daemon 即装即用,通常为 linux 系统默认安装,相关介绍可参考其 manpage:man nscd;man nscd.conf
(1)安装方法:通过系统自带软件包管理程序安装,如 yum install nscd
(2)缓存管理(清除):
1.service nscd restart 重启服务清除所有缓存;
2.nscd -i hosts 清除 hosts 表中的域名缓存(hosts 为域名缓存使用的 table 名称,nscd 有多个缓存 table,可参考程序相关 manpage)
dnsmasq
较为轻量,可选择其作为 nscd 替代,通常需单独安装
(1)安装方法:通过系统自带软件包管理程序安装,如 yum install dnsmasq
(2)核心文件介绍(基于 Dnsmasq version 2.86,较低版本略有差异,请参考对应版本文档如 manpage 等)
(3)/etc/default/dnsmasq 提供六个变量定义以支持六种控制类功能
(4)/etc/dnsmasq.d/ 此目录含 README 文件,可参考;目录内可以存放自定义配置文件
(5)/etc/dnsmasq.conf 主配置文件,如仅配置 dnsmasq 作为缓存程序,可参考以下配置
listen-address=127.0.0.1#程序监听地址,务必指定本机内网或回环地址,避免暴露到公网环境 port=53 #监听端口 resolv-file=/etc/dnsmasq.d/resolv.conf#配置dnsmasq向自定义文件内的 nameserver 转发 dns 解析请求 cache-size=150#缓存记录条数,默认 150 条,可按需调整、适当增大 no-negcache #不缓存解析失败的记录,主要是 NXDOMAIN,即域名不存在 log-queries=extra #开启日志记录,指定“=extra”则记录更详细信息,可仅在问题排查时开启,平时关闭 log-facility=/var/log/dnsmasq.log #指定日志文件 #同时需要将本机 /etc/resolv.conf 第一个 nameserver 指定为上述监听地址,这样本机系统的 dns 查询请求才会通过 dnsmasq 代为转发并缓存响应结果。 #另 /etc/resolv.conf 务必额外配置 2 个 nameserver,以便 dnsmasq 服务异常时支持系统自动重试,注意 resolv.conf 仅读取前 3 个 nameserver
(6)缓存管理(清除):
1.kill -s HUP `pidof dnsmasq` 推荐方式,无需重启服务
2.kill -s TERM `pidof dnsmasq` 或 service dnsmasq stop
3.service dnsmasq force-reload 或 service dnsmasq restart
(7)官方文档:https://thekelleys.org.uk/dnsmasq/doc.html
3. 纯内网业务取消查询域名的AAAA记录的请求
以 linux 操作系统为例,常用的网络请求命令行工具常常通过调用 getaddrinfo() 完成域名解析过程,如 ping、telnet、curl、wget 等,但其可能出于通用性的考虑,均被设计为对同一个域名每次解析会发起两个请求,分别查询域名 A 记录(即 IPV4 地址)和 AAAA 记录(即 IPV6 地址)。
因目前大部分公司的内网环境及云上内网环境还未使用 ipv6 网络,故通常 DNS 系统不为内网域名添加 AAAA 记录,徒劳请求域名的 AAAA 记录会造成前端应用和后端 DNS 服务不必要的资源开销。因此,仅需请求内网域名的业务,如决定自研客户端,建议开发人员视实际情况,可将其设计为仅请求内网域名 A 记录,尤其当因故无法实施本地缓存机制时。
4. 规范域名处理逻辑
客户端需严格规范域名/主机名的处理逻辑,避免产生大量对不存在域名的解析请求(确保域名从权威渠道获取,避免故意或意外使用随机构造的域名、主机名),因此类请求的返回结果(NXDOMAIN)通常不被缓存或缓存时长较短,且会触发客户端重试,对后端 DNS 系统造成一定影响。
以上是各開發語言DNS快取配置建議的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

報錯的原因NameResolutionError(self.host,self,e)frome是由urllib3函式庫中的例外類型,這個錯誤的原因是DNS解析失敗,也就是說,試圖解析的主機名稱或IP位址無法找到。這可能是由於輸入的URL位址不正確,或DNS伺服器暫時無法使用所導致的。如何解決解決此錯誤的方法可能有以下幾種:檢查輸入的URL地址是否正確,確保它是可訪問的確保DNS伺服器可用,您可以嘗試在命令行中使用"ping"命令來測試DNS伺服器是否可用嘗試使用IP位址而不是主機名稱來存取網站如果是在代理

DNS(DomainNameSystem)是網際網路中用來將網域名稱轉換為對應IP位址的系統。在Linux系統中,DNS快取是一種將網域名稱和IP位址的映射關係儲存在本地的機制,可提高網域解析速度,減輕DNS伺服器的負擔。 DNS快取允許系統在之後存取相同網域名稱時快速檢索IP位址,而不必每次都向DNS伺服器發出查詢請求,從而提高網路效能和效率。本文不念將和大家一起探討如何在Linux上查看和刷新DNS緩存,以及相關的詳細內容和範例程式碼。 DNS快取的重要性在Linux系統中,DNS快取扮演關鍵的角色。它的存在

想必有很多的用戶都發現自己的網路不知道為什麼有點卡頓,在搜尋之後發現修改dns很多的用戶說不卡頓了,就想要了解一下修改dns有什麼好處?那就來文中看看吧。 win11修改dns位址有什麼用答:總共有4點好處。 1.網路存取速度變得更加的快速。 2.能夠幫助使用者保證自己造訪的網站是安全的。 3.也可以幫助使用者預防自己的dns被劫持。 4.部分的使用者在發現自己上不了某個網站的時候更改dns也可以直接連結上網站。

CPU(中央處理器)、記憶體(隨機存取記憶體)以及快取之間存在著緊密的相互作用,它們合力構成了電腦系統的關鍵組成部分。它們之間的協調配合,確保了電腦的正常運作和高效性能。 CPU作為電腦的大腦,負責執行各種指令和資料處理;記憶體則用於臨時儲存資料和程序,提供了快速的讀寫存取速度;而快取則起到了緩衝作用,加快了資料的存取速度,提高了電腦的CPU是電腦的核心元件,負責執行各種指令、算術運算和邏輯操作。它被稱為電腦的"大腦",承擔著處理資料和執行任務的重要角色。記憶體是電腦中重要的儲存設備,

PHPAPCu(替代php快取)是加速PHP應用程式的opcode快取和資料快取模組。理解其高級功能對於充分利用其潛力至關重要。 1.批次操作:APCu提供批次操作方法,可同時處理大量鍵值對。這對於大規模快取清除或更新非常有用。 //批次取得快取鍵$values=apcu_fetch(["key1","key2","key3"]);//批次清除快取鍵apcu_delete(["key1","key2","key3"]);2 .設定快取過期時間:APCu允許您為快取項目設定過期時間,以便在指定時間後自

SpringBoot是一款廣受歡迎的Java框架,以其簡單易用和快速開發而聞名。然而,隨著應用程式的複雜性增加,效能問題可能會成為瓶頸。為了幫助您打造疾風般快速的springBoot應用,本文將分享一些實用的效能優化秘訣。優化啟動時間應用程式的啟動時間是使用者體驗的關鍵因素之一。 SpringBoot提供了多種最佳化啟動時間的途徑,例如使用快取、減少日誌輸出和最佳化類別路徑掃描。您可以透過在application.properties檔案中設定spring.main.lazy-initialization

基於大模型的持續最佳化,LLM智能體-這些強大的演算法實體已經展現出解決複雜多步驟推理任務的潛力。從自然語言處理到深度學習,LLM智能體正逐漸成為研究和工業界的焦點,它們不僅能理解和生成人類語言,還能在多樣的環境中製定策略、執行任務,甚至使用API調用和編碼來建置解決方案。在這種背景下,AgentQuest框架的提出具有里程碑意義,它不僅僅是一個LLM智能體的評估和進步提供了一個模組化的基準測試平台,而且透過其易於擴展的API,為研究人員提供了一個強大的工具,以更細緻地追蹤和改進這些智能體的性能

瀏覽器快取的影片怎麼匯出來隨著網路的快速發展,影片已經成為人們日常生活中不可或缺的一部分。而在瀏覽網頁時,我們常常會遇到想要儲存或分享的影片內容,但是有時候我們卻無法找到影片檔案的來源,因為它們可能只存在於瀏覽器的快取中。那麼,如何匯出瀏覽器快取中的影片呢?本文將為您介紹幾種常用的方法。首先,我們需要明確一個概念,即瀏覽器快取。瀏覽器快取是瀏覽器為了提高用
