电子政务门户网站建设汇报,网站菜单导航制作,购物网站后台好管理吗,全国装饰公司排名100强名单一#xff1a;背景
1. 讲故事
这段时间分析了几个和网络故障有关的.NET程序之后#xff0c;真的越来越体会到计算机基础课的重要#xff0c;比如 计算机网络 课#xff0c;如果没有对 tcpip协议 的深刻理解#xff0c;解决这些问题真的很难#xff0c;因为你只能在高层…一背景
1. 讲故事
这段时间分析了几个和网络故障有关的.NET程序之后真的越来越体会到计算机基础课的重要比如 计算机网络 课如果没有对 tcpip协议 的深刻理解解决这些问题真的很难因为你只能在高层做黑盒测试你无法看到 tcp 层面的握手和psh通讯。
这篇我们通过两个小例子来理解一下 tcp 协议在故障分析中的作用。
二tcp协议的两个小例子
1. 程序突然大量超时
这个故事起源于一位朋友遇到的问题 起初程序跑的一直都是好好的但会有偶发性突然无法访问奇怪的是在故障时手工访问域名时又是正常的后面又莫名奇怪的好了请问这是怎么回事 这种问题朋友虽然抓了dump但在dump中寻找问题很难因为大概率是在 http 通讯中出了问题需要用类似 wireshark 去做流量监控最后发现的原因是代理服务器偶发的抽风导致 C# 的 HttpClient 无法访问。
为了方便演示这里用一段简单的测试代码。
WebAPI 代码
创建一个 WebApi 骨架代码然后部署 Windows 虚拟机上。
[HttpGet]public IEnumerableWeatherForecast 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 中配置对外端口为 80。 {Logging: {LogLevel: {Default: Information,Microsoft.AspNetCore: Warning}},Kestrel: {Endpoints: {Http: {Url: http://0.0.0.0:80}}}
}
Client 的 HttpClient
这里面我用 hosts 做了虚拟机 192.168.25.133 myproxy.com 的映射然后通过域名的方式访问。
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{// 发送 GET 请求HttpResponseMessage response await client.GetAsync(http://youtube.com/WeatherForecast);// 检查响应状态码response.EnsureSuccessStatusCode();// 读取响应内容string responseBody await response.Content.ReadAsStringAsync();// 输出响应内容Console.WriteLine(responseBody);await Task.Delay(1000);}catch (HttpRequestException e){Console.WriteLine(${DateTime.Now} HTTP 请求异常{e.Message} {e.GetType().Name});}}}}
打开 wireshark 进行流量监听将程序运行起来发现一切都是那么太平截图如下 由于某些原因代理服务器出了问题这里用 关闭的方式来模拟再次观察 wireshark 可以发现没有收到服务器对154号包的响应client 这边根据 RTO1s 进行重试。 2. DNS解析到的IP无法访问
有些朋友程序出现了卡死原因在于设置了很长的 Timeout这种 Timeout 挺有意思域名能够通过 DNS 解析到 IP但 IP 无法被访问到导致 client 这边在不断的重试直到 timeout 的时限到时抛出异常。
接下来还是用 HttpClient 做一个小例子直接访问 youtube.com 参考如下代码 static async Task Main(string[] args){HttpClient client new HttpClient();for (int i 0; i 100000; i){try{// 发送 GET 请求HttpResponseMessage response await client.GetAsync(http://youtube.com);// 检查响应状态码response.EnsureSuccessStatusCode();// 读取响应内容string responseBody await response.Content.ReadAsStringAsync();// 输出响应内容Console.WriteLine(responseBody);await Task.Delay(1000);}catch (HttpRequestException e){Console.WriteLine(${DateTime.Now} HTTP 请求异常{e.Message} {e.GetType().Name});}}}
打开 wireshark 启动监控然后将程序运行起来截图如下 从卦中可以看到 client 发起了一个 DNS 查询DNS服务器查询到 youtube.com 所对应的 IP 是 104.244.46.85接下来应该就是 client 对这个 ip 发起 握手请求截图如下 从图中信息看真的很尬尴有如下两点信息 client 发起了 SYN 请求结果没人鸟它没人鸟主要是因为路径上的防火墙把这个 SYN ACK 给没收了。 client 端按照 1s2s4s8s 的RTO计时器超时进行重试直到 HttpClient 等不及抛 TimeoutException 异常。
三总结
人是活在错综复杂的关系网里同样程序也是要想解决更多的.NET程序故障对 tcp/ip 体系知识的了解也同样必不可少。