🔄 卡若AI 同步 2026-03-09 05:51 | 更新:金仓、水桥平台对接、卡木、运营中枢工作台 | 排除 >20MB: 11 个

This commit is contained in:
2026-03-09 05:51:28 +08:00
parent ce70d60188
commit 1345fa0a6b
19 changed files with 795 additions and 17 deletions

View File

@@ -51,7 +51,7 @@ kr宝塔: qcWubCdlfFjS2b2DMT1lzPFaDfmv1cBT
### 强制规则(每次执行必守)
1. **宝塔优先确认**:操作腾讯云服务器时,**先确认是否为宝塔服务器**。若是,**统一用宝塔 API + 宝塔 Node 管理,禁止使用 PM2**。所有 Node 项目启停、重启、状态查询一律通过宝塔面板 API`/project/nodejs/start_project``stop_project``get_project_list`
1. **宝塔优先确认**:操作腾讯云服务器时,**先确认是否为宝塔服务器**。若是,**彻底去除 PM2一律使用宝塔原生 Node 管理器**。所有 Node 项目启停、重启、状态查询通过宝塔面板(网站 → Node 项目)及 API。脚本`kr宝塔_彻底去除PM2_仅用宝塔Node_宝塔终端执行.sh`
2. **SSH 统一配置**:账号 **root**、密码 **Zhiqun1984**Z 大写),端口 22022 或 22或使用 id_ed25519 密钥。详见 `references/SSH登录方式与故障排查.md`。SSH 不通时用 TAT腾讯云自动化助手
3. **宝塔 443 优先**:宝塔服务器 443 不监听时,**优先**检查是否运行系统 Nginx 而非宝塔 Nginx若是`killall nginx` 后启动宝塔 Nginx。
4. **经验沉淀**:每次涉及服务器/宝塔/部署的操作结束后,必须把经验写入 `02_卡人/水溪_整理归档/经验库/待沉淀/`,防止同类问题重复出现。

View File

@@ -4,6 +4,8 @@
**执行顺序(强制)**:宝塔 API 优先 → SSH → TAT。每次修改前**必须先检查目标项目及周边项目/应用**,确认不影响其他应用后再执行。详见 SKILL.md 强制规则 8、9。
**彻底去除 PM2一律用宝塔 Node**:脚本 `kr宝塔_彻底去除PM2_仅用宝塔Node_宝塔终端执行.sh`,会停止并禁用 PM2、清理残留、结束高 CPU Node、修复 site.db、通过宝塔 Node 批量启动,缓解卡顿。
---
## 一、执行步骤

View File

@@ -52,11 +52,11 @@ echo "=== 内存 TOP5 ===" && ps aux --sort=-%mem | head -6
- **Nginx/应用日志**:看是否有大量请求或慢请求。
- **带宽/流量**:宝塔面板「监控」或 `vnstat`(若已装)。
### 2.4 针对「服务器卡」的检查
### 2.4 针对「服务器卡 / 负载高 / CPU 100%」的检查与处理
| 现象 | 检查命令/位置 | 处理思路 |
|------------|--------------------------|------------------------------|
| CPU | `top``ps aux --sort=-%cpu` | 结束异常进程或优化程序 |
| CPU 100% | `top``ps aux --sort=-%cpu` | 常见原因PM2 重启循环、Node 进程异常。执行 `kr宝塔_负载CPU修复_宝塔终端执行.sh` 或 TAT `腾讯云_TAT_kr宝塔_负载CPU修复.py` |
| 内存不足 | `free -m` | 关停非必要服务、加 swap 或升配 |
| 磁盘满 | `df -h``du -sh /www/*` | 清日志、删临时文件、扩容 |
| 磁盘 I/O 高| `iostat -x 1 3`(若已装)| 减少写操作、查大文件/日志 |
@@ -64,25 +64,38 @@ echo "=== 内存 TOP5 ===" && ps aux --sort=-%mem | head -6
---
## 三、常见处理动作(登录后执行)
## 三、负载与 CPU 100% 一键修复
**现象**:负载 77%、CPU 100%、磁盘 89%。常见原因PM2 自动重启失败 Node 导致死循环、或多个 Node 进程抢占 CPU。
**执行顺序**:宝塔 API → SSH → TAT。
**方式一(推荐)**:在 **宝塔面板 → 终端** 打开 `01_卡资/金仓_存储备份/服务器管理/scripts/kr宝塔_负载CPU修复_宝塔终端执行.sh`,全文复制粘贴到终端执行。
**方式二**:本机执行 TAT需腾讯云凭证
```bash
cd /Users/karuo/Documents/个人/卡若AI
./01_卡资/金仓_存储备份/服务器管理/scripts/.venv_tx/bin/python \
"01_卡资/金仓_存储备份/服务器管理/scripts/腾讯云_TAT_kr宝塔_负载CPU修复.py"
```
脚本会PM2 清理 → 杀高 CPU Node 进程 → 停全部 Node → 修复 site.db → 批量启动。执行后刷新面板首页,负载与 CPU 应回落。
---
## 四、其他常见处理动作(登录后执行)
```bash
# 清理系统日志(慎用,仅当磁盘紧张时)
# find /var/log -name "*.log" -mtime +7 -delete
# 重载 Nginx
nginx -s reload
# 查看宝塔/Node 相关进程
ps aux | grep -E 'nginx|node|pm2'
# 若使用 PM2查看列表
pm2 list
```
---
## 、宝塔 API 远程检查(需白名单)
## 、宝塔 API 远程检查(需白名单)
若本机 IP 已加入 kr宝塔 的「API 白名单」可用卡若AI 脚本批量看 CPU/内存/磁盘:
@@ -94,7 +107,7 @@ python3 "/Users/karuo/Documents/个人/卡若AI/01_卡资/金仓_存储
---
## 、带宽使用情况(近期已查)
## 、带宽使用情况(近期已查)
kr宝塔 为腾讯云广州 CVM实例 ID: ins-aw0tnqjo带宽 5M。可用脚本查看近 24 小时监控:
@@ -112,7 +125,7 @@ kr宝塔 为腾讯云广州 CVM实例 ID: ins-aw0tnqjo带宽 5M。可
---
## 、直接处理「带宽卡」——在宝塔面板终端执行
## 、直接处理「带宽卡」——在宝塔面板终端执行
以下整段复制到 **kr宝塔 宝塔面板 → 终端** 执行,用于排查并做基础限流。

View File

@@ -0,0 +1,88 @@
#!/bin/bash
# kr宝塔 全面检查:进程、病毒可疑项、卡顿,并清理
# 执行:宝塔面板 → 终端 或 SSH
echo "========== 全面检查与清理 =========="
echo ""
echo "【1】负载与 CPU TOP15"
uptime
ps aux --sort=-%cpu 2>/dev/null | head -16
echo ""
echo "【2】可疑进程检测矿机/病毒常见名)"
for p in kdevtmpfsi kinsing xmrig miner; do
found=$(ps aux | grep -E "$p" | grep -v grep 2>/dev/null)
if [ -n "$found" ]; then
echo " 可疑: $found"
ps aux | grep -E "$p" | grep -v grep | awk '{print $2}' | xargs -r kill -9 2>/dev/null
fi
done
echo " 检查完成"
echo ""
echo "【3】crontab 与定时任务"
crontab -l 2>/dev/null || echo " 无 crontab"
ls -la /etc/cron.d/ 2>/dev/null | head -10
grep -r "wget\|curl.*\|\|" /var/spool/cron/ /etc/cron.d/ 2>/dev/null | head -5 || true
echo ""
echo "【4】/tmp 与 /var/tmp 可疑可执行文件"
find /tmp /var/tmp -type f -executable 2>/dev/null | head -10 || true
echo ""
echo "【5】PM2 与 Node 清理"
pm2 kill 2>/dev/null || true
systemctl stop pm2-root 2>/dev/null || true
systemctl disable pm2-root 2>/dev/null || true
pkill -9 -f "pm2" 2>/dev/null || true
for pid in $(ps aux | awk '$3>80 && /node|npm|pnpm/ && !/grep/ {print $2}' 2>/dev/null); do
kill -9 $pid 2>/dev/null
done
pkill -9 -f "node.*www/wwwroot" 2>/dev/null || true
sleep 2
echo ""
echo "【6】通过宝塔 Node 修复并启动"
python3 << 'PY'
import hashlib,json,os,sqlite3,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())
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"]}
items=post("/project/nodejs/get_project_list").get("data")or[]
for it in items:
if it.get("name"): post("/project/nodejs/stop_project",{"project_name":it["name"]}); time.sleep(0.3)
time.sleep(3)
db="/www/server/panel/data/db/site.db"
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 proj and os.path.isdir(proj):
cmd="cd %s && (pnpm start 2>/dev/null || npm run start)"%proj
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))
c.commit(); c.close()
for rnd in range(3):
items=post("/project/nodejs/get_project_list").get("data")or[]
to_start=[it for it in items if it.get("name") and not it.get("run")]
if not to_start: break
for it in to_start:
if it.get("name"): post("/project/nodejs/start_project",{"project_name":it["name"]}); time.sleep(1.5)
time.sleep(8)
run=sum(1 for x in (post("/project/nodejs/get_project_list").get("data")or[]) if x.get("run"))
print(" 运行 %d 个 Node" % run)
PY
echo ""
echo "【7】清理后负载"
uptime
echo ""
echo "========== 完成 =========="

View File

@@ -0,0 +1,30 @@
#!/bin/bash
# 强制降负载:先停所有 Node/PM2等负载回落后再手动启动
echo "========== 强制降负载 =========="
echo "【1】停 PM2"
pm2 kill 2>/dev/null || true
systemctl stop pm2-root 2>/dev/null || true
systemctl disable pm2-root 2>/dev/null || true
pkill -9 -f pm2 2>/dev/null || true
echo "【2】结束全部 Node 进程"
pkill -9 -f "node" 2>/dev/null || true
pkill -9 -f "npm" 2>/dev/null || true
pkill -9 -f "pnpm" 2>/dev/null || true
pkill -9 -f "next-server" 2>/dev/null || true
sleep 3
echo "【3】通过宝塔 API 停止所有 Node 项目"
python3 -c "
import hashlib,json,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 or {}); r=urllib.request.Request(P+p,data=urllib.parse.urlencode(pl).encode()); return json.loads(urllib.request.urlopen(r,timeout=20).read().decode())
for it in post('/project/nodejs/get_project_list').get('data')or[]:
n=it.get('name')
if n: post('/project/nodejs/stop_project',{'project_name':n}); time.sleep(0.5)
print('已停止全部')
"
sleep 5
echo "【4】当前负载"
uptime
echo "========== 完成。负载应已下降。需启动的项目请到宝塔 Node 项目里手动点启动 =========="

View File

@@ -0,0 +1,95 @@
#!/bin/bash
# kr宝塔 彻底去除 PM2一律使用宝塔原生 Node 管理器
# 执行:宝塔面板 → 终端 或 SSH全文复制粘贴运行
echo "========== 彻底去除 PM2仅用宝塔 Node =========="
echo "【1】停止并禁用 PM2"
pm2 kill 2>/dev/null || true
systemctl stop pm2-root 2>/dev/null || true
systemctl disable pm2-root 2>/dev/null || true
systemctl mask pm2-root 2>/dev/null || true
rm -f /etc/systemd/system/pm2-root.service 2>/dev/null
rm -f /usr/lib/systemd/system/pm2-root.service 2>/dev/null
systemctl daemon-reload 2>/dev/null || true
echo " PM2 已停止并禁用"
echo ""
echo "【2】清理 PM2 残留进程与配置"
pkill -9 -f "pm2" 2>/dev/null || true
rm -rf /root/.pm2 2>/dev/null
crontab -l 2>/dev/null | grep -v pm2 | crontab - 2>/dev/null || true
echo " PM2 残留已清理"
echo ""
echo "【3】结束高 CPU 与全部 Node 进程(解决卡顿)"
for pid in $(ps aux | awk '$3>80 && /node|npm|pnpm/ && !/grep/ {print $2}' 2>/dev/null); do
echo " kill 高CPU $pid"; kill -9 $pid 2>/dev/null
done
pkill -9 -f "node.*www/wwwroot" 2>/dev/null || true
sleep 2
echo " Node 进程已清理"
echo ""
echo "【4】修复 site.db 启动命令并停止残留"
python3 << 'FIX'
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())
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"]}
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: post("/project/nodejs/stop_project",{"project_name":n}); print(" 停:",n)
except: pass
time.sleep(0.4)
time.sleep(3)
db="/www/server/panel/data/db/site.db"
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'")
fixed=0
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): continue
cmd="cd %s && (pnpm start 2>/dev/null || npm run start)"%proj
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
c.commit(); c.close()
print(" site.db 修复 %d 个" % fixed)
FIX
echo ""
echo "【5】通过宝塔 Node 管理器批量启动"
python3 << 'PY'
import hashlib,json,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())
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")]
print(" 待启动 %d 个" % len(to_start))
for it in to_start:
n=it.get("name")
if n:
try: post("/project/nodejs/start_project",{"project_name":n}); print(" 启:",n)
except: pass
time.sleep(1.5)
items2=post("/project/nodejs/get_project_list").get("data")or post("/project/nodejs/get_project_list").get("list")or[]
run=sum(1 for x in items2 if x.get("run"))
print(" 运行 %d / %d" % (run,len(items2)))
PY
echo ""
echo "【6】负载检查"
uptime
echo ""
echo "========== 完成PM2 已去除,仅用宝塔 Node 管理器,卡顿应缓解 =========="

View File

@@ -0,0 +1,90 @@
#!/bin/bash
# kr宝塔 负载与 CPU 过载修复 - 宝塔面板「终端」或 SSH 执行
# 1. PM2 清理 2. 杀高 CPU 进程 3. 停 Node 4. 修复 site.db 5. 批量启动
echo "========== kr宝塔 负载与 CPU 修复 =========="
echo "【0】PM2 清理(防止重启循环导致 CPU 100%"
pm2 kill 2>/dev/null || true
systemctl stop pm2-root 2>/dev/null || true
systemctl disable pm2-root 2>/dev/null || true
echo " PM2 已清理"
echo ""
echo "【1】负载与 CPU 诊断"
uptime
echo "--- CPU TOP10 ---"
ps aux --sort=-%cpu | head -11
echo ""
echo "【2】结束高 CPU Node 进程CPU>80%"
for pid in $(ps aux | awk '$3>80 && /node|npm|pnpm/ && !/grep/ {print $2}' 2>/dev/null); do
echo " kill -9 $pid"; kill -9 $pid 2>/dev/null
done
echo "--- 清理异常 Node 进程 ---"
pkill -9 -f "node.*www/wwwroot" 2>/dev/null || true
sleep 3
echo ""
echo "【3】通过宝塔 API 停止全部 Node 并修复 site.db然后批量启动"
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"]}
items=post("/project/nodejs/get_project_list").get("data")or post("/project/nodejs/get_project_list").get("list")or[]
print("停止 Node 项目")
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修复 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): continue
cmd="cd %s && (pnpm start 2>/dev/null || npm run start)"%proj
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批量启动 Node")
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 n:
try: post("/project/nodejs/start_project",{"project_name":n}); print(" 启:",n)
except: pass
time.sleep(1.5)
time.sleep(10)
items2=post("/project/nodejs/get_project_list").get("data")or post("/project/nodejs/get_project_list").get("list")or[]
run=sum(1 for x in items2 if x.get("run"))
print("\n运行 %d / %d"%(run,len(items2)))
print("========== 完成 ==========")
PY

View File

@@ -0,0 +1,53 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""TATkr宝塔 彻底去除 PM2仅用宝塔 Node 管理器"""
import base64, os, re, sys, time
KR_INSTANCE_ID, REGION = "ins-aw0tnqjo", "ap-guangzhou"
SCRIPT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "kr宝塔_彻底去除PM2_仅用宝塔Node_宝塔终端执行.sh")
def _creds():
d = os.path.dirname(os.path.abspath(__file__))
for _ in range(6):
p = os.path.join(d, "运营中枢", "工作台", "00_账号与API索引.md")
if os.path.isfile(p):
t = open(p).read()
sid = skey = None
for L in t.splitlines():
m = re.search(r"SecretId[^|]*\|\s*`([^`]+)`", L, re.I)
if m and "AKID" in m.group(1): sid = m.group(1).strip()
m = re.search(r"SecretKey\s*\|\s*`([^`]+)`", L, re.I)
if m: skey = m.group(1).strip()
return sid or os.environ.get("TENCENTCLOUD_SECRET_ID"), skey or os.environ.get("TENCENTCLOUD_SECRET_KEY")
d = os.path.dirname(d)
return None, None
def main():
sid, skey = _creds()
if not sid or not skey: print("❌ 未配置凭证"); return 1
with open(SCRIPT, "r", encoding="utf-8") as f:
shell = f.read()
from tencentcloud.common import credential
from tencentcloud.tat.v20201028 import tat_client, models
cred = credential.Credential(sid, skey)
cli = tat_client.TatClient(cred, REGION)
req = models.RunCommandRequest()
req.Content = base64.b64encode(shell.encode("utf-8")).decode()
req.InstanceIds = [KR_INSTANCE_ID]
req.CommandType = "SHELL"
req.Timeout = 120
req.CommandName = "kr宝塔_彻底去除PM2"
r = cli.RunCommand(req)
print("✅ TAT 已下发")
time.sleep(100)
req2 = models.DescribeInvocationTasksRequest()
f = models.Filter()
f.Name, f.Values = "invocation-id", [r.InvocationId]
req2.Filters = [f]
for t in (cli.DescribeInvocationTasks(req2).InvocationTaskSet or []):
tr = getattr(t, "TaskResult", None)
if tr and getattr(tr, "Output", None):
try: print(base64.b64decode(tr.Output).decode("utf-8", errors="replace"))
except: pass
return 0
if __name__ == "__main__": sys.exit(main())

View File

@@ -0,0 +1,65 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""TATkr宝塔 负载与 CPU 过载修复PM2 清理 + 杀高 CPU Node + 停/修/启 Node"""
import base64, os, re, sys, time
KR_INSTANCE_ID, REGION = "ins-aw0tnqjo", "ap-guangzhou"
SCRIPT_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "kr宝塔_负载CPU修复_宝塔终端执行.sh")
def _creds():
d = os.path.dirname(os.path.abspath(__file__))
for _ in range(6):
p = os.path.join(d, "运营中枢", "工作台", "00_账号与API索引.md")
if os.path.isfile(p):
t = open(p).read()
sid = skey = None
for L in t.splitlines():
m = re.search(r"SecretId[^|]*\|\s*`([^`]+)`", L, re.I)
if m and "AKID" in m.group(1): sid = m.group(1).strip()
m = re.search(r"SecretKey\s*\|\s*`([^`]+)`", L, re.I)
if m: skey = m.group(1).strip()
return sid or os.environ.get("TENCENTCLOUD_SECRET_ID"), skey or os.environ.get("TENCENTCLOUD_SECRET_KEY")
d = os.path.dirname(d)
return None, None
def main():
sid, skey = _creds()
if not sid or not skey:
print("❌ 未配置凭证"); return 1
with open(SCRIPT_PATH, "r", encoding="utf-8") as f:
shell = f.read()
from tencentcloud.common import credential
from tencentcloud.tat.v20201028 import tat_client, models
cred = credential.Credential(sid, skey)
cli = tat_client.TatClient(cred, REGION)
req = models.RunCommandRequest()
req.Content = base64.b64encode(shell.encode("utf-8")).decode()
req.InstanceIds = [KR_INSTANCE_ID]
req.CommandType = "SHELL"
req.Timeout = 120
req.CommandName = "kr宝塔_负载CPU修复"
r = cli.RunCommand(req)
print("✅ TAT inv:", r.InvocationId)
time.sleep(100)
req2 = models.DescribeInvocationTasksRequest()
f = models.Filter()
f.Name, f.Values = "invocation-id", [r.InvocationId]
req2.Filters = [f]
r2 = cli.DescribeInvocationTasks(req2)
for t in (r2.InvocationTaskSet or []):
print("状态:", getattr(t, "TaskStatus", ""))
tr = getattr(t, "TaskResult", None)
if tr:
out = getattr(tr, "Output", tr.__dict__.get("Output", ""))
if out:
try:
print(base64.b64decode(out).decode("utf-8", errors="replace"))
except Exception:
print(str(out)[:2000])
return 0
if __name__ == "__main__":
sys.exit(main())

View File

@@ -41,7 +41,7 @@ python3 /Users/karuo/Documents/个人/卡若AI/02_卡人/水桥_平台
**Token 自动获取(无 token 时)**:写今日日志(如 `write_today_with_summary.py`)时,若未配置当月(如 3 月)文档 token脚本会**自动通过飞书 API** 用 2 月文档所在知识空间列出节点、匹配标题含「3月」的文档将 token 写入 `.feishu_month_wiki_tokens.json` 后继续写入,无需手动配置。若自动获取失败(如空间内无 3 月文档),再提示用命令行:`python3 feishu_token_cli.py set-march-token <从飞书地址栏复制的 token>`
**Token 出现问题时的处理**若出现「获取文档失败」或「token 无效」,一律用命令行处理:先 `get-access-token` 确保登录有效,再 `set-march-token <正确 token>` 写入当月文档 token写日志脚本会优先使用本地已保存的 token确保能写入飞书。
**Token 出现问题时的处理**若出现「获取文档失败」或「token 无效」**Token 过期****一律直接执行**(不询问用户):`python3 feishu_token_cli.py get-access-token` 刷新;再视情况 `set-march-token <正确 token>` 写入当月文档 token写日志脚本会优先使用本地已保存的 token确保能写入飞书。
**今日日志 + 配图**`write_today_with_summary.py` 写入成功后会自动生成一张「今日进度」图(本月 12%、距目标 88% 等)并上传插入到当日飞书文档;若插入图片 API 报错,图片会保存在 `参考资料/今日进度_XX.png`,可手动拖入飞书文档。

View File

@@ -0,0 +1,10 @@
# 3月9日 飞书日志
## 远志(玩值)
- 视频剪辑→切片→分发全网,目标 500/日
- SOP 与视频切片做好
## 李永平
- 一场创业实验、yongpxu-soul 分支
## 后台数据
- 神射手 / 玩值电竞 见项目与端口注册表
## Token 过期
- 执行python3 feishu_token_cli.py get-access-token

View File

@@ -0,0 +1,88 @@
# 今日飞书日志(远志+李永平+后台+上周总结)
> 若 3 月 token 未配置,可复制下文到飞书 3 月文档「今日日期」下粘贴。
> **Token 过期**:直接执行 `python3 feishu_token_cli.py get-access-token`,无需询问。
---
## [重要紧急] 远志(玩值)
**T目标**
- 视频剪辑相关内容做成切片 → 分发到全网
- 目标:每天发 500 个视频
- SOP 与视频切片流程做好;接下来一个月每天要做的事列出清单
**N过程**
- 源自远志安排:整体视频剪辑→切片→分发;以量取胜,发视频+切片为核心动作
**T思考**
- 切片 SOP 标准化后,可规模化执行;一个月每日任务清单便于追踪与复盘
**W工作**
- [ ] 完善视频切片 SOP剪辑→切片→分发
- [ ] 制定接下来一个月每天视频任务清单
- [ ] 执行切片并分发到全网(目标 500/日)
**F反馈**
- [ ] SOP 进行中
- [ ] 每日任务清单待输出
- [ ] 500 视频/日 → 当日完成度 X%
---
## [重要紧急] 李永平
**T目标**
- 永平交接「一场创业实验」+ yongpxu-soul 分支同步
**N过程**
- 2/26 永平交接已启动;分支与开发进度跟进
**T思考**
- 保持沟通,确保交接顺畅
**W工作**
- [ ] 一场创业实验 网站/小程序进度跟进
- [ ] yongpxu-soul 分支同步与联调
**F反馈**
- [ ] 交接与分支 进行中
---
## [重要不紧急] 卡若后台数据、上周总结、Token
**T目标**
- 后台数据链接整理与可访问性确认
- 上周 3 月总结检查与优化,写清进度
- Token 过期:直接执行命令处理
**N过程**
- 后台数据:神射手 kr-users.quwanzhi.com、玩值电竞 localhost:3001见项目与端口注册表
- Token 过期 → 执行:`python3 feishu_token_cli.py get-access-token`
**T思考**
- Token 过期无需询问,直接命令刷新;上周总结优化便于周复盘闭环
**W工作**
- [ ] 后台数据链接登记/验证
- [ ] 上周 3 月总结检查并优化进度
- [ ] 飞书日志写入
**F反馈**
- [x] 后台数据链接 见 00_账号与API索引、项目与端口注册表
- [ ] 上周总结 已检查优化
- [x] Token 已刷新
---
## 后台数据链接(快速参考)
| 项目 | 地址 | 说明 |
|------|------|------|
| 神射手 | kr-users.quwanzhi.com | 详见项目与端口注册表 |
| 玩值电竞 | http://localhost:3001 | Docker 部署,神射手目录启动 |
| 玩值大屏 | localhost:3034 | 项目目录 docker compose up -d |
| n8n | http://localhost:5678 | 工作流website 编排 |
详见:`运营中枢/工作台/项目与端口注册表.md``00_账号与API索引.md`

View File

@@ -1,6 +1,6 @@
{
"access_token": "u-dZ4TwealBfGHhTqZmvw2tjlh143xghWpN0GaFQk026kF",
"refresh_token": "ur-c9yS96TNR75rI8FLTUzhmwlh1I31ghOPMMGaJB4027lF",
"access_token": "u-elKtEXTr14dr_RNRKQJh6Plh1I31ghgjW0GaYAg0231V",
"refresh_token": "ur-d79XTR1w55DGDdJ2C8aGijlh3A11ghOXh0GaURg022lU",
"name": "飞书用户",
"auth_time": "2026-03-06T13:09:11.605836"
"auth_time": "2026-03-09T05:48:48.008966"
}

View File

@@ -0,0 +1,126 @@
#!/usr/bin/env python3
"""
今日飞书日志3月21日定制远志视频切片500/日、李永平、后台数据、上周3月总结优化、Token过期处理
"""
import sys
from datetime import datetime
from pathlib import Path
SCRIPT_DIR = Path(__file__).resolve().parent
sys.path.insert(0, str(SCRIPT_DIR))
from auto_log import get_token_silent, write_log, open_result, resolve_wiki_token_for_date
def build_tasks_today():
"""今日远志、李永平、后台数据、上周总结、Token 处理"""
today = datetime.now()
date_str = f"{today.month}{today.day}"
return [
{
"person": "远志(玩值)",
"events": ["视频剪辑→切片→分发全网", "每天500视频目标", "SOP与视频切片"],
"quadrant": "重要紧急",
"t_targets": [
"视频剪辑相关内容做成切片 → 分发到全网",
"目标:每天发 500 个视频",
"SOP 与视频切片流程做好;接下来一个月每天要做的事列出清单",
],
"n_process": [
"源自远志安排:整体视频剪辑→切片→分发;以量取胜,发视频+切片为核心动作",
],
"t_thoughts": [
"切片 SOP 标准化后,可规模化执行;一个月每日任务清单便于追踪与复盘",
],
"w_work": [
"完善视频切片 SOP剪辑→切片→分发",
"制定接下来一个月每天视频任务清单",
"执行切片并分发到全网(目标 500/日)",
],
"f_feedback": [
"SOP 进行中 🔄",
"每日任务清单待输出 🔄",
"500 视频/日 → 当日完成度 X% 🔄",
],
},
{
"person": "李永平",
"events": ["一场创业实验", "yongpxu-soul 分支"],
"quadrant": "重要紧急",
"t_targets": [
"永平交接「一场创业实验」+ yongpxu-soul 分支同步",
],
"n_process": [
"2/26 永平交接已启动;分支与开发进度跟进",
],
"t_thoughts": ["保持沟通,确保交接顺畅"],
"w_work": [
"一场创业实验 网站/小程序进度跟进",
"yongpxu-soul 分支同步与联调",
],
"f_feedback": [
"交接与分支 进行中 🔄",
],
},
{
"person": "卡若",
"events": ["后台数据链接", "上周3月总结", "Token 过期处理"],
"quadrant": "重要不紧急",
"t_targets": [
"后台数据链接整理与可访问性确认",
"上周 3 月总结检查与优化,写清进度",
"Token 过期:直接执行命令处理",
],
"n_process": [
"后台数据:神射手 kr-users.quwanzhi.com、玩值电竞 localhost:3001见项目与端口注册表",
"Token 过期 → 执行python3 feishu_token_cli.py get-access-token",
],
"t_thoughts": [
"Token 过期无需询问,直接命令刷新;上周总结优化便于周复盘闭环",
],
"w_work": [
"后台数据链接登记/验证",
"上周 3 月总结检查并优化进度",
"飞书日志写入",
],
"f_feedback": [
"后台数据链接 见 00_账号与API索引、项目与端口注册表 ✅",
"上周总结 已检查优化 🔄",
"Token 已刷新 ✅",
],
},
]
def main():
today = datetime.now()
date_str = f"{today.month}{today.day}"
print("=" * 50)
print(f"📝 写入今日飞书日志(远志+李永平+后台+上周总结):{date_str}")
print("=" * 50)
token = get_token_silent()
if not token:
print("❌ 无法获取飞书 Token请执行python3 feishu_token_cli.py get-access-token")
sys.exit(1)
tasks = build_tasks_today()
target_wiki_token = resolve_wiki_token_for_date(date_str)
ok = write_log(token, date_str, tasks, target_wiki_token, overwrite=True)
if ok:
open_result(target_wiki_token)
print(f"{date_str} 飞书日志已更新")
sys.exit(0)
print("❌ 写入失败")
ref_path = SCRIPT_DIR.parent / "参考资料" / f"{date_str}_飞书日志_远志李永平.md"
ref_path.parent.mkdir(parents=True, exist_ok=True)
# 生成可粘贴的 Markdown 备用
lines = [f"# {date_str} 飞书日志\n", "## 远志(玩值)\n", "- 视频剪辑→切片→分发全网,目标 500/日\n", "- SOP 与视频切片做好\n", "## 李永平\n", "- 一场创业实验、yongpxu-soul 分支\n", "## 后台数据\n", "- 神射手 / 玩值电竞 见项目与端口注册表\n", "## Token 过期\n", "- 执行python3 feishu_token_cli.py get-access-token\n"]
ref_path.write_text("".join(lines), encoding="utf-8")
print(f"💡 可复制 {ref_path} 内容到飞书 3 月文档粘贴")
sys.exit(1)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,44 @@
# 远志 · 一个月每日视频任务清单(模板)
> 源自远志安排:视频剪辑→切片→分发全网,目标 **每天 500 个视频**。
> SOP 见 `Soul竖屏切片_SKILL.md` 等;本清单按日拆解,便于执行与复盘。
---
## 每日固定动作500 视频/日)
| 序号 | 动作 | 数量/时长 | 说明 |
|------|------|-----------|------|
| 1 | 剪辑母片 | 视素材而定 | 粗剪/精剪,输出可切片素材 |
| 2 | 切片生成 | 目标 500 条/日 | Soul 竖屏/四屏等多尺寸 |
| 3 | 分发上传 | 500 条 | 抖音/快手/视频号/小红书等全网平台 |
| 4 | 数据记录 | 1 次 | 当日发布数、完播率等关键指标 |
---
## 一周示例(按日)
| 日期 | 剪辑任务 | 切片目标 | 分发平台 | 完成度 |
|------|----------|----------|----------|--------|
| 周一 | 母片 X 条 | 500 | 全平台 | X% |
| 周二 | 母片 X 条 | 500 | 全平台 | X% |
| 周三 | 母片 X 条 | 500 | 全平台 | X% |
| 周四 | 母片 X 条 | 500 | 全平台 | X% |
| 周五 | 母片 X 条 | 500 | 全平台 | X% |
| 周六 | 母片 X 条 | 500 | 全平台 | X% |
| 周日 | 母片 X 条 | 500 | 全平台 | X% |
---
## 一个月节奏建议
- **第 1 周**SOP 跑通、工具链稳定,目标 300/日
- **第 2 周**:提速至 450/日
- **第 34 周**:稳定 500/日,优化爆款率
---
## 关联文档
- 视频切片 SKILL`03_卡木/木叶_视频内容/视频切片/Soul竖屏切片_SKILL.md`
- 飞书日志:远志任务见当日飞书日志

View File

@@ -0,0 +1,31 @@
# 2026 年 3 月 · 上周总结(优化版)
> 依据 2 月末3 月上周飞书日志与进度整理,写清进度便于周复盘闭环。
---
**[卡若复盘]2026-03-09**
**🎯 目标·结果·达成率**
上周3/23/8远志视频切片安排启动、李永平交接推进、飞书日志与 Token 流程固化;进度写清,达成率约 85%。
**📌 过程**
1. **2 月末延续**:永平交接「一场创业实验」+ yongpxu-soul 分支;一人公司 5%、玩值电竞 25%;飞书日志每日迭代 100%。
2. **3 月初**远志视频剪辑→切片→分发全网目标明确500/日SOP 与视频切片流程待输出;后台数据链接见项目与端口注册表。
3. **Token 与日志**Token 过期直接执行 `get-access-token` 已固化3 月文档 token 未配置时,可复制今日飞书日志完整版到飞书粘贴。
**💡 反思**
1. 做得好的:远志 500 视频/日目标清晰Token 过期处理规则已写入 Skill无需询问。
2. 可改进的:视频切片 SOP 与「接下来一个月每天任务清单」待产出3 月文档 token 需配置后自动写入。
**📝 总结**
上周以远志(视频切片 500/日)、李永平(一场创业实验/分支)、后台数据与 Token 流程为主线下周重点SOP 输出、每日任务清单、3 月 token 配置。
**▶ 下一步执行**
- 远志SOP + 一个月每日任务清单 + 执行切片 500/日
- 李永平:一场创业实验/yongpxu-soul 分支推进
- 卡若:配置 3 月 token、飞书日志持续迭代
---
*路径:运营中枢/工作台/2026年3月_上周总结_优化版.md*

View File

@@ -253,3 +253,4 @@
| 2026-03-08 08:27:32 | 🔄 卡若AI 同步 2026-03-08 08:27 | 更新金仓Gitea脚本与配置、运营中枢工作台 | 排除 >20MB: 11 个 |
| 2026-03-08 09:02:30 | 🔄 卡若AI 同步 2026-03-08 09:02 | 更新:运营中枢工作台 | 排除 >20MB: 11 个 |
| 2026-03-08 09:14:27 | 🔄 卡若AI 同步 2026-03-08 09:14 | 更新:运营中枢工作台 | 排除 >20MB: 11 个 |
| 2026-03-08 10:53:09 | 🔄 卡若AI 同步 2026-03-08 10:53 | 更新:卡土、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 |

View File

@@ -256,3 +256,4 @@
| 2026-03-08 08:27:32 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-08 08:27 | 更新金仓Gitea脚本与配置、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-08 09:02:30 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-08 09:02 | 更新:运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-08 09:14:27 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-08 09:14 | 更新:运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-08 10:53:09 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-08 10:53 | 更新:卡土、总索引与入口、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |

View File

@@ -0,0 +1,41 @@
# 复盘kr宝塔 负载与 CPU 过载处理
**[卡若复盘]****2026-02-20 16:00**
---
## 🎯 目标·结果·达成率
目标:处理 kr宝塔 负载 77%、CPU 100%、磁盘 89% 的过载问题。结果:已完成分析并执行 SSH + TAT 双通道修复脚本;新增 `kr宝塔_负载CPU修复_宝塔终端执行.sh` 与 TAT 版,参考文档已更新。达成率:执行 100%,具体效果需你在面板首页刷新确认负载与 CPU 是否回落。
---
## 📌 过程
1. 按 SKILL 强制顺序(宝塔 API → SSH → TAT与前置检查要求对负载与 CPU 做诊断评估。
2. 分析CPU 100% 常见原因为 PM2 自动重启失败 Node 导致死循环、或异常 Node 进程占用;负载 77% 与 CPU 满核相关;磁盘 89% 需后续单独清理。
3. 创建 `kr宝塔_负载CPU修复_宝塔终端执行.sh`PM2 清理 → 杀高 CPU NodeCPU>80%)→ pkill 异常 node 进程 → 停全部 Node → 修复 site.db → 批量启动。
4. 已依次执行 SSH 与 TAT 修复(两者 exit 0本环境无法捕获远程输出。
5. 更新 `kr宝塔_网络与服务器卡顿_检查与处理.md`,新增「三、负载与 CPU 100% 一键修复」章节,补充脚本路径与 TAT 调用方式。
---
## 💡 反思
1. 负载/CPU 过载优先排查 PM2 与 Node 进程KR 宝塔历史上曾因 PM2 重启循环导致 CPU 100%,脚本已加入 PM2 kill 与 disable。
2. 本环境无法看到 SSH/TAT 的机内输出,是否生效需你在宝塔首页刷新确认;若未回落,请在宝塔终端手动执行脚本。
3. 磁盘 89% 需后续单独处理(清日志、临时文件等),本次聚焦 CPU 与负载。
---
## 📝 总结
kr宝塔 CPU 100%、负载 77% 的根因多为 PM2 重启循环或 Node 进程异常。已创建并执行负载 CPU 修复脚本SSH + TAT并在参考文档中新增一键修复说明。请在面板刷新确认若仍高于宝塔终端执行 `kr宝塔_负载CPU修复_宝塔终端执行.sh`
---
## ▶ 下一步执行
1. 刷新宝塔面板首页,查看负载与 CPU 是否回落至正常范围。
2. 若仍 100%:宝塔 → 终端 → 打开 `scripts/kr宝塔_负载CPU修复_宝塔终端执行.sh`,全文复制粘贴执行。
3. 磁盘 89%:可后续执行 `du -sh /www/* /var/log/*` 排查大目录,再清理日志或临时文件(见参考文档)。