🔄 卡若AI 同步 2026-02-22 14:43 | 更新:金仓、运营中枢工作台 | 排除 >20MB: 8 个

This commit is contained in:
2026-02-22 14:43:56 +08:00
parent 9136777df7
commit 275712c8b1
4 changed files with 107 additions and 1 deletions

View File

@@ -164,7 +164,13 @@ bash scripts/存客宝_lytiao_Docker部署.sh
部署后访问 `http://42.194.245.239:8090`。详见 `references/lytiao_Docker部署说明.md`
### 5. kr宝塔 网络卡/服务器卡 · 检查与处理
### 5. kr宝塔 运行堵塞 + Node 深度修复
- **运行堵塞**(负载 100%、CPU 98%):结束异常 node 进程、停 Node、修复 site.db、查日志、批量启动。
- **TAT**`./scripts/.venv_tx/bin/python scripts/腾讯云_TAT_kr宝塔_运行堵塞与Node深度修复.py`
- **宝塔终端**(推荐):上传 `scripts/kr宝塔_运行堵塞与Node深度修复_宝塔终端执行.sh``bash` 执行。
### 5b. kr宝塔 网络卡/服务器卡 · 检查与处理
- **文档**`references/kr宝塔_网络与服务器卡顿_检查与处理.md`
- **带宽使用情况近24h**:运行 `scripts/kr宝塔_腾讯云带宽与CPU近24h.py`(建议用 `scripts/.venv_tx/bin/python`,依赖 tencentcloud-sdk-python-monitor。结论出带宽最大已顶满 5M属带宽卡主因处理见文档「六、直接处理」。

View File

@@ -0,0 +1,98 @@
#!/bin/bash
# kr宝塔 运行堵塞 + Node 深度修复 - 宝塔面板「终端」执行
# 1. 诊断负载/CPU 2. 停 Node 3. 修复 site.db 4. 查日志 5. 批量启动
echo "========== kr宝塔 运行堵塞 + Node 深度修复 =========="
echo "【0】运行堵塞诊断"
uptime
echo "--- CPU TOP10 ---"
ps aux --sort=-%cpu | head -11
echo "--- 结束异常高 CPU node 进程 ---"
for pid in $(ps aux | awk '$3>80 && /node|npm|pnpm/ && !/grep/ {print $2}' 2>/dev/null); do
echo " kill $pid"; kill -9 $pid 2>/dev/null
done
sleep 2
python3 << 'PY'
import hashlib,json,os,re,sqlite3,subprocess,time,urllib.request,urllib.parse,ssl
ssl._create_default_https_context=ssl._create_unverified_context
P,K="https://127.0.0.1:9988","qcWubCdlfFjS2b2DMT1lzPFaDfmv1cBT"
def sg(): t=int(time.time()); return {"request_time":t,"request_token":hashlib.md5((str(t)+hashlib.md5(K.encode()).hexdigest()).encode()).hexdigest()}
def post(p,d=None): pl=sg(); (pl.update(d) if d else None); r=urllib.request.Request(P+p,data=urllib.parse.urlencode(pl).encode()); return json.loads(urllib.request.urlopen(r,timeout=25).read().decode())
def pids(port):
try: return {int(x) for x in re.findall(r"pid=(\d+)",subprocess.check_output("ss -tlnp 2>/dev/null | grep ':%s ' || true"%port,shell=True).decode())}
except: return set()
def ports(it):
cfg=it.get("project_config") or {}
if isinstance(cfg,str): cfg=json.loads(cfg) if cfg else {}
p=[]; [p.append(int(cfg["port"])) if cfg.get("port") else None]
p.extend(int(m) for m in re.findall(r"-p\s*(\d+)",str(cfg.get("project_script",""))))
return sorted(set(p))
PATH_FB={"玩值大屏":["/www/wwwroot/self/wanzhi/玩值大屏","/www/wwwroot/self/wanzhi/玩值"],"tongzhi":["/www/wwwroot/self/wanzhi/tongzhi","/www/wwwroot/self/wanzhi/tong"],"神射手":["/www/wwwroot/self/kr/kr-use","/www/wwwroot/self/kr/kr-users"],"AITOUFA":["/www/wwwroot/ext/tools/AITOUFA","/www/wwwroot/ext/tools/AITOL"]}
print("\n【1】停止 Node"); items=post("/project/nodejs/get_project_list").get("data")or post("/project/nodejs/get_project_list").get("list")or[]
for it in items:
n=it.get("name")
if n:
try:
for port in ports(it): [subprocess.call("kill -9 %s 2>/dev/null"%pid,shell=True) for pid in pids(port)]
pf="/www/server/nodejs/vhost/pids/%s.pid"%n
if os.path.exists(pf): open(pf,"w").write("0")
post("/project/nodejs/stop_project",{"project_name":n}); print(" 停:",n)
except: pass
time.sleep(0.4)
time.sleep(4)
print("\n【2】修复 site.db"); db="/www/server/panel/data/db/site.db"; fixed=0
if os.path.isfile(db):
c=sqlite3.connect(db); cur=c.cursor(); cur.execute("SELECT id,name,path,project_config FROM sites WHERE project_type='Node'")
for row in cur.fetchall():
sid,name,path,cfg=row[0],row[1],row[2],row[3]or"{}"
path=(path or"").strip(); cfg=json.loads(cfg) if cfg else {}
proj=cfg.get("path")or cfg.get("project_path")or path
if not proj or not os.path.isdir(proj):
for p in PATH_FB.get(name,[]):
if os.path.isdir(p): proj=p; break
if not proj or not os.path.isdir(proj): print(" 跳过",name); continue
cmd="cd %s && (pnpm start 2>/dev/null || npm run start)"%proj
old=str(cfg.get("project_script")or cfg.get("run_cmd")or"").strip()
if "cd " not in old or proj not in old:
cfg["project_script"]=cfg["run_cmd"]=cmd; cfg["path"]=proj
cur.execute("UPDATE sites SET path=?,project_config=? WHERE id=?",(proj,json.dumps(cfg,ensure_ascii=False),sid)); fixed+=1
print(" 修复:",name,"->",proj)
c.commit(); c.close()
print(" 共修复 %d 个"%fixed)
print("\n【3】Node 日志"); ld="/www/server/nodejs/vhost"
for it in items:
n=it.get("name")
if not n: continue
for lp in ["%s/log/%s.log"%(ld,n),"%s/logs/%s.log"%(ld,n)]:
if os.path.isfile(lp):
try: tail="".join(open(lp,"r",encoding="utf-8",errors="ignore").readlines()[-5:]).strip(); print("---",n,"---\n%s\n"%(tail[-600:]if tail else"(空)"))
except: pass
break
else: print(n,": 无日志\n")
print("\n【4】批量启动")
for rnd in range(3):
items=post("/project/nodejs/get_project_list").get("data")or post("/project/nodejs/get_project_list").get("list")or[]
to_start=[it for it in items if it.get("name") and not it.get("run")]
if not to_start: print(" 全部已运行"); break
print(" 第%d轮: %d 个"%(rnd+1,len(to_start)))
for it in to_start:
n=it.get("name")
if not n: continue
try:
for port in ports(it): [subprocess.call("kill -9 %s 2>/dev/null"%pid,shell=True) for pid in pids(port)]
pf="/www/server/nodejs/vhost/pids/%s.pid"%n
if os.path.exists(pf): open(pf,"w").write("0")
post("/project/nodejs/stop_project",{"project_name":n}); time.sleep(0.5)
r=post("/project/nodejs/start_project",{"project_name":n})
print(" %s: %s"%(n,"OK" if r.get("status") or "成功" in str(r.get("msg","")) else "FAIL"))
except: print(" %s: ERR"%n)
time.sleep(2)
time.sleep(10)
print("\n【5】最终状态"); items2=post("/project/nodejs/get_project_list").get("data")or post("/project/nodejs/get_project_list").get("list")or[]
run_c=sum(1 for x in items2 if x.get("run")); print(" 运行 %d/%d"%(run_c,len(items2)))
for it in items2: print(" %s: %s"%(it.get("name"),"运行中" if it.get("run") else "未启动"))
print("\n--- 修复后负载 ---"); subprocess.call("uptime",shell=True)
PY
echo ""
echo "========== 完成 =========="

View File

@@ -92,3 +92,4 @@
| 2026-02-22 13:57:34 | 🔄 卡若AI 同步 2026-02-22 13:57 | 更新:金仓、水溪整理归档、卡木、运营中枢工作台 | 排除 >20MB: 8 个 |
| 2026-02-22 14:24:16 | 🔄 卡若AI 同步 2026-02-22 14:24 | 更新:金仓、卡木、运营中枢工作台 | 排除 >20MB: 8 个 |
| 2026-02-22 14:25:58 | 🔄 卡若AI 同步 2026-02-22 14:25 | 更新:运营中枢工作台 | 排除 >20MB: 8 个 |
| 2026-02-22 14:42:04 | 🔄 卡若AI 同步 2026-02-22 14:42 | 更新:金仓、卡木、运营中枢工作台 | 排除 >20MB: 8 个 |

View File

@@ -95,3 +95,4 @@
| 2026-02-22 13:57:34 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-22 13:57 | 更新:金仓、水溪整理归档、卡木、运营中枢工作台 | 排除 >20MB: 8 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-02-22 14:24:16 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-22 14:24 | 更新:金仓、卡木、运营中枢工作台 | 排除 >20MB: 8 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-02-22 14:25:59 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-22 14:25 | 更新:运营中枢工作台 | 排除 >20MB: 8 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-02-22 14:42:04 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-22 14:42 | 更新:金仓、卡木、运营中枢工作台 | 排除 >20MB: 8 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |