在Heroku上的Python/Django应用中执行ICMP Ping的问题
解决Heroku上Django应用调用ping命令找不到的问题
问题根源
你已经通过apt buildpack安装了iputils-ping,但Heroku的默认PATH环境变量并没有包含apt包安装的二进制文件路径,所以系统找不到ping命令。apt buildpack会把软件安装在/app/.apt/usr/bin目录下,这个路径不在默认PATH里。
直接解决方案:使用绝对路径调用ping
修改你的subprocess调用,把"ping"替换成ping命令的绝对路径:
result = subprocess.run(["/app/.apt/usr/bin/ping", "-c", "2", url], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
如果不确定路径,可以通过Heroku命令行工具进入dyno控制台执行which ping,就能得到准确的路径。
另一种方案:添加apt路径到系统PATH
在Django的启动文件(比如settings.py)里,把apt的bin目录添加到环境变量PATH中,这样后续调用ping就不用写绝对路径了:
import os # 将apt安装的二进制路径加入PATH os.environ["PATH"] += os.pathsep + "/app/.apt/usr/bin"
更适合Heroku的替代方案:用HTTP请求检测网站状态
ping依赖ICMP协议,Heroku的dyno对ICMP有一定限制,而且需要额外安装包。其实可以直接用Python的requests库发送HTTP HEAD请求来检测网站是否可达,这种方式更简单且不需要额外依赖:
import requests def check_site_status(url): try: # 发送HEAD请求,比GET更轻量 resp = requests.head(url, timeout=5) # 只要状态码在2xx范围内就算正常 return 200 <= resp.status_code < 300 except requests.exceptions.RequestException: # 出现异常说明网站不可达 return False
这个方法不需要安装iputils-ping,也不会遇到路径问题,更适配Heroku的运行环境。
内容的提问来源于stack exchange,提问作者racinjasin
相关产品推荐
相关产品推荐

