哈哈哈哈哈操欧洲电影,久草网在线,亚洲久久熟女熟妇视频,麻豆精品色,久久福利在线视频,日韩中文字幕的,淫乱毛视频一区,亚洲成人一二三,中文人妻日韩精品电影

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

各開發(fā)語(yǔ)言DNS緩存配置建議

OSC開源社區(qū) ? 來(lái)源:京東云開發(fā)者 ? 作者: 翟賀龍 ? 2022-12-16 09:45 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1、背景

在計(jì)算機(jī)領(lǐng)域,涉及性能優(yōu)化動(dòng)作時(shí)首先應(yīng)被考慮的原則之一便是使用緩存,合理的數(shù)據(jù)緩存機(jī)制能夠帶來(lái)以下收益:

1)縮短數(shù)據(jù)獲取路徑,熱點(diǎn)數(shù)據(jù)就近緩存以便后續(xù)快速讀取,從而明顯提升處理效率;

2)降低數(shù)據(jù)遠(yuǎn)程獲取頻次,緩解后端數(shù)據(jù)服務(wù)壓力、減少前端和后端之間的網(wǎng)絡(luò)帶寬成本;

CPU 硬件的多級(jí)緩存設(shè)計(jì),到瀏覽器快速展示頁(yè)面,再到大行其道的 CDN、云存儲(chǔ)網(wǎng)關(guān)等商業(yè)產(chǎn)品,處處應(yīng)用了緩存理念。

在公網(wǎng)領(lǐng)域,如操作系統(tǒng)、瀏覽器和移動(dòng)端 APP 等成熟產(chǎn)品所具備的緩存機(jī)制,極大的消解了網(wǎng)絡(luò)提供商如電信移動(dòng)聯(lián)通、內(nèi)容提供商如各大門戶平臺(tái)和 CDN 廠商直面的服務(wù)壓力,運(yùn)營(yíng)商的 DNS 才能從容面對(duì)每秒億萬(wàn)級(jí)的 DNS 解析,網(wǎng)絡(luò)設(shè)備集群才能輕松承擔(dān)每秒 Tbit 級(jí)的互聯(lián)網(wǎng)帶寬,CDN 平臺(tái)才能快速處理每秒億萬(wàn)次的請(qǐng)求。

面對(duì)公司目前龐大且仍在不斷增長(zhǎng)的的域名接入規(guī)模,筆者所在團(tuán)隊(duì)在不斷優(yōu)化集群架構(gòu)、提升 DNS 軟件性能的同時(shí),也迫切需要推動(dòng)各類客戶端環(huán)境進(jìn)行域名解析請(qǐng)求機(jī)制的優(yōu)化,因此,特組織團(tuán)隊(duì)成員調(diào)研、編寫了這篇指南文章,以期為公司、客戶及合作方的前端開發(fā)運(yùn)維人員給出合理建議,優(yōu)化 DNS 整體請(qǐng)求流程,為業(yè)務(wù)增效。

本文主要圍繞不同業(yè)務(wù)和開發(fā)語(yǔ)言背景下,客戶端本地如何實(shí)現(xiàn) DNS 解析記錄緩存進(jìn)行探討,同時(shí)基于筆者所在團(tuán)隊(duì)對(duì) DNS 本身及公司網(wǎng)絡(luò)環(huán)境的掌握,給出一些其他措施,最終致力于客戶端一側(cè)的 DNS 解析請(qǐng)求規(guī)范化。

2、名詞解釋

1. 客戶端

本文所述客戶端,泛指所有主動(dòng)發(fā)起網(wǎng)絡(luò)請(qǐng)求的對(duì)象,包括但不限于服務(wù)器、PC、移動(dòng)終端、操作系統(tǒng)、命令行工具、腳本、服務(wù)軟件、用戶 APP 等。

2. DNS

Domain Name System(Server/Service),域名系統(tǒng)(服務(wù)器/服務(wù)),可理解為一種類數(shù)據(jù)庫(kù)服務(wù);

客戶端同服務(wù)端進(jìn)行網(wǎng)絡(luò)通信,是靠 IP 地址識(shí)別對(duì)方;而作為客戶端的使用者,人類很難記住大量 IP 地址,所以發(fā)明了易于記憶的域名如 www.jd.com,將域名和 IP 地址的映射關(guān)系,存儲(chǔ)到 DNS 可供客戶端查詢;

客戶端只有通過(guò)向 DNS 發(fā)起域名解析請(qǐng)求從而獲取到服務(wù)端的 IP 地址后,才能向 IP 地址發(fā)起網(wǎng)絡(luò)通信請(qǐng)求,真正獲取到域名所承載的服務(wù)或內(nèi)容。

參考:域名系統(tǒng) ?域名解析流程?

3. LDNS

Local DNS,本地域名服務(wù)器;公網(wǎng)接入環(huán)境通常由所在網(wǎng)絡(luò)供應(yīng)商自動(dòng)分配(供應(yīng)商有控制權(quán),甚至可作 DNS 劫持,即篡改解析域名得到的 IP),內(nèi)網(wǎng)環(huán)境由 IT 部門設(shè)置自動(dòng)分配;

通常 Unix、類Unix、MacOS系統(tǒng)可通過(guò) /etc/resolv.conf 查看自己的 LDNS,在 nameserver 后聲明,該文件亦支持用戶自助編輯修改,從而指定 LDNS,如公網(wǎng)常見的公共 DNS 如谷歌 DNS、114DNS 等;純內(nèi)網(wǎng)環(huán)境通常不建議未咨詢IT部門的情況下擅自修改,可能導(dǎo)致服務(wù)不可用;可參考 man resolv.conf 指令結(jié)果。

當(dāng)域名解析出現(xiàn)異常時(shí),同樣應(yīng)考慮 LDNS 服務(wù)異?;虬l(fā)生解析劫持情況的可能。

參考:windows系統(tǒng)修改TCP/IP設(shè)置(含DNS);

4. hosts

DNS 系統(tǒng)可以動(dòng)態(tài)的提供域名和IP的映射關(guān)系,普遍存在于各類操作系統(tǒng)的hosts文件則是域名和IP映射關(guān)系的靜態(tài)記錄文件,且通常 hosts 記錄優(yōu)先于 DNS 解析,即本地?zé)o緩存或緩存未命中時(shí),則優(yōu)先通過(guò) hosts 查詢對(duì)應(yīng)域名記錄,若 hosts 無(wú)相關(guān)映射,則繼續(xù)發(fā)起 DNS 請(qǐng)求。關(guān)于 Linux 環(huán)境下此邏輯的控制,請(qǐng)參考下文 C/C++ 語(yǔ)言 DNS 緩存介紹部分。

所以在實(shí)際工作中,常利用上述默認(rèn)特性,將特定域名和特定 IP 映射關(guān)系寫到 hosts 文件中(俗稱“固定 hosts”),用于繞開 DNS 解析過(guò)程,對(duì)目標(biāo) IP 作針對(duì)性訪問(wèn)(其效果與 curl 的-x選項(xiàng),或 wget 的 -e 指定 proxy 選項(xiàng),異曲同工);

5. TTL

Time-To-Live,生存時(shí)間值,此概念在多領(lǐng)域適用且可能有不同意義。

本文涉及到 TTL 描述均針對(duì)數(shù)據(jù)緩存而言,可直白理解為已緩存數(shù)據(jù)的“有效期”,從數(shù)據(jù)被緩存開始計(jì),在緩存中存在時(shí)長(zhǎng)超過(guò) TTL 規(guī)定時(shí)長(zhǎng)的數(shù)據(jù)被視為過(guò)期數(shù)據(jù),數(shù)據(jù)被再次調(diào)用時(shí)會(huì)立刻同權(quán)威數(shù)據(jù)源進(jìn)行有效性確認(rèn)或重新獲取。

因緩存機(jī)制通常是被動(dòng)觸發(fā)和更新,故在客戶端的緩存有效期內(nèi),后端原始權(quán)威數(shù)據(jù)若發(fā)生變更,客戶端不會(huì)感知,表現(xiàn)為業(yè)務(wù)上一定程度的數(shù)據(jù)更新延遲、緩存數(shù)據(jù)與權(quán)威數(shù)據(jù)短時(shí)不一致。

對(duì)于客戶端側(cè) DNS 記錄的緩存 TTL,我們建議值為 60s;同時(shí)如果是低敏感度業(yè)務(wù)比如測(cè)試、或域名解析調(diào)整不頻繁的業(yè)務(wù),可適當(dāng)延長(zhǎng),甚至達(dá)到小時(shí)或天級(jí)別;

3、DNS解析優(yōu)化建議

3.1 各語(yǔ)言網(wǎng)絡(luò)庫(kù)對(duì) DNS 緩存的支持調(diào)研

以下調(diào)研結(jié)果,推薦開發(fā)人員參考,以實(shí)現(xiàn)自研客戶端 DNS 緩存。各開發(fā)語(yǔ)言對(duì) DNS 緩存支持可能不一樣,在此逐個(gè)分析一下。

C/C++ 語(yǔ)言

(1) glibc 的 getaddrinfo 函數(shù)

Linux環(huán)境下的 glibc 庫(kù)提供兩個(gè)域名解析的函數(shù):gethostbyname 函數(shù)和 getaddrinfo 函數(shù),gethostbyname 是曾經(jīng)常用的函數(shù),但是隨著向 IPv6 和線程化編程模型的轉(zhuǎn)移,getaddrinfo 顯得更有用,因?yàn)樗冉馕?IPv6 地址,又符合線程安全,推薦使用 getaddrinfo 函數(shù)。

函數(shù)原型:

int getaddrinfo( const char *node, 
                 const char *service,
                 const struct addrinfo *hints,
                 struct addrinfo **res);

getaddrinfo 函數(shù)是比較底層的基礎(chǔ)庫(kù)函數(shù),很多開發(fā)語(yǔ)言的域名解析函數(shù)都依賴這個(gè)函數(shù),因此我們?cè)诖私榻B一下這個(gè)函數(shù)的處理邏輯。通過(guò) strace 命令跟蹤這個(gè)函數(shù)系統(tǒng)調(diào)用。

44880332-7ce2-11ed-8abf-dac502259ad0.jpg

1)查找 nscd 緩存(nscd 介紹見后文)

我們?cè)?linux 環(huán)境下通過(guò) strace 命令可以看到如下的系統(tǒng)調(diào)用

//連接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)

通過(guò) unix socket 接口"/var/run/nscd/socket"連接nscd服務(wù)查詢DNS緩存。

2)查詢 /etc/hosts 文件

如果nscd服務(wù)未啟動(dòng)或緩存未命中,繼續(xù)查詢hosts文件,我們應(yīng)該可以看到如下的系統(tǒng)調(diào)用

//讀取 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 服務(wù)

從 /etc/resolv.conf 配置中查詢到 DNS 服務(wù)器(nameserver)的IP地址,然后做 DNS 查詢獲取解析結(jié)果。我們可以看到如下系統(tǒng)調(diào)用

//獲取 resolv.conf 中 DNS 服務(wù) 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.114

", 4096) = 25
...
//連到 DNS 服務(wù),開始 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}])

而關(guān)于客戶端是優(yōu)先查找 /etc/hosts 文件,還是優(yōu)先從 /etc/resolv.conf 中獲取 DNS 服務(wù)器作查詢解析,是由 /etc/nsswitch.conf 控制:
#/etc/nsswitch.conf 部分配置
...
#hosts:     db files nisplus nis dns
hosts:      files dns
...

實(shí)際通過(guò) strace 命令可以看到,系統(tǒng)調(diào)用 nscd socket 之后,讀取 /etc/resolv.conf 之前,會(huì)讀取該文件
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)驗(yàn)證
#include 
#include 
#include 
#include 
#include 
#include 
#include 


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: %s
", 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:%s
", ipstr);
    }


    freeaddrinfo(result);
    return 0;
}

綜上分析,getaddrinfo 函數(shù)結(jié)合 nscd ,是可以實(shí)現(xiàn) DNS 緩存的。

(2)libcurl 庫(kù)的域名解析函數(shù)

libcurl 庫(kù)是 c/c++ 語(yǔ)言下,客戶端比較常用的網(wǎng)絡(luò)傳輸庫(kù),curl 命令就是基于這個(gè)庫(kù)實(shí)現(xiàn)。這個(gè)庫(kù)也是調(diào)用 getaddrinfo 庫(kù)函數(shù)實(shí)現(xiàn) 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 語(yǔ)言是很多公司業(yè)務(wù)系統(tǒng)開發(fā)的主要語(yǔ)言,通過(guò)編寫簡(jiǎn)單的 HTTP 客戶端程序測(cè)試驗(yàn)證 Java 的網(wǎng)絡(luò)庫(kù)是否支持 DNS 緩存。測(cè)試驗(yàn)證了 Java 標(biāo)準(zhǔn)庫(kù)中 HttpURLConnection 和 Apache httpcomponents-client 這兩個(gè)組件。

(1)Java 標(biāo)準(zhǔn)庫(kù) 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++;
        }
    }
}

測(cè)試結(jié)果顯示 Java 標(biāo)準(zhǔn)庫(kù) HttpURLConnection 是支持 DNS 緩存,5 次請(qǐng)求中只有一次 DNS 請(qǐng)求。

(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++;
        }
    }
}

測(cè)試結(jié)果顯示 Apache httpcomponents-client 支持 DNS 緩存,5 次請(qǐng)求中只有一次 DNS 請(qǐng)求。

從測(cè)試中發(fā)現(xiàn) Java 的虛擬機(jī)實(shí)現(xiàn)一套 DNS 緩存,即實(shí)現(xiàn)在 java.net.InetAddress 的一個(gè)簡(jiǎn)單的 DNS 緩存機(jī)制,默認(rèn)為緩存 30 秒,可以通過(guò) networkaddress.cache.ttl 修改默認(rèn)值,緩存范圍為 JVM 虛擬機(jī)進(jìn)程,也就是說(shuō)同一個(gè) JVM 進(jìn)程中,30秒內(nèi)一個(gè)域名只會(huì)請(qǐng)求DNS服務(wù)器一次。同時(shí) Java 也是支持 nscd 的 DNS 緩存,估計(jì)底層調(diào)用 getaddrinfo 函數(shù),并且 nscd 的緩存級(jí)別比 Java 虛擬機(jī)的 DNS 緩存高。

# 默認(rèn)緩存 ttl 在 jre/lib/security/java.security 修改,其中 0 是不緩存,-1 是永久緩存
networkaddress.cache.ttl=10


# 這個(gè)參數(shù) sun.net.inetaddr.ttl 是以前默認(rèn)值,目前已經(jīng)被 networkaddress.cache.ttl 取代

Go

隨著云原生技術(shù)的發(fā)展,Go 語(yǔ)言逐漸成為云原生的第一語(yǔ)言,很有必要驗(yàn)證一下 Go 的標(biāo)準(zhǔn)庫(kù)是否支持 DNS 緩存。通過(guò)我們測(cè)試驗(yàn)證發(fā)現(xiàn) Go 的標(biāo)準(zhǔn)庫(kù) net.http 是不支持 DNS 緩存,也是不支持 nscd 緩存,應(yīng)該是沒(méi)有調(diào)用 glibc 的庫(kù)函數(shù),也沒(méi)有實(shí)現(xiàn)類似 getaddrinfo 函數(shù)的功能。這個(gè)跟 Go語(yǔ)言的自舉有關(guān)系,Go 從 1.5 開始就基本全部由 Go(.go) 和匯編 (.s) 文件寫成的,以前版本的 C(.c) 文件被全部重寫。不過(guò)有一些第三方 Go 版本 DNS 緩存庫(kù),可以自己在應(yīng)用層實(shí)現(xiàn),還可以使用 fasthttp 庫(kù)的 httpclient。

(1)標(biāo)準(zhǔn)庫(kù)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: %s
", getUrl)
    for i := 0; i < 5; i++ {
        _, buf, err := httpGet(getUrl)
        if err != nil {
            fmt.Printf("err: %v
", err)
            return
        }
        fmt.Printf("resp: %s
", string(buf))
        time.Sleep(10 * time.Second)    # 等待10s發(fā)起另一個(gè)請(qǐng)求
    }
}


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,  //設(shè)置短連接
        IdleConnTimeout:   readWriteTimeout,
    }
    client := &http.Client{
        Timeout:   readWriteTimeout,
        Transport: tr,
    }
    return client
}

從測(cè)試結(jié)果來(lái)看,net.http 每次都去 DNS 查詢,不支持 DNS 緩存。

(2)fasthttp 庫(kù)

fasthttp 庫(kù)是 Go 版本高性能 HTTP 庫(kù),通過(guò)極致的性能優(yōu)化,性能是標(biāo)準(zhǔn)庫(kù) net.http 的 10 倍,其中一項(xiàng)優(yōu)化就是支持 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緩存庫(kù)

這個(gè)是 github 中的一個(gè) Go 版本 DNS 緩存庫(kù)?

可以參考如下代碼,在HTTP庫(kù)中支持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 庫(kù)

#!/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 庫(kù)
#!/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 庫(kù)

#!/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 測(cè)試三種庫(kù)都是支持 nscd 的 DNS 緩存的(推測(cè)底層也是調(diào)用 getaddrinfo 函數(shù)),以上測(cè)試時(shí)使用 HTTP 短連接,都在 python2 環(huán)境測(cè)試。

總結(jié)

針對(duì) HTTP 客戶端來(lái)說(shuō),可以優(yōu)先開啟 HTTP 的 keep-alive 模式,可以復(fù)用 TCP 連接,這樣可以減少 TCP 握手耗時(shí)和重復(fù)請(qǐng)求域名解析,然后再開啟 nscd 緩存,除了 Go 外,C/C++、Java、Python 都可支持 DNS 緩存,減少 DNS查詢耗時(shí)。

這里只分析了常用 C/C++、Java、Go、Python 語(yǔ)言,歡迎熟悉其他語(yǔ)言的小伙伴補(bǔ)充。

3.2 Unix/類 Unix 系統(tǒng)常用 dns 緩存服務(wù):

在由于某些特殊原因,自研或非自研客戶端本身無(wú)法提供 DNS 緩存支持的情況下,建議管理人員在其所在系統(tǒng)環(huán)境中部署DNS緩存程序;

現(xiàn)介紹 Unix/類 Unix 系統(tǒng)適用的幾款常見輕量級(jí) DNS 緩存程序。而多數(shù)桌面操作系統(tǒng)如 Windows、MacOS 和幾乎所有 Web 瀏覽器均自帶 DNS 緩存功能,本文不再贅述。

P.S. DNS 緩存服務(wù)請(qǐng)務(wù)必確保隨系統(tǒng)開機(jī)啟動(dòng);

nscd

name service cache daemon 即裝即用,通常為 linux 系統(tǒng)默認(rèn)安裝,相關(guān)介紹可參考其 manpage:man nscd;man nscd.conf

(1)安裝方法:通過(guò)系統(tǒng)自帶軟件包管理程序安裝,如 yum install nscd (2)緩存管理(清除):

service nscd restart 重啟服務(wù)清除所有緩存;

nscd -i hosts 清除 hosts 表中的域名緩存(hosts 為域名緩存使用的 table 名稱,nscd 有多個(gè)緩存 table,可參考程序相關(guān) manpage)

dnsmasq

較為輕量,可選擇其作為 nscd 替代,通常需單獨(dú)安裝

(1)安裝方法:通過(guò)系統(tǒng)自帶軟件包管理程序安裝,如 yum install dnsmasq (2)核心文件介紹(基于 Dnsmasq version 2.86,較低版本略有差異,請(qǐng)參考對(duì)應(yīng)版本文檔如 manpage 等) (3)/etc/default/dnsmasq 提供六個(gè)變量定義以支持六種控制類功能 (4)/etc/dnsmasq.d/ 此目錄含 README 文件,可參考;目錄內(nèi)可以存放自定義配置文件

(5)/etc/dnsmasq.conf 主配置文件,如僅配置 dnsmasq 作為緩存程序,可參考以下配置

listen-address=127.0.0.1                #程序監(jiān)聽地址,務(wù)必指定本機(jī)內(nèi)網(wǎng)或回環(huán)地址,避免暴露到公網(wǎng)環(huán)境
port=53                                 #監(jiān)聽端口
resolv-file=/etc/dnsmasq.d/resolv.conf  #配置dnsmasq向自定義文件內(nèi)的 nameserver 轉(zhuǎn)發(fā) dns 解析請(qǐng)求
cache-size=150                          #緩存記錄條數(shù),默認(rèn) 150 條,可按需調(diào)整、適當(dāng)增大
no-negcache                             #不緩存解析失敗的記錄,主要是 NXDOMAIN,即域名不存在
log-queries=extra                       #開啟日志記錄,指定“=extra”則記錄更詳細(xì)信息,可僅在問(wèn)題排查時(shí)開啟,平時(shí)關(guān)閉
log-facility=/var/log/dnsmasq.log       #指定日志文件


#同時(shí)需要將本機(jī) /etc/resolv.conf 第一個(gè) nameserver 指定為上述監(jiān)聽地址,這樣本機(jī)系統(tǒng)的 dns 查詢請(qǐng)求才會(huì)通過(guò) dnsmasq 代為轉(zhuǎn)發(fā)并緩存響應(yīng)結(jié)果。
#另 /etc/resolv.conf 務(wù)必額外配置 2 個(gè) nameserver,以便 dnsmasq 服務(wù)異常時(shí)支持系統(tǒng)自動(dòng)重試,注意 resolv.conf 僅讀取前 3 個(gè) nameserver
(6)緩存管理(清除):

kill -s HUP `pidof dnsmasq` 推薦方式,無(wú)需重啟服務(wù)

kill -s TERM `pidof dnsmasq` 或 service dnsmasq stop

service dnsmasq force-reload 或 service dnsmasq restart

(7)官方文檔:https://thekelleys.org.uk/dnsmasq/doc.html?

3.3 純內(nèi)網(wǎng)業(yè)務(wù)取消查詢域名的AAAA記錄的請(qǐng)求

以 linux 操作系統(tǒng)為例,常用的網(wǎng)絡(luò)請(qǐng)求命令行工具常常通過(guò)調(diào)用 getaddrinfo() 完成域名解析過(guò)程,如 ping、telnet、curl、wget 等,但其可能出于通用性的考慮,均被設(shè)計(jì)為對(duì)同一個(gè)域名每次解析會(huì)發(fā)起兩個(gè)請(qǐng)求,分別查詢域名 A 記錄(即 IPV4 地址)和 AAAA 記錄(即 IPV6 地址)。

因目前大部分公司的內(nèi)網(wǎng)環(huán)境及云上內(nèi)網(wǎng)環(huán)境還未使用 ipv6 網(wǎng)絡(luò),故通常 DNS 系統(tǒng)不為內(nèi)網(wǎng)域名添加 AAAA 記錄,徒勞請(qǐng)求域名的 AAAA 記錄會(huì)造成前端應(yīng)用和后端 DNS 服務(wù)不必要的資源開銷。因此,僅需請(qǐng)求內(nèi)網(wǎng)域名的業(yè)務(wù),如決定自研客戶端,建議開發(fā)人員視實(shí)際情況,可將其設(shè)計(jì)為僅請(qǐng)求內(nèi)網(wǎng)域名 A 記錄,尤其當(dāng)因故無(wú)法實(shí)施本地緩存機(jī)制時(shí)。

3.4規(guī)范域名處理邏輯

客戶端需嚴(yán)格規(guī)范域名/主機(jī)名的處理邏輯,避免產(chǎn)生大量對(duì)不存在域名的解析請(qǐng)求(確保域名從權(quán)威渠道獲取,避免故意或意外使用隨機(jī)構(gòu)造的域名、主機(jī)名),因此類請(qǐng)求的返回結(jié)果(NXDOMAIN)通常不被緩存或緩存時(shí)長(zhǎng)較短,且會(huì)觸發(fā)客戶端重試,對(duì)后端 DNS 系統(tǒng)造成一定影響。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    11320

    瀏覽量

    225778
  • Linux
    +關(guān)注

    關(guān)注

    88

    文章

    11806

    瀏覽量

    219482
  • 緩存
    +關(guān)注

    關(guān)注

    1

    文章

    248

    瀏覽量

    27805
  • DNS
    DNS
    +關(guān)注

    關(guān)注

    0

    文章

    229

    瀏覽量

    21224
  • C++
    C++
    +關(guān)注

    關(guān)注

    22

    文章

    2124

    瀏覽量

    77339

原文標(biāo)題:各開發(fā)語(yǔ)言DNS緩存配置建議

文章出處:【微信號(hào):OSC開源社區(qū),微信公眾號(hào):OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    如何在Linux中配置DNS服務(wù)器

    本文詳細(xì)介紹了如何在Linux中配置DNS服務(wù)器,包括DNS工作原理、本地緩存、DNS查詢過(guò)程,以及正向和反向查詢的
    的頭像 發(fā)表于 05-09 13:38 ?2761次閱讀
    如何在Linux中<b class='flag-5'>配置</b><b class='flag-5'>DNS</b>服務(wù)器

    怎樣清除dns緩存,教程來(lái)了 #電腦小技巧

    電腦緩存DNS
    學(xué)習(xí)硬聲知識(shí)
    發(fā)布于 :2022年11月02日 02:16:59

    【Raspberry Pi 3試用體驗(yàn)】+ 搭建本地DNS服務(wù)器

    address=/taobao.com/218.195.54.90resolv.conf:文件主要的作用是DNS客戶機(jī)配置文件,設(shè)置DNS服務(wù)器的IP地址及DNS域名.如果我們不
    發(fā)表于 04-24 21:39

    linux的DNS緩存清空方法

    Linux下DNS緩存實(shí)現(xiàn)通常有兩種方式:一種是用DNS緩存程序NSCD(name service cache daemon)負(fù)責(zé)管理DNS
    發(fā)表于 07-25 07:53

    linux的高速緩存DNS怎么設(shè)置

    linux 高速緩存DNS
    發(fā)表于 08-12 12:06

    DNS服務(wù)器及其配置

    DNS服務(wù)器及其配置:DNS的作用將主機(jī)名字轉(zhuǎn)換成二進(jìn)制IP地址。1.DNS被設(shè)計(jì)成為一個(gè)聯(lián)機(jī)分布數(shù)據(jù)庫(kù)系統(tǒng)。2.DNS采用客戶服務(wù)器模式。
    發(fā)表于 12-07 14:39 ?20次下載

    基于DNS緩存中毒的Webmail攻擊及防護(hù)

    針對(duì)Webmail 的特性,提出一種基于域名系統(tǒng)(DNS)緩存中毒(Cache Poisoning)的Web 郵箱(Webmail)攻擊技術(shù),并對(duì)整個(gè)攻擊流程進(jìn)行描述,實(shí)現(xiàn)了對(duì)當(dāng)前安全性較高的Live Mail 的成功攻擊,驗(yàn)證DNS
    發(fā)表于 03-23 09:05 ?24次下載

    如何配置Win 2003的DNS服務(wù)器

    如何配置Win 2003的DNS服務(wù)器 概要   本文介紹了如何配置“域名系統(tǒng)”(DNS) 服務(wù)器,使其承載可從外
    發(fā)表于 01-29 11:35 ?755次閱讀

    企業(yè)AD、DNS、WINS服務(wù)器的配置

    企業(yè)AD、DNS、WINS服務(wù)器的配置
    發(fā)表于 09-05 16:59 ?6次下載
    企業(yè)AD、<b class='flag-5'>DNS</b>、WINS服務(wù)器的<b class='flag-5'>配置</b>

    在Linux中如何配置DNS

    ----DNS的功用是把計(jì)算機(jī)的名稱轉(zhuǎn)換為 IP地址。DNS的使用簡(jiǎn)化了系統(tǒng)管理員及客戶對(duì)主機(jī)文件的操作和維護(hù)。 Intranet服務(wù)器的系統(tǒng)配置 ----硬件配置:Pentium 1
    發(fā)表于 11-07 10:44 ?3次下載

    DNS癱瘓:原因、問(wèn)題及解決方法

    DNS協(xié)議運(yùn)行在UDP協(xié)議之上,使用端口號(hào)53。在RFC文檔中RFC 2181對(duì)DNS有規(guī)范說(shuō)明,RFC 2136對(duì)DNS的動(dòng)態(tài)更新進(jìn)行說(shuō)明,RFC 2308對(duì)DNS查詢的反向
    發(fā)表于 01-15 17:00 ?2703次閱讀
    <b class='flag-5'>DNS</b>癱瘓:原因、問(wèn)題及解決方法

    VPC子網(wǎng)中DNS server配置建議

    一次DNS解析,然后才能獲取到正確的IP地址,導(dǎo)致處理耗時(shí)比較長(zhǎng),影響體驗(yàn)。?  三、配置建議?  1、新創(chuàng)建的子網(wǎng),建議按照默認(rèn)的配置項(xiàng)
    發(fā)表于 09-01 14:28 ?992次閱讀

    如何在Windows,Linux和MacOS操作系統(tǒng)清除或刷新DNS緩存

    DNS緩存是一個(gè)臨時(shí)數(shù)據(jù)庫(kù),用于存儲(chǔ)已解釋的DNS查詢信息。換句話說(shuō),每當(dāng)您訪問(wèn)網(wǎng)站時(shí),您的操作系統(tǒng)和網(wǎng)絡(luò)瀏覽器都會(huì)保留域名和相應(yīng)IP地址的記錄。
    的頭像 發(fā)表于 12-05 16:08 ?4687次閱讀

    如何在 Linux 上查看本地 DNS 緩存

    ? 刷新本地 DNS 緩存可以解決 HTTP 錯(cuò)誤并保護(hù)您免受 DNS 欺騙。以下是在 Linux 上執(zhí)行此操作的方法。 當(dāng)您使用域名訪問(wèn)網(wǎng)站時(shí),您的系統(tǒng)會(huì)向 DNS 服務(wù)器發(fā)送請(qǐng)求以
    的頭像 發(fā)表于 06-26 10:52 ?4543次閱讀
    如何在 Linux 上查看本地 <b class='flag-5'>DNS</b> <b class='flag-5'>緩存</b>

    如何檢查DNS配置及其重要性

    在網(wǎng)絡(luò)環(huán)境中,DNS(域名系統(tǒng))負(fù)責(zé)將域名轉(zhuǎn)換為對(duì)應(yīng)的IP地址,以確保我們能夠順利訪問(wèn)各種網(wǎng)站和服務(wù)。所以對(duì)我們的網(wǎng)絡(luò)安全至關(guān)重要,以下來(lái)講解一些常用的DNS配置檢查方法。 一、確認(rèn)DNS
    的頭像 發(fā)表于 07-08 14:53 ?2790次閱讀
    如何檢查<b class='flag-5'>DNS</b><b class='flag-5'>配置</b>及其重要性
    修文县| 庄浪县| 嘉鱼县| 井冈山市| 江门市| 阿鲁科尔沁旗| 华池县| 伊川县| 海城市| 叙永县| 五常市| 永胜县| 桐城市| 綦江县| 安国市| 台前县| 隆德县| 崇仁县| 白玉县| 秦皇岛市| 当阳市| 平凉市| 吕梁市| 咸丰县| 大理市| 朝阳区| 虎林市| 博爱县| 昌宁县| 柞水县| 阿克| 方正县| 福安市| 阳新县| 三亚市| 札达县| 两当县| 东乡族自治县| 扬中市| 长宁区| 甘南县|