gpt4 book ai didi

python - 多个 Python 进程缓慢

转载 作者:太空狗 更新时间:2023-10-30 01:55:40 25 4
gpt4 key购买 nike

我有一个 python 脚本,它会启动并向各个域发出大量 HTTP 和 urllib 请求。

我们有大量域需要处理,需要尽快处理。由于 HTTP 请求很慢(即它们可能会超时,因为域上没有网站)我在任何时候都运行许多脚本,从数据库中的域列表中获取它们。

我看到的问题是在一段时间内(几小时到 24 小时)脚本都开始变慢并且 ps -al 显示它们正在休眠。

服务器非常强大(8 核、72GB 内存、6TB Raid 6 等 80MB 2:1 连接)并且永远不会达到极限,即 Free -m 显示

-/+ buffers/cache:      61157      11337
Swap: 4510 195 4315

顶部显示 80-90% 空闲

sar -d 显示平均 5.3% util

更有趣的是,iptraf 以大约 50-60MB/s 的速度开始,大约 4 小时后以 8-10MB/s 的速度结束。

我目前在每台服务器(2 台服务器)上运行大约 500 个版本的脚本,它们都显示相同的问题。

ps -al 显示大多数 python 脚本都在休眠,我不明白为什么例如:

0 S 0 28668  2987  0  80   0 - 71003 sk_wai pts/2 00:00:03 python
0 S 0 28669 2987 0 80 0 - 71619 inet_s pts/2 00:00:31 python
0 S 0 28670 2987 0 80 0 - 70947 sk_wai pts/2 00:00:07 python
0 S 0 28671 2987 0 80 0 - 71609 poll_s pts/2 00:00:29 python
0 S 0 28672 2987 0 80 0 - 71944 poll_s pts/2 00:00:31 python
0 S 0 28673 2987 0 80 0 - 71606 poll_s pts/2 00:00:26 python
0 S 0 28674 2987 0 80 0 - 71425 poll_s pts/2 00:00:20 python
0 S 0 28675 2987 0 80 0 - 70964 sk_wai pts/2 00:00:01 python
0 S 0 28676 2987 0 80 0 - 71205 inet_s pts/2 00:00:19 python
0 S 0 28677 2987 0 80 0 - 71610 inet_s pts/2 00:00:21 python
0 S 0 28678 2987 0 80 0 - 71491 inet_s pts/2 00:00:22 python

执行的脚本中没有 sleep 状态,所以我不明白为什么 ps -al 显示大多数人都在 sleep ,以及为什么当 CPU、内存、磁盘访问时,随着时间的推移,他们发出的 IP 请求会越来越慢和带宽都是可用的。

如果有人能提供帮助,我将不胜感激。

编辑:

代码量很大,因为我通过它使用异常来捕获有关域的诊断信息,即我无法连接的原因。如果需要,会在某处发布代码,但通过 HTTPLib 和 URLLib 的基本调用直接来自 python 示例。

更多信息:

两者

配额-u mysql配额-u root

一无所获

nlimit -n 返回 1024更改 limit.conf 以允许 mysql 允许 16000 个软连接和硬连接,并且到目前为止能够运行超过 2000 个脚本,但问题仍然存在。

一些进展

好的,所以我已经为用户更改了所有限制,确保所有套接字都已关闭(它们没有关闭),尽管情况有所好转,但我的速度仍然变慢了,虽然没有那么糟糕。

有趣的是,我还注意到一些内存泄漏 - 脚本运行时间越长,使用的内存就越多,但我不确定是什么原因造成的。我将输出数据存储在一个字符串中,然后在每次迭代后将其打印到终端,我也确实在最后清除了该字符串,但是不断增加的内存是否会下降到存储所有输出的终端?

编辑:不,似乎不是——运行了 30 个脚本而没有输出到终端,仍然是同样的泄漏。我没有使用任何聪明的东西(只是字符串、HTTPlib 和 URLLib)- 想知道 python mysql 连接器是否有任何问题...?

最佳答案

检查盒子和运行脚本的用户的 ulimitquota/etc/security/limits.conf 也可能包含您可能想要修改的资源限制。

ulimit -n 将显示允许打开的文件描述符的最大数量。

  • 是否已超过所有打开的套接字?
  • 脚本是否在完成后关闭每个套接字?

您还可以使用 ls -l/proc/[PID]/fd/ 检查 fd,其中 [PID] 是其中一个脚本的进程 ID。

需要查看一些代码以了解实际情况..


编辑(导入评论和更多故障排除想法):

你能展示一下你打开关闭连接的代码吗?
当只是运行一些脚本进程时,它们是否也开始运行一段时间后空闲?还是仅当同时运行数百个以上脚本时才会发生这种情况?
是否存在启动所有这些脚本的单个父进程?

如果您使用 s = urllib2.urlopen(someURL),请确保在完成后使用 s.close()。 Python 可以经常 为您关闭一些东西(比如如果您执行 x = urllib2.urlopen(someURL).read()),但它会将它留给 如果你被告知(例如将变量分配给 .urlopen() 的返回值)。仔细检查您打开和关闭的 urllib 调用(或所有 I/O 代码以确保安全)。如果每个脚本被设计为一次只有 1 个打开的套接字,并且您的 /proc/PID/fd 显示每个脚本进程有多个事件/打开的套接字,那么肯定有一个 代码 要解决的问题。

ulimit -n 显示 1024 给出 limit 打开 socket/fd mysql 用户可以拥有,您可以使用 ulimit -S -n [LIMIT_#] 更改此设置,但请先查看这篇文章:
Changing process.max-file-descriptor using 'ulimit -n' can cause MySQL to change table_open_cache value .

您可能需要注销并在之后重新登录。和/或将其添加到 /etc/bashrc(如果您更改了 bashrc,请不要忘记 source/etc/bashrc 并且不想要注销/登录)。

磁盘空间 是我发现的另一件事(困难的方法)会导致非常奇怪的问题。我遇到过一些进程表现得好像它们正在运行(不是僵尸化)但没有执行预期的操作,因为它们打开了一个日志文件的句柄,该句柄位于剩余磁盘空间为零的分区上。

netstat -anpTee | grep -i mysql 还将显示这些套接字是否已连接/已建立/正在等待关闭/等待超时/等。

watch -n 0.1 'netstat -anpTee | grep -i mysql' 在漂亮的表输出中实时查看套接字打开/关闭/更改状态/等(可能需要export GREP_OPTIONS= 首先,如果你将它设置为类似 --color=always 的东西。

lsof -u mysqllsof -U 也会显示打开的 FD(输出非常冗长)。


import urllib2
import socket

socket.settimeout(15)
# or settimeout(0) for non-blocking:
#In non-blocking mode (blocking is the default), if a recv() call
# doesn’t find any data, or if a send() call can’t
# immediately dispose of the data,
# a error exception is raised.

#......

try:
s = urllib2.urlopen(some_url)
# do stuff with s like s.read(), s.headers, etc..
except (HTTPError, etcError):
# myLogger.exception("Error opening: %s!", some_url)
finally:
try:
s.close()
# del s - although, I don't know if deleting s will help things any.
except:
pass

一些手册页和引用链接:

关于python - 多个 Python 进程缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7619259/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com