非常好玩的C#/.NET 基础 -- 安全有效引发事件
强撂侨乘最近买了台mac mini用来写博客但迟迟没有动笔。虽然积累了非常多的素材但写一篇《解Bug之路》系列的博客实在是太累人了。同时也很久没有那种让我感到兴奋的问题了。但总归不能让这台新买的mac mini成为摆设于是就写一些平时遇到的小问题吧。问题现场问题是喜闻乐见的调用超时。这个问题的显著特征是:1.流量小的时候容易出现偶发性访问超时一般是空闲很长时间后的第一笔请求超时。2.调大超时时间没有任何效果平常请求在1s内就能返回。但出现这类超时的时候就算调整到1min超时时间依旧会超时。3.超时后的重试调用一般都会成功。4.同一时间其它相同调用不会出现问题。5.在内网调用不会出现这个问题在非内网调用不管是专线还是互联网都容易出现这个问题。6.服务端无法搜索到任何日志仿佛这个超时请求没有出现过。猜想1:服务端关闭了连接一个非常直观的猜想就是服务端关闭了这个链接请求直接被拒绝了。但熟悉tcp协议的笔者很快否定了这个猜想如果连接被关闭了会有下面图中所示的两种情况:serverclientserverclientalt[client未收到FIN包][client收到FIN包]请求正常返回close连接tcp packettcp resetsocket has already closed第一种情况client端没有收到服务端返回的FIN包那么在请求发送后应该是直接被对端Reset立刻感知到报错。第二种情况client端收到了服务端返回的FIN包那么在请求发送前会直接报socket has already closed立刻感知到报错。根据上面的判断无论什么情况都是立刻返回而不是等待很长时间之后超时和特征2不符于是可以否定由于服务端关闭连接导致。猜想2:偶发性路由翻动因为过了非常长的时间才超时这时候我们的就可以考虑是在网络层丢包了。那么到底为什么丢包呢难道是偶发性的路由翻动这个想法立马被笔者否决了。因为如果是路由翻动一般会在分钟级别的收敛而我们观察到在5s超时后的重试都是成功的。而且一旦路由翻动这段时间内所有的请求都应该收到影响而问题现场其它请求确实正常的。这就和特征3/特征4不符合。猜想3(真正的原因)其实这个问题笔者一直遇到而且解决方案也一直有但从没有真正的仔细思考过。但最近读《tcpip路由技术》卷二突然灵光一闪将书中的一些阐述和这个问题莫名的关联想通了其中的关窍。人们由于IPv4地址即将耗尽而不得不开发出NAT技术而NAT毕竟只是个补丁其无法完整的融合进TCP导致出现种种因为这个补丁而出现的问题。我们通过NAT设备中的转发表项维护内网的ip:port和外网的ip:port之间的映射入下图所示:很明显的由于client和server的数量是非常多的(因为多个服务可能公用一个公网IP)所以转发表是一个非常宝贵的资源一旦转发表满了就无法创建新的连接路径了。所以一些长期没有流量需要有一个定时的清理机制腾出转发表以供新的连接创建。如下图所示在tcp连接estalbish状态后一定时间内没有任何流量NAT会直接清空这个转发表项而client和server端无法感知到这一点于是client端只好在多次NAT重传后超时。这个和Bug现场的各种特征完全一致。当然无论是NAT-1和NAT-2都有可能清理转发表只要有一个过期那么这个连接就会出现超时。使用LVS做NAT的默认超时时间那么我们看一下我们最常用的使用LVS做NAT的默认超时时间是多少让我们来番一下LVS源代码:static const int tcp_timeouts[IP_VS_TCP_S_LAST1] {[IP_VS_TCP_S_NONE] 2*HZ,[IP_VS_TCP_S_ESTABLISHED] 15*60*HZ, // 这边设定了ESTABLISHED状态的超时时间为15min[IP_VS_TCP_S_SYN_SENT] 2*60*HZ,[IP_VS_TCP_S_SYN_RECV] 1*60*HZ,[IP_VS_TCP_S_FIN_WAIT] 2*60*HZ,[IP_VS_TCP_S_TIME_WAIT] 2*60*HZ,[IP_VS_TCP_S_CLOSE] 10*HZ,[IP_VS_TCP_S_CLOSE_WAIT] 60*HZ,[IP_VS_TCP_S_LAST_ACK] 30*HZ,[IP_VS_TCP_S_LISTEN] 2*60*HZ,[IP_VS_TCP_S_SYNACK] 120*HZ,[IP_VS_TCP_S_LAST] 2*HZ,};struct ip_vs_conn *ip_vs_conn_new(......){......timer_setup(cp-timer, ip_vs_conn_expire, 0); // 在初始化连接的时候设置超时函数ip_vs_conn_expire......}static void ip_vs_conn_expire(struct timer_list *t){......if (likely(ip_vs_conn_unlink(cp))) { // 在这里清理转发表......}......}static inline void set_tcp_state(......){......// 通过状态在tcp_timeout表中找到相应的超时时间并设置进timeoutcp-timeout pd-timeout_table[cp-state new_state];......}从上面代码中我们可以看到LVS通过设置的timeout_table来设置转发表项超时时间而不同的tcp状态会有不同的超时时间而默认的established的超时时间是15 * 60 * HZ也就是15min。也就是说在默认不设置的情况下15min中之后这个连接就会GG。解决方案好了了解完原理之后我们就可以有解决方案了。第一种方案就是使用短连接。也就是每次请求的时候新建一个连接NAT本身对tcp的FIN包做了处理一旦发生四次挥手会自动清理表项。用完即回收即减少了NAT设备转发表的压力也不会产生过一段时间超时的问题。但这个方案有个缺陷也是短连接的固有缺陷。由于复用不了连接短时候有海量的请求过来产生大量的短连接由于TCP 2MSL机制的存在client即有可能出现端口耗尽。而端口耗尽后会导致Kernel在搜索可用端口号的时候性能急剧劣化(每次搜索端口从数次循环急剧劣化到每次搜多端口都要数万次循环)这会导致client端的机器CPU利用率急剧上升一直陷在搜索端口号的循环里面导致整体不可用 如下图所示:具体分析可以见笔者的另一篇博客: https://my.oschina.net/alchemystar/blog/4436558为了解决第一种的方案的问题我们可以依旧复用连接只不过这个复用时间特别短例如6s之内复用超过6s的连接就直接丢弃。这样既能在大量请求涌过来的时候扛住又能解决长时间不用的超时问题。HttpClient其实提供这个机制如下所示:HttpClients.custom().evictIdleConnections(6, TimeUnit.SECONDS)第三种方案我们可以轮询每一个connection发送心跳包但这个实现起来比较麻烦远没有上面的HttpClient内置方案省心。还有一个需要提到的是Http的Keep-alive连接的保持时间是在Server端设置的。而这个Keep-alive timeout可能 NAT的清理时间。对于Client端来说很难约束Server端的配置。所以笔者还是建议采用第二种方案。总结NAT虽然大幅度延长了IPV4地址耗尽的时间但由于只是打了补丁它的固有缺陷会导致很多问题。不过我们会根据遇到问题的原因给出各种解决的方案从而让系统稳定的运行。如果具备相应的基础知识这个问题非常容易解决。但如果没有对整个通信过程有一个大致的理解会无从着手所以系统化的学习非常重要。

相关新闻

ASP.NET MVC关于生成纯静态后如何不再走路由直接访问静态页面

ASP.NET MVC关于生成纯静态后如何不再走路由直接访问静态页面

敦位导纳项目上使用SpringCloudGateway作为网关承接公网上各个业务线进来的请求流量,在网关的前面有两台Nginx反向代理了网关,网关做了一系列的前置处理后转发请求到后面各个业务线的服务,简要的网络链路为: 网关域名(wmg.test.co…

2026/7/5 5:31:38 阅读更多 →
T-SQL查询进阶--详解公用表表达式(CTE)

T-SQL查询进阶--详解公用表表达式(CTE)

钾记济臀我们在生活中最先接触的是细节,比如看到各种动作后,才开始对它们进行分类,才会去思考他们的叫声是不同,走路也是不同的。这种从细节到整体的思维方式,恰恰可以指导我们在编程中合理地使用继承。 自下而上&…

2026/7/4 14:17:39 阅读更多 →
对SCHEME的一些理解

对SCHEME的一些理解

颜置籽酚一.什么是Flex布局? Flex布局是Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为Flex布局,这使得元素在容器内的排列、对齐和空间分配变得更加简单和灵活。 基本概…

2026/7/7 3:31:01 阅读更多 →

最新新闻

Kubeflow实战指南:构建可交付的端到端机器学习流水线

Kubeflow实战指南:构建可交付的端到端机器学习流水线

1. 为什么我们需要 Kubeflow:从“能跑通”到“可交付”的真实断层你有没有过这样的经历?在本地 Jupyter Notebook 里,用 Scikit-learn 训练一个随机森林模型,准确率 92%,代码清爽,逻辑清晰,连注…

2026/7/7 22:00:01 阅读更多 →
SQL Join本质是数据关系翻译,不是拼表语法题

SQL Join本质是数据关系翻译,不是拼表语法题

1. 项目概述:为什么“SQL Join”不是语法题,而是数据关系的翻译器 “Introduction to SQL Joins”——这个标题看起来像教科书第一章,但在我带过37个真实业务团队、处理过2100次线上数据取数需求后,我越来越确信: 绝大…

2026/7/7 21:57:54 阅读更多 →
Python垃圾回收机制深度解析:代际回收、循环引用与调优实战

Python垃圾回收机制深度解析:代际回收、循环引用与调优实战

1. 项目概述:为什么Python的垃圾回收不是“设好就忘”的后台服务Python开发者常有个错觉:对象用完就丢,解释器自会收拾残局——毕竟del obj之后内存似乎就“干净”了。但真实场景里,你写完一个数据处理脚本,跑着跑着内…

2026/7/7 21:55:54 阅读更多 →
Runway视频生成三模型对比:4K画质、快速原型与实时应用实战

Runway视频生成三模型对比:4K画质、快速原型与实时应用实战

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 如果你正在寻找能够真正提升视频生成质量的新工具,Runway最新推出的三款模型值得重点关注。这次发布的Seedance 4K、Seeda…

2026/7/7 21:53:53 阅读更多 →
勒索病毒应急响应实战指南:从隔离遏制到系统加固的完整路径

勒索病毒应急响应实战指南:从隔离遏制到系统加固的完整路径

1. 当勒索病毒敲响企业大门:一份来自一线的实战响应指南“服务器所有文件都被加密了,后缀变成了.locked,桌面上留了一个勒索信!”——这可能是IT管理员最不想在深夜或清晨接到的电话。勒索病毒攻击早已不是新闻,但它对…

2026/7/7 21:51:52 阅读更多 →
2026年AI开发者工具链盘点:从模型调用到应用上线全链路

2026年AI开发者工具链盘点:从模型调用到应用上线全链路

写在前面做 AI 应用一年多,工具链换了好几轮。最早只用 OpenAI SDK 直连,后来加向量库,再加框架,再加中转站,再加监控——到现在基本稳定下来了。这篇文章盘点我目前在用的完整工具链,从模型调用到应用上线…

2026/7/7 21:51:52 阅读更多 →

日新闻

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

图片浏览是移动应用中最高频的场景之一。从社交应用的照片流到电商平台的商品图集,从旅游应用的景点相册到摄影作品展示——用户对图片浏览的体验要求不断提高:流畅的切换动画、直观的缩略图导航、便捷的收藏操作、自动播放模式。HarmonyOS NEXT ArkUI 虽…

2026/7/7 0:05:16 阅读更多 →
24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V稳压芯片完整选型指南 PW8600 PW75XX PW2815 PW2312B LDODC/DC全方案 一、24V稳压方案概述 24V直流电源在工业自动化、门禁系统、电梯控制、汽车电子、LED驱动、监控设备等场景中应用极广,是最常见的中压直流母线电压。要将24V母线稳定降压至下游MCU、传感器…

2026/7/7 0:05:16 阅读更多 →
RAG+知识图谱混合检索与Graph RAG核心对比

RAG+知识图谱混合检索与Graph RAG核心对比

做企业RAG落地的团队,往往容易卡在一容易踩坑的选型难题: 当需求单纯靠向量RAG搞不定、单纯靠知识图谱也搞不定,必须同时依赖「文本语义理解 实体关系推理」时,到底是做「向量图谱混合检索」就够了,还是必须上「Grap…

2026/7/7 0:07:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/7 14:24:45 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/7 12:34:47 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/7 15:59:06 阅读更多 →

月新闻