Django調(diào)用外部Python程序的完整項(xiàng)目實(shí)戰(zhàn)
一、為什么 Django 需要調(diào)用外部 Python 程序
Django 是 Web 框架,但它經(jīng)常需要與外部腳本互動(dòng),例如:
- 啟動(dòng)某個(gè)獨(dú)立運(yùn)行的監(jiān)控腳本
- 執(zhí)行訓(xùn)練模型、特征提取腳本
- 啟動(dòng) CPU / 內(nèi)存壓力腳本
- 調(diào)用分析腳本并返回結(jié)果
- 運(yùn)行系統(tǒng)層面的 Python 工具
你的 AIOps 場(chǎng)景就是典型需求:
點(diǎn)擊前端按鈕 → 啟動(dòng) CPU 壓力腳本 → 持續(xù)采集數(shù)據(jù)
二、三種常見(jiàn)的調(diào)用方式
方式 1:直接 import 調(diào)用(輕量級(jí))
寫(xiě)一個(gè)外部腳本:
# scripts/calc.py
def calc():
return 1 + 1
Django 中調(diào)用:
from scripts.calc import calc
def index(request):
result = calc()
return HttpResponse(result)
這種方式最簡(jiǎn)單,但缺點(diǎn)也明顯:
不能用于啟動(dòng)長(zhǎng)期運(yùn)行的腳本(比如你的壓力腳本),因?yàn)闀?huì)阻塞 Django。
方式 2:subprocess 啟動(dòng)外部進(jìn)程(最常用)
適用于:
- CPU 壓力腳本
- 特征提取腳本
- 數(shù)據(jù)處理腳本
- 長(zhǎng)時(shí)間運(yùn)行程序
示例:
import subprocess
def run_script():
subprocess.Popen(["python", "scripts/load_cpu.py"])
它會(huì)啟動(dòng)一個(gè)完全獨(dú)立的 Python 進(jìn)程,不會(huì)阻塞 Django。
方式 3:Django 異步任務(wù)(高級(jí)版)
使用 Celery、Django-Q、Huey 等任務(wù)隊(duì)列:
- 任務(wù)會(huì)進(jìn)入隊(duì)列,不阻塞網(wǎng)頁(yè)
- 可以查看任務(wù)運(yùn)行狀態(tài)
- 可以重試、監(jiān)控
大型公司一般采用這種方式。但對(duì)入門(mén)來(lái)說(shuō)略復(fù)雜。
三、完整項(xiàng)目實(shí)戰(zhàn):用 Django 按鈕啟動(dòng) CPU 負(fù)載腳本
假設(shè)你想用 Django 前端按鈕啟動(dòng)下面這個(gè)腳本負(fù)載 CPU:
# scripts/cpu_stress.py
import time
def stress():
while True:
x = 0
for i in range(10_000_000):
x += i # 消耗 CPU
time.sleep(0.1)
不要讓 Django import 運(yùn)行,而是讓它跑在獨(dú)立進(jìn)程:
Step 1:將腳本放入項(xiàng)目目錄
project/
scripts/
cpu_stress.py
app/
views.py
Step 2:創(chuàng)建啟動(dòng)腳本的 view
# app/views.py
import subprocess
from django.http import JsonResponse
import os, sys
PROCESS = None
def start_stress(request):
global PROCESS
if PROCESS and PROCESS.poll() is None:
return JsonResponse({"msg": "已在運(yùn)行中"})
script = os.path.join(os.getcwd(), "scripts", "cpu_stress.py")
PROCESS = subprocess.Popen([sys.executable, script])
return JsonResponse({"msg": "啟動(dòng)成功"})
def stop_stress(request):
global PROCESS
if PROCESS:
PROCESS.terminate()
PROCESS = None
return JsonResponse({"msg": "已停止"})
return JsonResponse({"msg": "沒(méi)有正在運(yùn)行的任務(wù)"})
Step 3:前端按鈕示例
<button onclick="fetch('/start_stress').then(r=>r.json()).then(alert)">啟動(dòng)負(fù)載</button>
<button onclick="fetch('/stop_stress').then(r=>r.json()).then(alert)">停止負(fù)載</button>
前端只需發(fā)起請(qǐng)求,Django 隨即啟動(dòng)或終止壓力腳本。
四、常見(jiàn)錯(cuò)誤示例與調(diào)試技巧
錯(cuò)誤 1:使用 import 直接運(yùn)行死循環(huán)
錯(cuò)誤寫(xiě)法:
from scripts.cpu_stress import stress
def start(request):
stress() # ? 會(huì)把 Django 線(xiàn)程卡死
原因:
壓力腳本死循環(huán) → Django 視圖無(wú)法返回 → 網(wǎng)站掛掉。
錯(cuò)誤 2:subprocess 沒(méi)寫(xiě)絕對(duì)路徑
錯(cuò)誤寫(xiě)法:
subprocess.Popen(["python", "cpu_stress.py"]) # ? 找不到腳本
正確寫(xiě)法:
script = os.path.join(os.getcwd(), "scripts", "cpu_stress.py") subprocess.Popen([sys.executable, script])
錯(cuò)誤 3:Windows 進(jìn)程無(wú)法 terminate
在 Windows 上,某些子進(jìn)程會(huì)繼續(xù)掛著,可以改為:
PROCESS.kill()
調(diào)試技巧:查看子進(jìn)程是否啟動(dòng)
Linux / WSL:
ps aux | grep cpu_stress
Windows:
tasklist | findstr python
這類(lèi)調(diào)試技巧在 AIOps 項(xiàng)目中非常常用。
五、生產(chǎn)環(huán)境高級(jí)技巧
1. 使用日志記錄子進(jìn)程輸出
subprocess.Popen(
[sys.executable, script],
stdout=open("out.log", "w"),
stderr=open("err.log", "w")
)
方便你排查模型腳本/壓力腳本的問(wèn)題。
2. 給腳本加鎖,避免重復(fù)啟動(dòng)
if PROCESS and PROCESS.poll() is None:
# 已經(jīng)在運(yùn)行中
防止用戶(hù)瘋狂點(diǎn)擊按鈕導(dǎo)致重復(fù)啟動(dòng)多個(gè)壓力腳本。
3. 使用 Redis / 數(shù)據(jù)庫(kù)存儲(chǔ)子進(jìn)程 PID
生產(chǎn)環(huán)境推薦:
- Django View 啟動(dòng)腳本
- 保存 PID 到 Redis
- 前端通過(guò) PID 判斷腳本是否在運(yùn)行
4. 避免 SQLite 作為生產(chǎn)數(shù)據(jù)庫(kù)
你的前端壓力腳本會(huì)導(dǎo)致 SQLite 鎖表問(wèn)題。
生產(chǎn)中建議使用:
- PostgreSQL(最常用)
- MySQL / MariaDB
SQLite 不適合頻繁寫(xiě)入+多進(jìn)程并發(fā)。
六、背后原理與機(jī)制拓展
Django 本身不能跑長(zhǎng)任務(wù)
Django 是典型的:
- 同步請(qǐng)求 → 同步響應(yīng)
- 一個(gè)請(qǐng)求不能占用長(zhǎng)時(shí)間
所以它天生不適合:
- 死循環(huán)腳本
- 深度學(xué)習(xí)訓(xùn)練任務(wù)
- CPU 壓力測(cè)試腳本
- 視頻特征提取任務(wù)
這類(lèi)任務(wù)應(yīng)該由:
- subprocess
- Celery
- 后臺(tái) Worker
來(lái)完成。
為什么 subprocess 是最常用方案?
因?yàn)椋?/p>
- 獨(dú)立進(jìn)程,不影響 Django 主進(jìn)程
- 可以 kill / terminate
- 支持長(zhǎng)時(shí)間運(yùn)行
- 支持日志
- 支持參數(shù)傳遞
- Windows / Linux 都能跑
它是 AIOps 平臺(tái)后臺(tái)運(yùn)行腳本的最基礎(chǔ)工具。
總結(jié)
文章介紹了 Django 調(diào)用外部 Python 腳本的三種方法,并通過(guò)完整的項(xiàng)目案例展示如何用 Django 前端按鈕啟動(dòng)與停止 CPU 壓力腳本,同時(shí)補(bǔ)充了常見(jiàn)錯(cuò)誤、調(diào)試技巧、高級(jí)實(shí)踐和背后原理。
到此這篇關(guān)于Django調(diào)用外部Python程序的文章就介紹到這了,更多相關(guān)Django調(diào)用外部Python程序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Django框架orM與自定義SQL語(yǔ)句混合事務(wù)控制操作
這篇文章主要介紹了Django框架orM與自定義SQL語(yǔ)句混合事務(wù)控制操作,結(jié)合實(shí)例形式分析了同一個(gè)方法里面既有ORM又有自定義SQL 語(yǔ)句的情況下事務(wù)控制相關(guān)操作技巧,需要的朋友可以參考下2019-06-06
Python進(jìn)程的通信Queue、Pipe實(shí)例分析
這篇文章主要介紹了Python進(jìn)程的通信Queue、Pipe,結(jié)合實(shí)例形式分析了Python進(jìn)程通信Queue、Pipe基本概念、用法及操作注意事項(xiàng),需要的朋友可以參考下2020-03-03
詳解Python實(shí)現(xiàn)按任意鍵繼續(xù)/退出的功能
在學(xué)Python時(shí)在總想實(shí)現(xiàn)一個(gè)按任意鍵繼續(xù)/退出的程序(受.bat毒害), 奈何一直沒(méi)有寫(xiě),今天抽時(shí)間寫(xiě)出來(lái)了,下面分享給大家,有需要的可以參考借鑒。2016-08-08
Ubuntu 下 vim 搭建python 環(huán)境 配置
這篇文章主要介紹了Ubuntu 下 vim 搭建python環(huán)境配置,需要的朋友可以參考下2017-06-06

