问题1

多人共享开发服务器(windows系统),我们小组有个程序,定时检测mongodb,redis,mysql连接是否正常,程序启动一段时间后,服务器管理人员找到我们说,我们的某个pid的程序把TCP连接占满了,很多功能都不可使用,第一次调查发现未关闭连接,然后修改了,修改之后还是会出现TCP连接被全部耗尽的情况。

调查

复现问题

启动上述问题程序,找到其对应的java的pid,查看其建立的线程数

netstat -ano | findstr "" | find /v /c ""

发现TCP连接在很短的时间内,增长非常快,程序的确有问题

由于我们程序中比较占用TCP的就只有在获取上述三个服务连接的时候,同事讲关闭连接没问题,所以也就没有怎么注意那块,有同事反馈mongodb,mysql,redis都正常连接的时候没有出现问题,故分别停掉以上三个数据库,查看该程序占用的TCP连接数

最后发现,停掉redis的时候,TCP连接数增长非常快,所以怀疑是redis连接问题,最后还是要去看下代码,经过查看代码,找到了一个怀疑的点,代码中是这么写的

private RedisClient client;
private StatefulRedisConnection<String,String> conn; public void redisTest(){
try{
client=...
conn=...
....
}catch(Exception e){
logger.error("",e)
}finally{
try{
conn.close();
client.close();
}catch(Exception ex){
logger.error("",ex)
}
}
}

乍一看,似乎没什么大问题,但这里隐藏了一个不是必现的BUG,由于我们一般启动程序时,都会配置正确连接,但如果上面的conn为空怎么办嘞,很明显会发生空指针,后面的client连接自然就不会释放,但奇怪的是,在日志文件中也并没有发现空指针异常日志输出。

为了验证猜想,在finally中分别打印出上述conn和client的值

验证了猜想,conn为空,造成后面的client未被释放。找到了问题,代码修改比较简单,只需要在finally块中对conn和client做非空判断即可

}finally{
try{
if (conn != null){
conn.close();
}
if(client != null){
client.close();
}
}catch(Exception ex){
logger.error("",ex)
}
}

连接不释放,TCP连接一直快速增长,造成的危害很大,在代码中,关闭多个连接时,一定要注意非空判断。

问题2

程序跑一段时间,内存占用超过了平时的4,5倍

调查

网上有讲在使用free -m查看内存时,不能只看used,因为在linux的内存分配机制中,优先使用物理内存,当物理内存还有空闲时,不会释放其占用内存,就算占用内存的程序已经被关闭了,该程序所占用的内存用来做缓存使用,对于开启过的程序、或是读取刚存取过得数据会比较快,应该查看buffers/cached+free,才是可用内存,但通过free -m查看本机的内存占用时,发现buffers/cached+free占用的内存不多,实际被使用到的内存达到了30个G,通过top命令查看每个程序占用到的内存也并不多,每个程序占用内存的百分比都很少,VIRT占用比较大,但它并不是程序占用的内存。

我们知道每个TCP连接也是耗内存的,那会不会是连接数过多造成的内存剧增,查看连接数

netstat -na | grep ESTABLISHED

发现有某个地址的连接非常多

查看当前机器总共建立连接

[root@localhost data]# netstat -na|grep ESTABLISHED|wc -l

该链接数还在增长,查看上述出现次数比较多的tcp连接数量(肉眼查看到的,比较low的方法,其实可以用脚本统计处每个外部地址占用的连接数)

[root@localhost data]# netstat -na|grep ESTABLISHED|grep ip_addr |wc -l

发现几乎所有建立的连接都来自这台外部机器,这台机器部署的了一个模拟程序,停止模拟程序,内存恢复到正常状态。

脚本统计每个连接到本机的ip的TCP连接数

netstat -na | grep ESTABLISHED | awk '{print $5}'| awk -F ":" '{print $1}'| sort | uniq -c

第一行为连接总数,第二行为连接当前服务器ip地址

记录Redis连接未正确释放,TCP连接过多,造成服务器上部分功能不可用和linux服务器内存一直增加问题的更多相关文章

  1. golang 网络编程之如何正确关闭tcp连接以及管理它的生命周期

    欢迎访问我的个人网站获取更佳阅读排版 golang 网络编程之如何正确关闭tcp连接以及管理它的生命周期 | yoko blog (https://pengrl.com/p/47401/) 本篇文章部 ...

  2. TCP系列05—连接管理—4、TCP连接的ISN、连接建立超时及TCP的长短连接

    一.TCP连接的ISN         之前我们说过初始建立TCP连接的时候的系列号(ISN)是随机选择的,那么这个系列号为什么不采用一个固定的值呢?主要有两方面的原因 防止同一个连接的不同实例(di ...

  3. TCP系列04—连接管理—3、TCP连接的半打开和半关闭

    在前面部分我们我们分别介绍了三次握手.四次挥手.同时打开和同时关闭,TCP连接还有两种场景分别是半打开(Half-Open)连接和半关闭(Half-Close)连接.TCP是一个全双工(Full-Du ...

  4. TCP系列07—连接管理—6、TCP连接管理的状态机

            经过前面对TCP连接管理的介绍,我们本小节通过TCP连接管理的状态机来总结一下看看TCP连接的状态变化 一.TCP状态机整体状态转换图(截取自第二版TCPIP详解) 二.TCP连接建立 ...

  5. TCP系列03—连接管理—2、TCP连接的同时打开和同时关闭

    在前面的内容中我们介绍了TCP连接管理中最常见的三次握手方式和四次挥手的方式.但是有可能A和B两端同时执行主动打开并连接对方或者同时执行主动关闭连接(尽管发生这种情况的可能性比较低低),这个时候的流程 ...

  6. 简述采用四次握手机制释放TCP连接的四个步骤

    (1)源结点A向目的结点B发送连接释放请求(FIN,seg=x),并且不再向B发送数据,但仍继续接收从B发来的数据. (2)目的结点B收到此连接释放请求后立即向A发出确认(ACK,ack=x+1),但 ...

  7. 简述TCP连接的建立与释放(三次握手、四次挥手)

    在介绍TCP连接的建立与释放之前,先回顾一下相关知识. TCP是面向连接的运输层协议,它提供可靠交付的.全双工的.面向字节流的点对点服务.HTTP协议便是基于TCP协议实现的.(虽然作为应用层协议,H ...

  8. TCP连接的建立与释放(三次握手与四次挥手)

    TCP连接的建立与释放(三次握手与四次挥手) TCP是面向连接的运输层协议,它提供可靠交付的.全双工的.面向字节流的点对点服务.HTTP协议便是基于TCP协议实现的.(虽然作为应用层协议,HTTP协议 ...

  9. TCP连接三次握手协议,释放连接四次挥手,以及使用 awl伪造mac地址进行多线程syn洪泛攻击。

    这个TCP连接就是一次追女生-谈恋爱-分手,追求比分手简单,但是分手比追求复杂.哥,谈了半年的女朋友,在就快要成功了的时候分了,原因是因为有人在后面该老子背后搞SYN洪泛攻击,最后女朋友丢失了.学会T ...

随机推荐

  1. 如何使用Visual Studio Code调试PHP CLI应用和Web应用

    在按照Jerry的公众号文章 什么?在SAP中国研究院里还需要会PHP开发? 进行XDebug在本地的配置之后,如果想使用Visual Studio Code而不是Eclipse来调试PHP应用,步骤 ...

  2. [LeetCode] 784. 字母大小写全排列 ☆☆☆(回溯、深度优先遍历)

    https://leetcode-cn.com/problems/letter-case-permutation/solution/shen-du-you-xian-bian-li-hui-su-su ...

  3. nginx环境依赖

    安装nginx所必需的的依赖环境 yum -y install pcre pcre-devel yum -y install zlib zlib-devel yum -y install zlib z ...

  4. C#当中使用async和await

    最近在写程序的时候,经常遇到大量需要异步访问的情况,但是对于async和await到底怎么写,还不是非常明确.于是参考<C#图解教程>了异步编程一节. 1.普通的程序怎么写? class ...

  5. 透过字节码生成审视Java动态代理运作机制

    对于动态代理我想应该大家都不陌生,就是可以动态去代理实现某个接口的类来干一些我们自己想要的功能,但是在字节码层面它的表现是如何的呢?既然目前刚好在研究字节码相关的东东,有必要对其从字节码角度来审视一下 ...

  6. 云计算下的企业IT运维

    云计算管理员们一般都工作在一个分布式局域网计算基础设施中,它与传统数据中心最大的区别之一就是,所有被存储.调配和管理的数据都在一个私有云中.基于云计算的高效工作负载监控可在性能发生问题之前就提前发现这 ...

  7. centos ntfs-3g not find

    1,CentOS默认源里没有ntfs3g,想要添加ntfs支持,需要自己下载编译安装或者加源yum安装.我这里使用的是添加aliyun的epel源来yum安装的方式. 2,添加epel yum源wge ...

  8. 这些Winforms界面开发技巧你还没学会?OUT了

    DevExpress Winforms Controls内置140多个UI控件和库,完美构建流畅.美观且易于使用的应用程序.无论是Office风格的界面,还是分析处理大批量的业务数据,DevExpre ...

  9. Python中的memoryview

    Python中的memoryview提供了类似C语言指针的功能,有了memoryview,如果某个Object支持buffer protocol,那么就可以通过memory去访问到他的内部. Pyth ...

  10. 谈CSRF与JSONP设置header问题

    关于前端发起请求 问题一 JS发起请求的方式 方法一 JS代码中发起请求的方式普遍为AJAX 该技术在 1998 年前后得到了应用.允许客户端脚本发送HTTP请求(XMLHTTP) 方法二 scrip ...