[20200305]netstat state=ESTABLISHED and timer=probe 2.txt
1.问题提出:
--//生产系统执行netstat发现大量的state=ESTABLISHED和timer=probe的网络链接。
# netstat -tnop 2>/dev/null | grep probe |wc -l
351
# netstat -tnop 2>/dev/null | grep probe |head -2
tcp 0 32120 aaa.bbb.ccc.ddd:1521 qqq. ESTABLISHED 16957/oraclezzzz1 probe (18.23/0/0)
tcp 0 32120 aaa.bbb.ccc.ddd:1521 qqq. ESTABLISHED 12413/oraclezzzz1 probe (19.25/0/0)
--//而processes=5000,几乎消耗351/5000*100=7.02%。而且如果从客户端查询网络连接已经消失了,也就是这些连接是死连接,毫无用
--//处。实际上春节前我就注意到这个问题,但是我没探究,因为高峰时连接数已经达到48XX。如果疫情一过,进程的网络连接数肯定不
--//足。
--//顺便说一下使用netatat和ss遇到的问题,如果在oracle,grid用户执行netstat -tnop 。在PID/Program name列是看不到进程号相
--//关信息的,注意一定要使用root用户执行,在PID/Program name列才有显示,
--//切记,我这里犯了一点点小错误。
--//另外ss 只要加入-p参数执行异常缓慢,不知道为什么。而且ss显示太宽,我以前讲过使用column -t 过滤,实际上不对齐。
--//应该使用expand效果更好。而且视乎存在某个缓存的问题,一段一段的输出信息在使用expand过滤时。
--//而且还有小部分是state=FIN_WAIT1(占11个), timer=probe的情况。
--//如果你连续检查:
# watch -d -t -n 1 "netstat -tnop 2>/dev/null | grep qqq."
# seq 100 | xargs -IQ bash -c "netstat -tnop 2>/dev/null | grep qqq.| ts.awk ; sleep 1"
[2020-03-05 16:23:58] tcp 0 32120 aaa.bbb.ccc.ddd:1521 qqq. ESTABLISHED 16957/oraclezzzz1 probe (3.29/0/0)
[2020-03-05 16:24:00] tcp 0 32120 aaa.bbb.ccc.ddd:1521 qqq. ESTABLISHED 16957/oraclezzzz1 probe (1.07/0/0)
[2020-03-05 16:24:02] tcp 0 32120 aaa.bbb.ccc.ddd:1521 qqq. ESTABLISHED 16957/oraclezzzz1 probe (119.22/0/0)
[2020-03-05 16:24:04] tcp 0 32120 aaa.bbb.ccc.ddd:1521 qqq. ESTABLISHED 16957/oraclezzzz1 probe (117.17/0/0)
[2020-03-05 16:24:06] tcp 0 32120 aaa.bbb.ccc.ddd:1521 qqq. ESTABLISHED 16957/oraclezzzz1 probe (115.08/0/0)
[2020-03-05 16:24:09] tcp 0 32120 aaa.bbb.ccc.ddd:1521 qqq. ESTABLISHED 16957/oraclezzzz1 probe (112.88/0/0)
--//probe后面的第1参数120->0->120->0不断反复。state=FIN_WAIT1也是一样。第2,第3参数都是0,从来没有变化。
--//注: The interpretation of field is, first field = timer countdown value, second field = no. of retransmissions,
--//third field= number of keepalive probes sent.
# ps -eLf | grep 1695[7]
oracle 16957 1 16957 0 1 Jan14 ? 00:00:01 oraclezzzz1 (LOCAL=NO)
--//STIME=Jan19,我抽查发现有一些显示2019. 如何显示完整的日期格式不知道.
2.问题分析:
--//通过数据库查询看看,我们系统通过触发器在v$session.client_info记录IP地址。
# netstat -tnop 2>/dev/null | grep probe |grep oraclezzzz1|awk '{print $5}' | sed -e "s/:/',/" -e "s/^/('/" -e "s/$/),/"
('qqq.),
...
SELECT *
FROM v$session
WHERE (client_info, port) IN ( ('qqq. 51586)
....
, ('qqq. 55470))
--//结果不再贴出,logon_time跨度 2019/11/27 17:15:38 -2020/2/7 10:31:31。
SELECT PREV_EXEC_START,logon_time,(PREV_EXEC_START-logon_time)*86400 sec,prev_sql_id
FROM v$session
WHERE (client_info, port) IN ( ('qqq. 51586)
...
, ('qqq. 55470))
order by 3 desc
--//(PREV_EXEC_START-logon_time)*86400大部分都是0或者是-1,而且prev_sql_id=b5j7y2r5zr37t.
> @ tpt/sqlid b5j7y2r5zr37t %
Show SQL text, child cursors and execution stats for SQLID b5j7y2r5zr37t child nvl('%','%')
HASH_VALUE PLAN_HASH_VALUE CH# SQL_TEXT
---------- --------------- ---- ------------------------------------------------------------------------------------------------------------------------------------------------------
3422260473 0 0 declare PRIVS_ERROR exception; --raise error,if rule exception,will trigger privs_error pragma exception_init(PRIVS_ERROR,-1031);
begin execute immediate 'begin tlogon.logon; end;'; exception when PRIVS_ERROR then raise; when others then rollback; end
capaalogon;
CH# PARENT_HANDLE OBJECT_HANDLE PLAN_HASH PARSES H_PARSES EXECUTIONS FETCHES ROWS_PROCESSED ROWS_PER_FETCH CPU_SEC CPU_SEC_EXEC ELA_SEC ELA_SEC_EXEC LIOS LIOS_EXEC PIOS SORTS USERS_EXECUTING
---- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- -------------- -------------- ---------- ------------ ---------- ------------ ---------- ---------- ---------- ---------- ---------------
0 000000131D196028 00000001FC3F2828 0 63547049 8 63588712 0 63587482 789794.321 .012420354 823529.875 .012950882 344748703 5.42153933 5343 0 0
--//防水墙导致的问题吗?从PREV_EXEC_START-logon_time的差值看登录马上就挂了。不会是该内核版本在网络处理上有bug,即使防水
--//墙导致连接断开,连接也不应该保持这么久不会断开。
3.先解决state=FIN_WAIT1的情况:
--//参考连接: https://blog.csdn.net/microgp/article/details/86588973
FIN_WAIT1:
1、sysctl -a |grep net.ipv4.tcp_max_orphans(记下 net.ipv4.tcp_max_orphans的值第三步需要赋给orig_orphans)
2、sysctl -w net.ipv4.tcp_max_orphans=0 然后等待FIN_WAIT1的消失,可以用 netstat -np|grep 9080 反复查看,直到没有任何条目
3、sysctl -w net.ipv4.tcp_max_orphans=$orig_orphans
--//在测试前我在测试环境做了测试,修改它并不影响业务。建议大家还是小心谨慎,自己再测试看看。
# sysctl -a |grep net.ipv4.tcp_max_orphans
net.ipv4.tcp_max_orphans = 262144
# sysctl -w net.ipv4.tcp_max_orphans=0
--//我的测试最多等3*120秒这些连接state=FIN_WAIT1会全部消失。
# sysctl -w net.ipv4.tcp_max_orphans =262144
4.解决state=ESTABLISHED and timer=probe:
--//先找一个不太重要的进程看看。
# netstat -tnop 2>/dev/null | grep 112514
tcp 0 25245 aaa.bbb.ccc.ddd:1521 rrr.ttt.yyy.215:1301 ESTABLISHED 112514/oraclezzzz1 probe (36.31/0/0)
# kill -9 112514
# ps -ef | grep 11251[4]
# netstat -tnop 2>/dev/null | grep rrr.ttt.yyy.215:1301
tcp 0 25246 aaa.bbb.ccc.ddd:1521 rrr.ttt.yyy.215:1301 FIN_WAIT1 - probe (57.31/0/0)
--//昏,state=FIN_WAIT1,对应进程已经不见了。但是链接还是保持,state=FIN_WAIT1。现在想想前面看到state=FIN_WAIT1的连接,不会当
--//时kill进程留下的把。
--//重复处理state=FIN_WAIT1步骤,该连接也会消失。
--//批量处理就简单了。
1.先看一下是否都是oracle相关进程,不能是一些特殊进程,避免数据库down掉.
# netstat -tnop 2>/dev/null | grep probe | awk '{print $7}' | cut -f1 -d"/" | paste -sd, | xargs ps v -p | column -t
2.建立kill脚本
# netstat -tnop 2>/dev/null | grep probe | awk '{print $7}' | cut -f1 -d"/"|xargs -IQ echo kill -9 Q
3.执行:
# netstat -tnop 2>/dev/null | grep probe | awk '{print $7}' | cut -f1 -d"/"|xargs -IQ echo kill -9 Q | bash
or
# netstat -tnop 2>/dev/null | grep probe | awk '{print $7}' | cut -f1 -d"/"|xargs -IQ kill -9 Q
--//不放心把上面的脚本copy下来,单独自行。另外必须提的是如果net.ipv4.tcp_max_orphans=0,kill -9进程后马上查询
--// netstat -tnop 2>/dev/null | grep probe马上消失。
--//不会出现前面state=FIN_WAIT1的情况。必须记住执行 sysctl -w net.ipv4.tcp_max_orphans=262144修改该参数回来。
4.检查netsta 是否还有timer=probe的信息.
# netstat -tnop 2>/dev/null | grep probe
5.总结:
--//1.不知道是否是在业务高峰密集登录导致的网络异常.因为登录是绕不开那个语句的执行的,还是该内核版本在网络上的bug.
--//2.netstat -ntop 注意选择root用户执行,不然看不到PID/Program name相关信息.
--//补充一点在我的测试环境oracle用户执行没有问题,有点奇怪。
--//3.我感觉不能使用SQLNET.EXPIRE_TIME检测网络连接,也许使用tcp keepalive特性要好一些.明天修改它,在1台机器使用
--//tcp keepalive特性,另外1台保持不变,再观察看看.
--//我们rac环境跑2个数据库,一台使用tcp keepalive特性,另外一台使用SQLNET.EXPIRE_TIME.再观察看看。
net.ipv4.tcp_keepalive_time = 590
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 4
--//4.另外我怀疑我们前台接入认证的软件引起的问题。windows开机出现登录界面快,实际上是一个假象,我们登录后接入认证的程序
--//设计不好,会弹出一个界面,如果用户选择X而不是最小化,机器无法接入网络,不知道这个是否会引起这个问题。
--//5.对这个团队再次失望,没人重视这些细节问题。这样被动的维护系统,真不知道以后会出什么事情。今天上班检查发现再次出现2
--//个链接。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-2678760/ ,如需转载,请注明出处,否则将追究法律责任。