perf: server/status接口优化(cpu非阻塞+pm2直接调用+COUNT估算+5秒缓存)
This commit is contained in:
parent
fbf84f2be5
commit
748f6f57a5
@ -458,11 +458,40 @@ async def get_signal_trades(
|
|||||||
|
|
||||||
import shutil, subprocess, psutil
|
import shutil, subprocess, psutil
|
||||||
|
|
||||||
|
# 服务器状态缓存(避免重复调用慢操作)
|
||||||
|
_server_cache: dict = {"data": None, "ts": 0}
|
||||||
|
_PM2_BIN = None
|
||||||
|
|
||||||
|
def _find_pm2_bin():
|
||||||
|
"""找到pm2二进制路径,避免每次走npx"""
|
||||||
|
global _PM2_BIN
|
||||||
|
if _PM2_BIN:
|
||||||
|
return _PM2_BIN
|
||||||
|
import shutil as _sh
|
||||||
|
for p in ["/home/fzq1228/.local/bin/pm2", "/usr/local/bin/pm2", "/usr/bin/pm2"]:
|
||||||
|
if os.path.exists(p):
|
||||||
|
_PM2_BIN = p
|
||||||
|
return p
|
||||||
|
found = _sh.which("pm2")
|
||||||
|
if found:
|
||||||
|
_PM2_BIN = found
|
||||||
|
return found
|
||||||
|
return "npx pm2"
|
||||||
|
|
||||||
|
# 启动时初始化CPU采样(首次调用不阻塞)
|
||||||
|
psutil.cpu_percent(interval=None)
|
||||||
|
|
||||||
@app.get("/api/server/status")
|
@app.get("/api/server/status")
|
||||||
async def get_server_status(user: dict = Depends(get_current_user)):
|
async def get_server_status(user: dict = Depends(get_current_user)):
|
||||||
"""服务器全状态:CPU/内存/硬盘/负载/PM2进程/PG数据库/回补进度"""
|
"""服务器全状态:CPU/内存/硬盘/负载/PM2进程/PG数据库/回补进度"""
|
||||||
# CPU
|
|
||||||
cpu_percent = psutil.cpu_percent(interval=0.5)
|
# 5秒缓存,避免频繁调用慢操作
|
||||||
|
now = time.time()
|
||||||
|
if _server_cache["data"] and (now - _server_cache["ts"]) < 5:
|
||||||
|
return _server_cache["data"]
|
||||||
|
|
||||||
|
# CPU(非阻塞,取上次采样间隔的值)
|
||||||
|
cpu_percent = psutil.cpu_percent(interval=None)
|
||||||
cpu_count = psutil.cpu_count()
|
cpu_count = psutil.cpu_count()
|
||||||
|
|
||||||
# 内存
|
# 内存
|
||||||
@ -482,12 +511,14 @@ async def get_server_status(user: dict = Depends(get_current_user)):
|
|||||||
# 网络IO
|
# 网络IO
|
||||||
net = psutil.net_io_counters()
|
net = psutil.net_io_counters()
|
||||||
|
|
||||||
# PM2进程状态
|
# PM2进程状态(直接调pm2二进制,不走npx)
|
||||||
pm2_procs = []
|
pm2_procs = []
|
||||||
try:
|
try:
|
||||||
|
pm2_bin = _find_pm2_bin()
|
||||||
|
cmd = [pm2_bin, "jlist"] if not pm2_bin.startswith("npx") else ["npx", "pm2", "jlist"]
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["npx", "pm2", "jlist"],
|
cmd,
|
||||||
capture_output=True, text=True, timeout=10
|
capture_output=True, text=True, timeout=5
|
||||||
)
|
)
|
||||||
import json as _json
|
import json as _json
|
||||||
procs = _json.loads(result.stdout)
|
procs = _json.loads(result.stdout)
|
||||||
@ -504,7 +535,7 @@ async def get_server_status(user: dict = Depends(get_current_user)):
|
|||||||
except Exception:
|
except Exception:
|
||||||
pm2_procs = []
|
pm2_procs = []
|
||||||
|
|
||||||
# PG数据库大小 + agg_trades条数
|
# PG数据库大小 + agg_trades条数(用估算值,快1000倍)
|
||||||
pg_info = {}
|
pg_info = {}
|
||||||
try:
|
try:
|
||||||
row = await async_fetchrow(
|
row = await async_fetchrow(
|
||||||
@ -512,10 +543,15 @@ async def get_server_status(user: dict = Depends(get_current_user)):
|
|||||||
)
|
)
|
||||||
pg_info["db_size_mb"] = round(row["db_size"] / 1024 / 1024, 1) if row else 0
|
pg_info["db_size_mb"] = round(row["db_size"] / 1024 / 1024, 1) if row else 0
|
||||||
|
|
||||||
row2 = await async_fetchrow("SELECT COUNT(*) as cnt FROM agg_trades")
|
# 用PG统计信息估算行数(毫秒级,而非COUNT(*)的秒级全表扫描)
|
||||||
pg_info["agg_trades_count"] = row2["cnt"] if row2 else 0
|
row2 = await async_fetchrow(
|
||||||
|
"SELECT SUM(n_live_tup)::bigint as cnt FROM pg_stat_user_tables WHERE relname LIKE 'agg_trades%'"
|
||||||
|
)
|
||||||
|
pg_info["agg_trades_count"] = row2["cnt"] if row2 and row2["cnt"] else 0
|
||||||
|
|
||||||
row3 = await async_fetchrow("SELECT COUNT(*) as cnt FROM rate_snapshots")
|
row3 = await async_fetchrow(
|
||||||
|
"SELECT n_live_tup::bigint as cnt FROM pg_stat_user_tables WHERE relname = 'rate_snapshots'"
|
||||||
|
)
|
||||||
pg_info["rate_snapshots_count"] = row3["cnt"] if row3 else 0
|
pg_info["rate_snapshots_count"] = row3["cnt"] if row3 else 0
|
||||||
|
|
||||||
# 各symbol最新数据时间
|
# 各symbol最新数据时间
|
||||||
@ -542,7 +578,7 @@ async def get_server_status(user: dict = Depends(get_current_user)):
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return {
|
result = {
|
||||||
"timestamp": int(time.time() * 1000),
|
"timestamp": int(time.time() * 1000),
|
||||||
"cpu": {
|
"cpu": {
|
||||||
"percent": cpu_percent,
|
"percent": cpu_percent,
|
||||||
@ -574,3 +610,6 @@ async def get_server_status(user: dict = Depends(get_current_user)):
|
|||||||
"postgres": pg_info,
|
"postgres": pg_info,
|
||||||
"backfill_running": backfill_running,
|
"backfill_running": backfill_running,
|
||||||
}
|
}
|
||||||
|
_server_cache["data"] = result
|
||||||
|
_server_cache["ts"] = now
|
||||||
|
return result
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user