日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

聊一聊 tcp/ip 在.NET故障分析的重要性

發(fā)布時(shí)間:2023/11/16 asp.net 57 coder
生活随笔 收集整理的這篇文章主要介紹了 聊一聊 tcp/ip 在.NET故障分析的重要性 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一:背景

1. 講故事

這段時(shí)間分析了幾個(gè)和網(wǎng)絡(luò)故障有關(guān)的.NET程序之后,真的越來(lái)越體會(huì)到計(jì)算機(jī)基礎(chǔ)課的重要,比如 計(jì)算機(jī)網(wǎng)絡(luò) 課,如果沒(méi)有對(duì) tcpip協(xié)議 的深刻理解,解決這些問(wèn)題真的很難,因?yàn)槟阒荒茉诟邔幼龊诤袦y(cè)試,你無(wú)法看到 tcp 層面的握手和psh通訊。

這篇我們通過(guò)兩個(gè)小例子來(lái)理解一下 tcp 協(xié)議在故障分析中的作用。

二:tcp協(xié)議的兩個(gè)小例子

1. 程序突然大量超時(shí)

這個(gè)故事起源于一位朋友遇到的問(wèn)題:

起初程序跑的一直都是好好的,但會(huì)有偶發(fā)性突然無(wú)法訪問(wèn),奇怪的是在故障時(shí)手工訪問(wèn)域名時(shí)又是正常的,后面又莫名奇怪的好了,請(qǐng)問(wèn)這是怎么回事?

這種問(wèn)題朋友雖然抓了dump,但在dump中尋找問(wèn)題很難,因?yàn)榇蟾怕适窃?http 通訊中出了問(wèn)題,需要用類似 wireshark 去做流量監(jiān)控,最后發(fā)現(xiàn)的原因是代理服務(wù)器偶發(fā)的抽風(fēng),導(dǎo)致 C# 的 HttpClient 無(wú)法訪問(wèn)。

為了方便演示,這里用一段簡(jiǎn)單的測(cè)試代碼。

  1. WebAPI 代碼

創(chuàng)建一個(gè) WebApi 骨架代碼,然后部署 Windows 虛擬機(jī)上。



        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }

并且在 appsetttings.json 中配置對(duì)外端口為 80。


{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://0.0.0.0:80"
      }
    }
  }
}

  1. Client 的 HttpClient

這里面我用 hosts 做了虛擬機(jī) 192.168.25.133 myproxy.com 的映射,然后通過(guò)域名的方式訪問(wèn)。


    internal class Program
    {
        public static HttpClient client = new HttpClient(new HttpClientHandler()
        {
            Proxy = new WebProxy("http://myproxy.com")
        });

        static async Task Main(string[] args)
        {
            for (int i = 0; i < 100000; i++)
            {
                try
                {
                    // 發(fā)送 GET 請(qǐng)求
                    HttpResponseMessage response = await client.GetAsync("http://youtube.com/WeatherForecast");

                    // 檢查響應(yīng)狀態(tài)碼
                    response.EnsureSuccessStatusCode();

                    // 讀取響應(yīng)內(nèi)容
                    string responseBody = await response.Content.ReadAsStringAsync();

                    // 輸出響應(yīng)內(nèi)容
                    Console.WriteLine(responseBody);

                    await Task.Delay(1000);
                }
                catch (HttpRequestException e)
                {
                    Console.WriteLine($"{DateTime.Now} HTTP 請(qǐng)求異常:{e.Message} {e.GetType().Name}");
                }
            }

        }
    }

打開(kāi) wireshark 進(jìn)行流量監(jiān)聽(tīng),將程序運(yùn)行起來(lái),發(fā)現(xiàn)一切都是那么太平,截圖如下:

由于某些原因,代理服務(wù)器出了問(wèn)題,這里用 關(guān)閉的方式來(lái)模擬,再次觀察 wireshark 可以發(fā)現(xiàn),沒(méi)有收到服務(wù)器對(duì)154號(hào)包的響應(yīng),client 這邊根據(jù) RTO=1s 進(jìn)行重試。

2. DNS解析到的IP無(wú)法訪問(wèn)

有些朋友程序出現(xiàn)了卡死,原因在于設(shè)置了很長(zhǎng)的 Timeout,這種 Timeout 挺有意思,域名能夠通過(guò) DNS 解析到 IP,但 IP 無(wú)法被訪問(wèn)到,導(dǎo)致 client 這邊在不斷的重試,直到 timeout 的時(shí)限到時(shí)拋出異常。

接下來(lái)還是用 HttpClient 做一個(gè)小例子,直接訪問(wèn) youtube.com ,參考如下代碼:


static async Task Main(string[] args)
        {
            HttpClient client = new HttpClient();

            for (int i = 0; i < 100000; i++)
            {
                try
                {
                    // 發(fā)送 GET 請(qǐng)求
                    HttpResponseMessage response = await client.GetAsync("http://youtube.com");

                    // 檢查響應(yīng)狀態(tài)碼
                    response.EnsureSuccessStatusCode();

                    // 讀取響應(yīng)內(nèi)容
                    string responseBody = await response.Content.ReadAsStringAsync();

                    // 輸出響應(yīng)內(nèi)容
                    Console.WriteLine(responseBody);

                    await Task.Delay(1000);
                }
                catch (HttpRequestException e)
                {
                    Console.WriteLine($"{DateTime.Now} HTTP 請(qǐng)求異常:{e.Message} {e.GetType().Name}");
                }
            }
        }

打開(kāi) wireshark 啟動(dòng)監(jiān)控,然后將程序運(yùn)行起來(lái),截圖如下:

從卦中可以看到 client 發(fā)起了一個(gè) DNS 查詢,DNS服務(wù)器查詢到 youtube.com 所對(duì)應(yīng)的 IP 是 104.244.46.85,接下來(lái)應(yīng)該就是 client 對(duì)這個(gè) ip 發(fā)起 握手請(qǐng)求,截圖如下:

從圖中信息看,真的很尬尷,有如下兩點(diǎn)信息:

  • client 發(fā)起了 SYN 請(qǐng)求,結(jié)果沒(méi)人鳥(niǎo)它,沒(méi)人鳥(niǎo)主要是因?yàn)槁窂缴系?strong>防火墻把這個(gè) SYN ACK 給沒(méi)收了。

  • client 端按照 1s,2s,4s,8s 的RTO計(jì)時(shí)器超時(shí)進(jìn)行重試,直到 HttpClient 等不及拋 TimeoutException 異常。

三:總結(jié)

人是活在錯(cuò)綜復(fù)雜的關(guān)系網(wǎng)里,同樣程序也是,要想解決更多的.NET程序故障,對(duì) tcp/ip 體系知識(shí)的了解也同樣必不可少。

總結(jié)

以上是生活随笔為你收集整理的聊一聊 tcp/ip 在.NET故障分析的重要性的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。