当前位置: 首页 > 编程日记 > 正文

NAT环境无法访问云端的深层次分析

这是一次我维护runningdoctor时候遇到的问题
现象:
1.用户无法打开web.runningdoctor.cn
2.监控状态无异常、无报警
3.tracert结果无异常、丢包率正常
4.用户无法访问的时候,我们能打开网站
5.多地代理访问网站,结果正常
6.有打开网站特别慢的时候,延迟30S

猜测问题

image

复现问题

image
偶然的一次 刷到了页面不存在
于是赶紧tracert一下 看看网络连通性
(但是不科学 因为这次请求被拒绝 我tracert并不及时 也许这个时候的tracert结果是能请求到页面时的 所以最后知道结果反推这次尝试应该说是一次失败的尝试)

试着解决问题

![image](https://yqfile.alicdn.com/d0c7

951b00e4c290c043ed9dbb1da4f72d98d93d.png)
做出这种尝试但是还是没有确定问题到底出现在C端还是S端 ,所以只能每种都去试试,推测一下,改了再观察。

Try
plus:

  1. Netstat 看到很多Time_wait
  2. 查看TIME_wait的解决思路
  3. 修改内核参数,重启应用程序

当时的内核一些网络配置参数:
net.ipv4.tcp_syncookies = 1(半开连接攻击????)
打开TCP SYN cookie选项,有助于保护服务器免受SyncFlood攻击。
net.ipv4.tcp_tw_reuse = 1(socket重用)
怀疑是不是socket占用太多导致建立不起tcp链接
net.ipv4.tcp_tw_recycle = 0(罪魁两巨头之一 default=1)
打开socket的快速回收机制
net.ipv4.tcp_fin_timeout = 20
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 180000
net.ipv4.icmp_echo_ignore_all=0
(这里无非就是打开一些上限 其实并没有达到上限)
net.ipv4.tcp_timestamps = 0 (罪魁祸首)
校验数据包头的时间戳 乱序的包将会被丢弃 满足递增的条件才保留

后来我被派到了医院里去 于是我打算通过一个小程序去监测我们web的80和443端口,看看他们这边有没有发生请求我们服务器的情况 并且返回时间戳(最后通过这个时间戳去搜索tcpdump出来的日志 去定位这次请求到底是在医院内被拒绝的还是请求走到公网到了我们的服务器被拒绝的)

image

image

image

最后通过程序返回的时间戳去tcpdump搜索附近的连接情况 终于找到了原因。就是被服务器拒绝了!
于是我又去谷歌搜为什么会被服务器拒绝 于是看到了这样一些结论,以及别人遇到的类似问题:

come to conclusion :
what makes our website server can be succed to ping and tracert but can not open it on broswer?

近来线上陆续出现了一些connect失败的问题,经过分析试验,最终确认和proc参数tcp_tw_recycle/tcp_timestamps相关;

  1. 现象
    第一个现象:模块A通过NAT网关访问服务S成功,而模块B通过NAT网关访问服务S经常性出现connect失败,抓包发现:服务S端已经收到了syn包,但没有回复synack;另外,模块A关闭了tcp timestamp,而模块B开启了tcp timestamp;

第二个现象:不同主机上的模块C(开启timestamp),通过NAT网关(1个出口ip)访问同一服务S,主机C1 connect成功,而主机C2 connect失败;

分析
根据现象上述问题明显和tcp timestmap有关;查看linux 2.6.32内核源码,发现tcp_tw_recycle/tcp_timestamps都开启的条件下,60s内同一源ip主机的socket connect请求中的timestamp必须是递增的。
源码函数:tcp_v4_conn_request(),该函数是tcp层三次握手syn包的处理函数(服务端);
源码片段:
if (tmp_opt.saw_tstamp &&
tcp_death_row.sysctl_tw_recycle &&
(dst = inet_csk_route_req(sk, req)) != NULL &&
(peer = rt_get_peer((struct rtable *)dst)) != NULL &&
peer->v4daddr == saddr) {
if (get_seconds() < peer->tcp_ts_stamp + TCP_PAWS_MSL &&
(s32)(peer->tcp_ts - req->ts_recent) >
TCP_PAWS_WINDOW) {
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED);
goto drop_and_release;
}
}
tmp_opt.saw_tstamp:该socket支持tcp_timestamp
sysctl_tw_recycle:本机系统开启tcp_tw_recycle选项
TCP_PAWS_MSL:60s,该条件判断表示该源ip的上次tcp通讯发生在60s内
TCP_PAWS_WINDOW:1,该条件判断表示该源ip的上次tcp通讯的timestamp 大于 本次tcp

分析:主机client1和client2通过NAT网关(1个ip地址)访问serverN,由于timestamp时间为系统启动到当前的时间,因此,client1和client2的timestamp不相同;根据上述syn包处理源码,在tcp_tw_recycle和tcp_timestamps同时开启的条件下,timestamp大的主机访问serverN成功,而timestmap小的主机访问失败;

参数:/proc/sys/net/ipv4/tcp_timestamps - 控制timestamp选项开启/关闭
/proc/sys/net/ipv4/tcp_tw_recycle - 减少timewait socket释放的超时时间

解决方法
echo 0 > /proc/sys/net/ipv4/tcp_tw_recycle;
tcp_tw_recycle默认是关闭的,有不少服务器,为了提高性能,开启了该选项;
为了解决上述问题,个人建议关闭tcp_tw_recycle选项,而不是timestamp;因为 在tcp timestamp关闭的条件下,开启tcp_tw_recycle是不起作用的;而tcp timestamp可以独立开启并起作用。
源码函数: tcp_time_wait()
源码片段:
if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp)
recycle_ok = icsk->icsk_af_ops->remember_stamp(sk);

if (timeo < rto)timeo = rto;if (recycle_ok) {tw->tw_timeout = rto;
} else {tw->tw_timeout = TCP_TIMEWAIT_LEN;if (state == TCP_TIME_WAIT)timeo = TCP_TIMEWAIT_LEN;
}inet_twsk_schedule(tw, &tcp_death_row, timeo,TCP_TIMEWAIT_LEN);

linux 服务器 无法建立TCP连接 时间戳 net.ipv4.tcp_timestamps

一.情况表现为
1.在公司内网对站点的http访问:
linux主机出现故障:curl以及抓包分析,发现服务端不响应linux客户端的请求,无法建立TCP连接,浏览器返回“无法连接到服务器”
windows主机正常
2.http访问质量下降:
基调显示,新架构上线后,访问质量下滑,主要表现为
2.1.访问提示“无法连接到服务器”
2.2.仅少数人遇到这种故障,并且一天中不是每次访问都会遇到,而是出现时好时坏的现象

二.处理过程
直接上google搜索关键字“服务器无法建立TCP连接”。
翻了几页后,发现这篇博文:“http://www.sunchis.com/html/os/linux/2012/0518/413.html”。
看了一下,和我们公司内网的表现一模一样,但各种问题(1为这方面基础知识薄弱,2为没有时间验证此配置)
然后这种问题持续了n久…一直以为是内部设备问题
后期搞不定了,大胆在线上启用这个参数“net.ipv4.tcp_timestamps = 0”,做了下测试后,发现故障解除,原故障机每次访问都正常了!
不过还是不明其中原理,只是大意了解,同样处于NAT上网方式的用户里(与别人共用出口IP地址),如果你的时间戳小于别人的,那么服务器不会响应你的TCP请求,要忽略此项,将net.ipv4.tcp_timestamps = 0(/etc/sysctl.conf)

三.总结
后期学习时,看见了一个更加详细的博客,讲的很详细,也引入了新的问题:http://huoding.com/2012/01/19/142

其实,linux服务器原本对时间戳(timestamps)默认是不开启的,Linux是否启用这种行为取决于tcp_timestamps和tcp_tw_recycle,因为tcp_timestamps缺省就是开启的,所以当tcp_tw_recycle被开启后,实际上这种行为就被激活了。
net.ipv4.tcp_tw_recycle又是啥呢,搜索了一下基本上是TIME_WAIT连接的回收参数

当 net.ipv4.tcp_timestamps 没有设置(缺省为开启),并且 net.ipv4.tcp_tw_recycle 也开启时,这个坑爹的错误就出现了,但是注意,只表现在NAT网络环境中。而且,大多数博客,以及一些大牛们,都有说过要开启 net.ipv4.tcp_tw_recycle …

启示录

1.三种网络模式
The network in hospital (our clients)
image

Nat mode ,ipaddr exchange

image

这是事故的出现就是因为医院内部是一个巨大的局域网(每个使用我们SaaS的医院都是数千人员工的医院),他们访问外网是通过nat来实现的。也就是所有请求都要从外端路由到达公网,所以最终会被服务器认为是一个用户在请求。一旦某个包头时间戳乱序,就会造成其他的请求被拒绝。而其他一些针对个人用户的Saas不会出现这种情况的原因就是因为用户分散在各个场景,各个网络中,并不由一个路由把包从公网传到服务器上。

另外两种网络模式简述一下怎么用的吧:
HOST 可以用一张图来理解:
image
image

这种模式我觉得就相当于你的每台主机与路由都是平行地址,外部能ping到你的路由就能ping你的主机,这种做法在云端的话非常占有ip地址资源,所以一般是内部环境才能用用。一般你拉一条专线只会给你几个公网地址,如果你都用brige的话服务器又多,不可能每个都配一个公网地址的。所以这种网络模式我一般就是在虚拟机上做做实验的时候会使用到,当然服务器内部比如docker之类的也用docker0与eth0桥接 从而达到一个share的作用 你才能再真机上ping172的那些网络地址。

2.三次握手协议
解决这次问题也帮我回顾了一下三次握手协议。作为一个运维,我觉得有一大块的工作重心就在“”what happend when you input a url in your broswer?“ 排除故障要是这个思路,请求到没有到服务器?服务器给你的状态码是什么?通过状态码判断是资源不存在还是程序错误?资源不存在的话是路由的问题还是权限的问题,是路由的问题的话是开发与你沟通的nginx转发配置的问题还是程序内部路由的问题;是代码的问题的话你就要去判断是启动报错还是什么情况?当然有了这种思路你就要通过去排查日志或者网络抓包去定位问题,从而解决问题。
当然,我们这次故障就是出现在握手协议上,所以这里
也顺便温习一下握手协议

image

男:妹子我喜欢你
女:我知道你喜欢我了,帅哥我也喜欢你
男:你知道我喜欢你了啊!你喜欢我我也喜欢你啊!
于是俩人就。。。。。。。。。。了
。。。。。。。。。。之后
男:睡觉吧
女:哦
女:那我也睡了
男: 好

前文能够定位到问题就是握手没建立起来 一直是妹子我喜欢你 喜欢你 喜欢你 。。。其实妹子是个聋子,根本不晓得你说的什么,也就没了后文………

专业一点:TCP状态迁移:CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED服务服务器TCP状态迁移:CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED

不管是程序员还是运维都要关注这个问题,比如你http不设置超时,那么服务器就会有大量的连接被占用,linux万物皆文件,高并发情况下资源损耗就会比较大,每个连接都是要占用句柄的。调优的话就是要依据这些来做,是启用长连接还是短连接?keepalive时间设置多少,请求频率做不做限制,内核如何调优?http返回什么状态码才友善等等,这都是要关注的细节问题。

3.经验都是惨痛的代价走出来的

以前从来没有遇到过这种场景,这次故障基于业务线的url监控,系统层级的监控全部没有发现医院出现的访问故障。这个问题也一直持续了很长一段时间,如果这是一个高频,高价值的生产线出现这种故障必定是致命的。未来的路还长,要学的东西还有很多很多……….

以下是我的csdn的地址:
https://blog.csdn.net/qq_15800363/article/details/78424101
版权声明:本文为博主原创文章,转载请附上博文链接!

相关文章:

Magento(麦进斗)安装问题

安装到数据库那一步会跳出 lib\Zend\Db\Statement\Pdo.php on line 228 错误 解决方案&#xff1a; 在你的php模块里的php.ini文件添加&#xff08;或者修改&#xff09;max_execution_time1800 重启你的web服务器&#xff08;apache&#xff0c;nginx&#xff09;&#xff0c;…

Linux Socket基础介绍

Linux Socket函数库是从Berkeley大学开发的BSD UNIX系统中移植过来的。BSD Socket接口是众多Unix系统中被广泛支持的TCP/IP通信接口&#xff0c;Linux下的Socket程序设计&#xff0c;除了微小的差别之外&#xff0c;也适用于大多数其它Unix系统。 Socket接口是TCP/IP网络的API…

免费公开课 | 基于定制数据流技术的AI计算加速

随着人工智能时代的来临&#xff0c;业内对于更高效率算力的需求也越来越紧迫&#xff0c;而传统的 CPU 计算能力弱&#xff0c;只适合软件编程&#xff0c;并不适合应用于人工神经网络算法的自主迭代运算。为了满足支撑深度学习的大规模并行计算的需求&#xff0c;人工智能芯片…

代替国足踢决赛?马宁当选卡日大战第四官员

卡塔尔杀进亚洲杯决赛。 图片来源&#xff1a;Osports全体育图片社 中新网1月30日电 日本与卡塔尔将会师本届亚洲杯的决赛。北京时间30日&#xff0c;亚足联官方已经公布了本次决赛的裁判组&#xff0c;中国裁判员马宁将担任第四官员。 来自乌兹别克斯坦的亚洲金哨伊尔马托夫将…

AI规模化落地,英特尔至强的七重助力

当今时代&#xff0c;各行各业与人工智能&#xff08;AI&#xff09;加速融合&#xff0c;通过智能化创新来寻求业务转型升级。与为数不多的顶级AI研发公司相比&#xff0c;大多数传统行业或企业有着更丰富的 AI 应用场景&#xff0c;推动着规模化的AI应用落地&#xff0c;其AI…

Linux进程编程基础介绍

Linux系统是一个多进程的系统&#xff0c;它的进程之间具有并行性、互不干扰等特点。也就是说&#xff0c;每个进程都是一个独立的运行单位&#xff0c;拥有各自的权利和责任。其中&#xff0c;各个进程都运行在独立的虚拟地址空间&#xff0c;因此&#xff0c;即使一个进程发生…

关于互联网技术基层绩效管理的一些思考

起因是一篇内部的文章&#xff0c;那记录也就留在内部吧&#xff0c;磨炼了的价值观在自己心里就好。 类似的还有 1. 罗振宇不发年终奖&#xff1a;https://xueqiu.com/7118120763/119669075 2. 有赞白鸦强行一波996&#xff1a;https://baijiahao.baidu.com/s?id1623959680…

波纹管 编织管

为什么80%的码农都做不了架构师&#xff1f;>>> 波纹管 编织管 http://wenku.baidu.com/view/4272a9feaef8941ea76e057e.html 转载于:https://my.oschina.net/tadcat/blog/151049

Git基础(常用命令)介绍

版本控制是一种记录若干文件内容变化,以便将来查阅特定版本修订情况的系统. 关于版本控制分为三种&#xff1a;本地版本控制系统&#xff0c;如rcs&#xff1b;集中化的版本控制系统&#xff0c;如CVS、SVN&#xff1b;分布式版本控制系统&#xff0c;如Git。 Git基础要点 G…

MIT开发新加密货币,用户所需数据比比特币减少99%

MIT的研究人员开发了一种新的加密货币&#xff0c;大大减少了用户加入网络和验证交易所需的数据&#xff0c;与当今流行的加密货币相比&#xff0c;最高可达99%。这意味着网络更具扩展性。 像比特币之类流行的加密货币都是构建于区块链上的网络&#xff0c;而区块链是按照一系列…

深入了解AI加速芯片的定制数据流架构与编译器 | 公开课

随着人工智能时代的来临&#xff0c;业内对于更高效率算力的需求也越来越紧迫&#xff0c;而传统的 CPU 计算能力弱&#xff0c;只适合软件编程&#xff0c;并不适合应用于人工神经网络算法的自主迭代运算。为了满足支撑深度学习的大规模并行计算的需求&#xff0c;人工智能芯片…

《GPU高性能编程CUDA实战》中代码整理

CUDA架构专门为GPU计算设计了一种全新的模块&#xff0c;目的是减轻早期GPU计算中存在的一些限制&#xff0c;而正是这些限制使得之前的GPU在通用计算中没有得到广泛的应用。使用CUDA C来编写代码的前提条件包括&#xff1a;(1)、支持CUDA的图形处理器&#xff0c;即由NVIDIA推…

​50年来最具影响力的十大编程语言!

作者 | javinpaul译者 | 馨怡责编 | 屠敏出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;【导语】“适者生存”的自然法则在应用竞争激烈的编程语言界同样适用&#xff0c;而在数百种编程语言中&#xff0c;相对而言&#xff0c;哪些最具影响力&#xff1f;哪些才是…

【基础篇】DatePickerDialog日期控件的基本使用(一)

项目步骤&#xff1a; 1.首先在Main.xml布局文件中添加一个Button标签&#xff0c;用来点击显示日期控件&#xff0c;Main.xml内容如下&#xff1a; <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android" xmlns:tools"http://sch…

PoPo数据可视化第9期

PoPo数据可视化 聚焦于Web数据可视化与可视化交互领域&#xff0c;发现可视化领域有意思的内容。不想错过可视化领域的精彩内容, 就快快关注吧 :)2018 in the Ito Design Lab&#xff08;视频内容请关注微信公众号浏览&#xff09;1900~2018年城市温度异常变化可视化Temperatur…

面向可解释的NLP:北大、哈工大等提出文本分类的生成性解释框架

作者 | Hui Liu, Qingyu Yin, William Yang Wang 译者 | Rachel编辑 | Jane出品 | AI科技大本营&#xff08;ID: rgznai100&#xff09;【导语】北大、哈工大和加州大学圣巴巴拉分校在 ACL 2019 的一篇论文中联合提出了一个全新的生成性解释框架&#xff0c;该框架能够对分类策…

pyramid参数

2019独角兽企业重金招聘Python工程师标准>>> 普通参数permission: 该view的访问权限&#xff0c;这个后续会具体介绍。attr: Pyramid默认调用的是view类的__call__函数&#xff0c;如果需要指定调用其他方法&#xff0c;通过attr指定。如attrindex。renderer: 指定构…

Linux下常用的C/C++开源Socket库

1. Linux Socket Programming In C : http://tldp.org/LDP/LG/issue74/tougher.html 2. ACE: http://www.cs.wustl.edu/~schmidt/ACE.html ACE采用ACE_OS适配层屏蔽各种不同的、复杂繁琐的操作系统API。 ACE是一个大型的中间件产品&#xff0c;代码20万行左右&…

前端技术选型的遗憾和经验教训

我是Max&#xff0c;Spectrum的技术联合创始人。Spectrum 是一个面向大型在线社区的开源聊天应用程序&#xff0c;最近被GitHub收购。我们是一个三人团队&#xff0c;主要拥有前端和设计背景&#xff0c;我们在这个项目上工作了近两年时间。 事后看来&#xff0c;以下是我做出的…

时间序列的建模新思路:清华、李飞飞团队等提出强记忆力E3D-LSTM网络

作者 | Yunbo Wang,、Lu Jiang、 Ming-Hsuan Yang、Li-Jia Li、Mingsheng Long、Li Fei-Fei译者 | 凯隐编辑 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;【导读】如何对时间序列进行时空建模及特征抽取&#xff0c;是RGB视频预测分类&#xff0…

了解node.js

转载自http://debuggable.com/posts/understanding-node-js:4bd98440-45e4-4a9a-8ef7-0f7ecbdd56cb 当我向人们介绍node.js时&#xff0c;通常会得到两种反应&#xff0c;一种人马上就能了解&#xff0c;另一种则是非常困惑。 如果你是第二种人&#xff0c;请看一下我对node的解…

VS2013中Image Watch插件的使用(OpenCV)

之前在vs2010中写OpenCV程序时经常用NativeViewer&#xff0c;安装此插件后&#xff0c;在调试代码时&#xff0c;对于cv::Mat变量&#xff0c;CV_TYPE类型为CV_8UC1或CV_8UC3&#xff0c;可以随时查看显示结果。其操作步骤为&#xff1a;1. 从http://sourceforge.net/p…

【spring boot2】第8篇:spring boot 中的 servlet 容器及如何使用war包部署

嵌入式 servlet 容器 在 spring boot 之前的web开发&#xff0c;我们都是把我们的应用部署到 Tomcat 等servelt容器&#xff0c;这些容器一般都会在我们的应用服务器上安装好环境&#xff0c;但是 spring boot 中并不需要外部应用服务器安装这些servlet容器&#xff0c;spring …

让织梦内容页arclist标签的当前文章标题加亮显示

很多人在用织梦做站的时候&#xff0c;会用到在当前栏目页面&#xff0c;给当前栏目标题使用指定样式如标题加亮&#xff0c;或者放个背景图。这是一个很常用和实用的功能&#xff0c;比如在导航页面&#xff0c;标识当前在浏览哪个栏目。如下图&#xff1a; 但是有些时候&…

RHEL6入门系列之九,常用命令2

今天还是继续来学习Linux的基本命令。4、touch命令——建立空文件touch命令用于建立空文件。[rootlocalhost ~]# mkdir /root/test ‘创建目录/root/test[rootlocalhost ~]# touch /root/test/test1.txt ‘在目录/root/test中创建空文件test1.txt[rootlocalhos…

为什么华为200万招聘AI博士,马斯克却推出脑机接口对抗AI?

作者 | 伍杏玲来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;7 月&#xff0c;华为一则薪资通知刷爆朋友圈&#xff1a;华为给8位博士应届生给予 89.6 万至 201 万的年薪。其中薪资最高的两位博士均研究人工智能相关专业。7 月还有一件大事&#xff1a;马斯克发布…

Artistic Style在windows下的使用(C/C++)

ArtisticStyle是一个开源的源代码格式化工具。主页地址为&#xff1a;http://astyle.sourceforge.net/&#xff0c;它可以应用在C、C、Objective-C、C#、Java等程序语言中。http://astyle.sourceforge.net/astyle.html中为对使用它的详细介绍。从http://sourceforge.net/projec…

ESXi主机与网络中其他主机的网咯数据包捕获

1、tcpdump-uw -i vmk0 -s 1514 host x.x.x.x 指定捕获与某台主机间的网络数据包2、tcpdump -i vmk0 -s 1514 port not 22 and port not 53 在捕获的数据包中&#xff0c;过滤掉指定端口的数据包3、tcpdump-uw -i vmk0 -s 1514 -w traffic.pcap 捕获的数据包保存成PCAP文件&…

Windows下批处理文件(.bat)的使用

批处理(Batch)&#xff0c;就是进行批量的处理&#xff0c;英文译文BATCH&#xff0c;批处理文件后缀BAT就取的前三个字母&#xff0c;通常被认为是一种简化的脚本语言&#xff0c;它应用于DOS和Windows系统中。批处理文件是扩展名为.bat或.cmd的文本文件&#xff0c;包含一条或…

金融业加速智能化,解析360金融AI基础架构和应用

传统金融信贷业务中&#xff0c;催收、客服及电销人员占比超过 60%&#xff0c;人员素质参差不齐的现状造成了管理成本过高的问题&#xff0c;由此衍生的客户体验差&#xff0c;也成为困扰金融业的一大通病。 8 月 15 日&#xff0c;在 360金融 AI 媒体开放日上&#xff0c;360…