Files
ykxmz/_build/check_lightsail.py
T
xmz7891 db669e2f40 修监测单元查错地址(改监听后它开始误报网站挂了)
把中转改成只监听 127.0.0.1(公网走 nginx)之后,监测单元还在查
http://13.54.30.196:13245/v1/health —— 那个端口已经不对公网开了,
于是它连续报"公网异常",fails 涨到 2。

**差一点就是无限重启循环**:再失败一次它会启动紧急预案,
而预案的动作是"重启中转服务",重启完再查还是 000,再救……

这是改监听地址时没想到的连带影响。教训写在这里:
**改一个服务的暴露方式时,必须把所有"探测它"的地方一起看一遍。**

== 改法 ==

监测地址改成"用户实际怎么访问"为准,域名优先、IP 兜底:

    PUBLIC_URL=http://yk.xxmxxs.top          域名(经 Cloudflare + nginx)
    FALLBACK_URL=http://13.54.30.196:80      绕过 CF 直连 nginx

只要有一个通就算健康。这样域名配好前靠兜底、配好后走真实路径。

== 顺带修的 ==

  * monitor.log 属主还是 root(后来新建的),admin 写不进去
    -> 再 chown 一次
  * _build/check_lightsail.py 里的"公网"地址也要跟着改,
    并且**故意保留**一项查 :13245(预期 000)用来确认
    中转确实不再暴露公网

全量状态:三层地址、缓存头、监测、属主全部正确。
2026-10-08 22:41:33 +08:00

114 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
r'''看一眼 Lightsail 上中转服务器的完整状态。
⚠ 写这个文件的原因:用 `python -c @"..."@` 传带 `$(...)` 的远端命令,
PowerShell 会**先在本机求值** `$(systemctl ...)`(报"无法将 systemctl
项识别为 cmdlet"),还会吃掉引号导致 Python 语法错。
这个毛病我这一轮犯了四五次 —— **凡是超过两行的远端命令,一律写文件。**
用法:
python _build/check_lightsail.py
python _build/check_lightsail.py --fix # 顺便修文件属主
'''
from __future__ import annotations
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "_build"))
from lssh import run # noqa: E402
PORT = "13245"
DOMAIN = "yk.xxmxxs.top"
RELAY_DIR = "/opt/ykxmz-relay"
# 三层地址各查一遍:
# 域名 —— 用户实际走的路(Cloudflare -> nginx -> 中转)
# IP:80 —— 绕过 Cloudflare,直连 nginx(域名没配好时靠它)
# :13245 —— **应该不通**(中转已只绑 127.0.0.1,不再对公网)
DOMAIN_URL = "http://%s" % DOMAIN
NGINX_URL = "http://13.54.30.196:80"
DIRECT_URL = "http://13.54.30.196:%s" % PORT
REMOTE = r'''
R=__DIR__
P=__PORT__
echo "════ 服务 ════"
for s in ykxmz-relay nginx ykxmz-monitor.timer; do
printf ' %-22s %s\n' "$s" "$(systemctl is-active $s 2>&1)"
done
echo
echo "════ 三层地址(用户路径 / 绕 CF / 直连中转)════"
printf ' %-26s %s\n' "域名 __DOMAIN__" "$(curl -s -o /dev/null -w '%{http_code}' --max-time 12 __DOMAIN_URL__/v1/health)"
printf ' %-26s %s\n' "IP:80(nginx)" "$(curl -s -o /dev/null -w '%{http_code}' --max-time 12 __NGINX_URL__/v1/health)"
printf ' %-26s %s\n' ":__PORT__(应 000)" "$(curl -s -o /dev/null -w '%{http_code}' --max-time 8 __DIRECT_URL__/v1/health)"
printf ' %-26s %s\n' "本机 :__PORT__" "$(curl -s -o /dev/null -w '%{http_code}' --max-time 8 http://127.0.0.1:$P/v1/health)"
printf ' %-26s %s\n' "IP:80 延迟" "$(curl -s -o /dev/null -w '%{time_total}s' --max-time 12 __NGINX_URL__/v1/health)"
echo
echo "════ 首页角标 ════"
echo " IP:80 -> $(curl -s --max-time 10 __NGINX_URL__/ | grep -o '最新版 [0-9.]*' | head -1)"
echo " 域名 -> $(curl -s --max-time 12 __DOMAIN_URL__/ | grep -o '最新版 [0-9.]*' | head -1)"
echo
echo "════ 缓存头(决定 Cloudflare 缓不缓存)════"
printf ' %-20s %s 条\n' "下载" "$(curl -sI --max-time 10 __NGINX_URL__/download/ykxmz-setup-2.1.3.exe | grep -ci cache-control)"
curl -sI --max-time 10 __NGINX_URL__/download/ykxmz-setup-2.1.3.exe \
| grep -i '^cache-control' | sed 's/^/ /'
printf ' %-20s %s\n' "长轮询" "$(curl -sI --max-time 10 __NGINX_URL__/v1/health | grep -i '^cache-control' | tr -d '\r')"
echo
echo "════ 监听 / 进程 ════"
ss -tlnp 2>/dev/null | grep -E ":(80|$P) " | sed 's/^/ /'
ps -eo pid,rss,etime,cmd --sort=-rss 2>/dev/null | grep 'relay\.py' | grep -v grep | head -1 | sed 's/^/ /'
echo
echo "════ 监测单元 ════"
cat $R/monitor_state.txt 2>/dev/null | sed 's/^/ /'
echo " --- 探测的是什么地址 ---"
grep -E '^(PUBLIC_URL|FALLBACK_URL)=' $R/monitor.sh | sed 's/^/ /'
echo " --- monitor.log 尾部(只挑非 Permission 的)---"
grep -v 'Permission denied' $R/monitor.log 2>/dev/null | tail -4 | sed 's/^/ /'
echo
echo "════ 抢救报告 / 知识库 ════"
echo " 报告 $(ls $R/rescue_reports 2>/dev/null | wc -l) 份"
echo " 知识库 $(wc -l < $R/rescue_knowledge.md 2>/dev/null || echo 0) 行"
echo
echo "════ 资源 ════"
free -m 2>/dev/null | sed -n 2p | awk '{printf " 内存 %s/%s MB\n", $3, $2}'
df -h / | tail -1 | awk '{printf " 磁盘 %s 用 %s\n", $2, $5}'
uptime | sed 's/^/ /'
echo
echo "════ 文件属主(admin 必须能写日志)════"
ls -la $R/*.log $R/monitor_state.txt 2>/dev/null | awk '{print " " $3":"$4" "$9}'
'''
def main() -> int:
if "--fix" in sys.argv:
print(" ── 修属主 ──")
out = run("sudo chown -R admin:admin %s && sudo chmod 755 %s && echo OK"
% (RELAY_DIR, RELAY_DIR), timeout=120, quiet=True)
print(" " + out[1].strip())
cmd = (REMOTE
.replace("__DIR__", RELAY_DIR)
.replace("__PORT__", PORT)
.replace("__DOMAIN__", DOMAIN)
.replace("__DOMAIN_URL__", DOMAIN_URL)
.replace("__NGINX_URL__", NGINX_URL)
.replace("__DIRECT_URL__", DIRECT_URL))
out = run(cmd, timeout=300, quiet=True)
print(out[1] if isinstance(out, tuple) else out)
return 0
if __name__ == "__main__":
sys.exit(main())