socket资源耗尽问题的追查

  • 问题表现:

    • 从某一天开始,主服务器上逐步出现了一些报错,比如:

      • 各种连接失败:mysql连接失败、redis连接失败,memcache插入数据失败
      • 某些时候,redis的llen命令返回值还异常,正常情况下应该是返回一个整数,但有时候会返回string,string的内容是“ok”。
    • 出现连接失败的频率变得越来越高。
  • 问题排查:
    • 首先排除网络原因,因为这些连接不是在本地,就是在内网。
    • 再次,排除连接数超过上限原因:监控能看到mysql/redis连接数并不多
    • 最后查了一下端口资源:sudo netstat -anp | wc -l,  你妹,2w多个, 其中绝大部分的连接状态是TIME_WAIT。好了,问题基本可以确定,就是socket连接过多,导致端口资源耗尽。
  • 问题解决

初步确定问题后,要找到问题的源头才好解决。所以要先查这些TIME_WAIT从哪里来的。确定基本都是mysql连接

netstat -anp | grep TIME_WAIT | awk ‘{print $5}‘ | sort | uniq -c | sort -nr | less

刚开始怀疑是网站前端php搞的,因为php的mysql连接都是短连接,短连接关闭以后,对应的socket连接状态就会变成TIME_WAIT,持续3s左右之后才会释放这个资源。如果前端请求较多,建立连接的速度超过释放速度,就会导致端口资源耗尽。但php涉及mysql地方较多,一时半会儿也优化不了,所以临时先想个方案处理一下,调整一下系统参数,设置socket连接可以重用(一般情况下不推荐):

echo 1 >> /proc/sys/net/ipv4/tcp_tw_reuse

调整系统参数后,安定了一个星期左右,然后又开始零星出现之前的连接失败问题。还得继续找到源头处理。用了一个很笨的办法,就是不断的查mysql的连接情况, 人工看有哪些连接经常出现,看是否能找到产生这些连接的程序

mysql -uuser -ppwd  -hdb_host -e "show full processlist"

结果还真发现,有一类sql请求异常的多次出现,异常的原因是因为每次出现的连接端口号都不同,这意味着这个请求在不断的申请和释放端口资源。而这个sql请求的程序理论上应该是一个长连接才对

查代码,发现程序是用的一个python的mysql库SQLAlchemy,代码如下:

# -*- coding: utf-8 -*-
import sqlalchemy
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from common.config import mysql

class MysqlSession(object):
    mysql_engine = None
    Session = None
    def init(self):
        mysqlStr = ‘mysql://{0}:{1}@{2}:{3}/{4}?charset=utf8‘              .format(mysql[‘username‘], mysql[‘password‘], mysql[‘host‘], mysql[‘port‘], mysql[‘dbname‘])

        MysqlSession.mysql_engine = sqlalchemy.create_engine(
            mysqlStr,
            encoding = "utf-8",
            pool_size=20,
            pool_recycle=10,
            echo = False)
        MysqlSession.Session = sessionmaker(bind=MysqlSession.mysql_engine)

    def getSession(self):
        session = MysqlSession.Session()
        return session

Base = declarative_base()

程序里在初始化的地方调用了上面的init,然后在一个循环里,不断的调用getSession,然后close session。特地去实验了一下,每次getSession确实都会从一个新的端口去连接mysql server。于是改掉此处,在循环外调用getSession和关闭 session,TIME_WAIT连接数很快就下降到几百!

看起来问题解决,后续继续观察。

时间: 2024-11-08 19:25:37

socket资源耗尽问题的追查的相关文章

TIME_WAIT状态的连接过多导致系统端口资源耗尽问题(2)

继上次解决完mysql连接过多,导致的TIME_WAIT进程过多问题之后,最近这个现象再一次出现,并且依然和之前一样严重.只不过这次出现问题的mysql 服务跟上次不一样,上一次主要是mysql master server,而这一次是mysql slave server.所以这意味着,我们上次解决了部分问题,但没有彻底解决,还存在一部分问题.所以这次彻底的把这个问题好好梳理一下. 再次确认一下TIME_WAIT进程的所属服务: sudo netstat -anp | grep TIME_WAIT

Linux磁盘空间被未知资源耗尽【转】

Linux磁盘空间被未知资源耗尽 在linux中,当我们使用rm在linux上删除了大文件,但是如果有进程打开了这个大文件,却没有关闭这个文件的句柄,那么linux内核还是不会释放这个文件的磁盘空间,最后造成磁盘空间占用100%,整个系统无法正常运行.这种情况下,通过df和du命令查找的磁盘空间,两者是无法匹配的,可能df显示磁盘100%,而du查找目录的磁盘容量占用却很小. 遇到这种情况,基本可以断定是某些大文件被某些程序占用了,并且这些大文件已经被删除了,但是对应的文件句柄没有被某些程序关闭

sping获取bean方法 解决资源耗尽

// ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml","spring-xxxxx.xml"}); // BeanFactory factory = (BeanFactory)context; // MonitorServer ce = (MonitorServer) factory.getBean("m

RAC环境产生大量ons进程,导致用户进程资源耗尽,用户切换提示Resource temporarily unavailable

基本要素(时间.用户.问题) 用户才实施了LINUX5.8+11.2.0.4的RAC环境,使用一段时间后,当切换的grid用户的时候,提示Resource temporarily unavailable,如下: [[email protected] bin]# su- grid su: cannot set userid: Resource temporarily unavailable 但是我们在切换其他用户如oracle用户的时候,却能够正常切换,并且CRS集群使用正常,客户端的连接和用户的

linux故障处理:磁盘资源耗尽故障

小生博客:http://xsboke.blog.51cto.com 小生 Q Q:1770058260 -------谢谢您的参考,如有疑问,欢迎交流 故障原因:磁盘空间已被大量的数据沾满空间耗尽,虽然还有可用空间,但文件数i节点也已耗尽 显而易见,当一个文件系统的磁盘空间耗尽以后,将无法继续在该分区中创建新的文件数据,从而导致故障的出现,例如:当根分区"/"中的磁盘空间耗尽以后,将可能导致部分程序乃至整个系统无法正常启动或运行,因为一些临时性的运行文件将无法建立 当根分区磁盘空间不足

tomcat JDBC连接池c3p0连接资源耗尽导致tomcat实例对应的app移动端无法访问。

tomcat app手机端程序无法打开了. 直接查看tomcat日志: [[email protected] logs]$ tail catalina.out          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)         at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(Task

生产上数据库大量的latch free 导致的CPU资源耗尽的问题的解决

中午的时候,我们生产上的某个数据库,cpu一直居高不下 通过如下的sql语句,我们查看当时数据库的等待,争用的情况: select s.SID, s.SERIAL#, 'kill -9 ' || p.SPID, s.MACHINE, s.OSUSER, s.PROGRAM, s.USERNAME, s.last_call_et, a.SQL_ID, s.LOGON_TIME, a.SQL_TEXT, a.SQL_FULLTEXT, w.EVENT, a.DISK_READS, a.BUFFER_

解决tail命令提示“tail: inotify 资源耗尽,无法使用 inotify 机制,回归为 polling 机制”

报错的原因是 inotify 跟踪的文件数量超出了系统设置的上限值,要是这个问题不经常出现可以使用临时解决方法,或者写入配置文件来永久解决. 临时解决方法: # 查看 inotify 的相关配置 $ sysctl fs.inotify fs.inotify.max_queued_events = 16384 fs.inotify.max_user_instances = 128 fs.inotify.max_user_watches = 8192 # 临时修改配置(重启后会恢复) $ sudo

记录一则ORA

应用服务器:Windows Server 2008 R2 Enterprise故障现象:项目侧同事反映应用服务器上的程序连接数据库报错:ORA-12560: TNS: 协议适配器错误 1.故障重现 2.定位问题 3.解决问题 1.故障重现 在应用服务器上使用sqlplus和PL/SQL工具登录连接数据库服务器均报错: ORA-12154: TNS: 无法解析指定的连接标识符 2.定位问题 2.1 ping测试网络 ping 数据库IP地址 网络通畅 C:\Users\Administrator>