Closed greensea closed 4 years ago
问题现象:
问题出现后,通过 netstat 查看 ardb 的网络连接情况,发现有大量 CLOSE_WAIT 状态的连接。
如何重现: 目前没有办法重现,这个现象只在生产环境上出现,生产环境上的 ops 大概是 1k~2k,同时连接数不到 10 个,高峰时同时连接数不超过 1000 个。 我尝试在本地模拟 5000 个用户同时连接,并执行 GET, SET, HSET, HGET 等指令,试图模拟服务器状态,但未能重现。
大致分析: 在服务器出现此问题后,使用 strace 工具进行了一些分析,发现主进程会循环执行下面的操作:
epoll_wait(...),随后获得一个 fd accept4(...),随后成功创建一个与客户端的连接 write(30, "\2\0\0\0\1\0\0\0", 8) = -1 EAGAIN ...不断循环以上过程
可以看到,主进程似乎一直卡在 write(30, ...) 这个行为上无法自拔。30 这个 fd 似乎是一个 FIFO 管道。
经过进一步的调试,发现主进程应该是在向一个线程通过 FIFO 发送消息,但接收此 FIFO 消息的线程似乎一直没有去读取 FIFO 的内容。
接收这个 FIFO 的线程似乎是负责处理 redis 命令并返回结果的线程,这个线程似乎冻结住了,所以造成了上面所说的情况。
怀疑是 systemd 的锅。虽然我使用的 systemd 配置文件是从 redis.service 复制过来修改的,但也检查过一遍,没发现有什么问题。 现在不用 systemd,直接手动启动 ardb,一切正常。
问题现象:
问题出现后,通过 netstat 查看 ardb 的网络连接情况,发现有大量 CLOSE_WAIT 状态的连接。
如何重现: 目前没有办法重现,这个现象只在生产环境上出现,生产环境上的 ops 大概是 1k~2k,同时连接数不到 10 个,高峰时同时连接数不超过 1000 个。 我尝试在本地模拟 5000 个用户同时连接,并执行 GET, SET, HSET, HGET 等指令,试图模拟服务器状态,但未能重现。
大致分析: 在服务器出现此问题后,使用 strace 工具进行了一些分析,发现主进程会循环执行下面的操作:
epoll_wait(...),随后获得一个 fd accept4(...),随后成功创建一个与客户端的连接 write(30, "\2\0\0\0\1\0\0\0", 8) = -1 EAGAIN ...不断循环以上过程
可以看到,主进程似乎一直卡在 write(30, ...) 这个行为上无法自拔。30 这个 fd 似乎是一个 FIFO 管道。
经过进一步的调试,发现主进程应该是在向一个线程通过 FIFO 发送消息,但接收此 FIFO 消息的线程似乎一直没有去读取 FIFO 的内容。
接收这个 FIFO 的线程似乎是负责处理 redis 命令并返回结果的线程,这个线程似乎冻结住了,所以造成了上面所说的情况。