Serv00服务器哪吒Agent保活并启用网页实时输出监控

493次阅读
没有评论

共计 6119 个字符,预计需要花费 16 分钟才能阅读完成。

首先感谢这两位作者脚本提出的贡献

https://hkfires.pp.ua/blog/1496222667/

在 Serv00 上使用 Cron 进行进程保活的情况下,发现 Cron 计划任务经常被清掉,导致进程存活时间很短

这个方案利用了 Serv00 自带 Apache 服务器的 Phusion Passenger 插件功能,每次访问网页时可以唤醒 Nodejs 程序

部署步骤

首先你需要手搓一个链接来启动你需要监控的 Serv00 服务器脚本内容如下

Serv00 服务器哪吒 Agent 保活并启用网页实时输出监控在 install-agent.sh 脚本中添加以下代码


#!/bin/bash

USERNAME=$(whoami)
WORKDIR="/home/${USERNAME}/.nezha-agent"

# 自定义参数部分
NZ_DASHBOARD_SERVER="your_dashboard_server" # 修改为你的 Dashboard 站点地址
NZ_DASHBOARD_PORT="5555" # 修改为你的面板 RPC 端口
NZ_DASHBOARD_PASSWORD="your_agent_secret" # 修改为你的 Agent 密钥
NZ_GRPC_PROXY="false" # 修改为 true 或 false,表示是否启用 gRPC 端口的 SSL/TLS 加密

# 下载 nezha-agent 的函数
download_agent() {
DOWNLOAD_LINK="https://github.com/nezhahq/agent/releases/latest/download/nezha-agent_freebsd_amd64.zip"
if ! wget -qO "$ZIP_FILE" "$DOWNLOAD_LINK"; then
echo 'error: Download failed! Please check your network or try again.'
return 1
fi
return 0
}

# 解压函数
decompression() {
unzip "$1" -d "$TMP_DIRECTORY"
EXIT_CODE=$?
if [${EXIT_CODE} -ne 0 ]; then
rm -r "$TMP_DIRECTORY"
echo "removed: $TMP_DIRECTORY"
exit 1
fi
}

# 安装 nezha-agent 的函数
install_agent() {install -m 755 ${TMP_DIRECTORY}/nezha-agent ${WORKDIR}/nezha-agent
}

# 生成 config.yml 的函数
generate_config() {CONFIG_PATH="${WORKDIR}/config.yml"
cat > "$CONFIG_PATH" << EOF
client_secret: ${NZ_DASHBOARD_PASSWORD}
debug: false
disable_auto_update: false
disable_command_execute: false
disable_force_update: false
disable_nat: false
disable_send_query: false
gpu: false
insecure_tls: false
ip_report_period: 1800
report_delay: 1
server: ${NZ_DASHBOARD_SERVER}:${NZ_DASHBOARD_PORT}
skip_connection_count: false
skip_procs_count: false
temperature: false
tls: ${NZ_GRPC_PROXY}
use_gitee_to_upgrade: false
use_ipv6_country_code: false
uuid:
EOF
echo "config.yml 已成功生成到 ${CONFIG_PATH}"
}

# 生成启动脚本的函数
generate_run_agent() {if [ -z "${NZ_DASHBOARD_SERVER}" ] || [-z "${NZ_DASHBOARD_PASSWORD}" ]; then
echo "error! 所有选项都不能为空 "
return 1
rm -rf ${WORKDIR}
exit
fi

generate_config

cat > ${WORKDIR}/start.sh << EOF
#!/bin/bash
pgrep -f 'nezha-agent' | xargs -r kill
cd ${WORKDIR}
TMPDIR="${WORKDIR}" exec ${WORKDIR}/nezha-agent -c config.yml >/dev/null 2>&1
EOF
chmod +x ${WORKDIR}/start.sh
}

# 启动 nezha-agent 的函数
run_agent() {nohup ${WORKDIR}/start.sh >/dev/null 2>&1 &
printf " 正在启动 nezha-agent,请耐心等待...\n"
sleep 3
if pgrep -f "nezha-agent -c" > /dev/null; then
echo "nezha-agent 已启动!"
echo " 如果面板处未上线,请检查参数是否填写正确,并停止 agent 进程,删除已安装的 agent 后重新安装!"
echo " 停止 agent 进程的命令:pgrep -f 'nezha-agent' | xargs -r kill"
echo " 删除已安装的 agent 的命令:rm -rf ~/.nezha-agent"
echo
echo " 如果你想使用 pm2 管理 agent 进程,请执行:pm2 start ~/.nezha-agent/start.sh --name nezha-agent"
else
rm -rf "${WORKDIR}"
echo "nezha-agent 启动失败,请检查参数填写是否正确,并重新安装!"
fi
}

# 主程序
mkdir -p ${WORKDIR}
cd ${WORKDIR}
TMP_DIRECTORY="$(mktemp -d)"
ZIP_FILE="${TMP_DIRECTORY}/nezha-agent_freebsd_amd64.zip"

[! -e ${WORKDIR}/start.sh ] && generate_run_agent
[! -e ${WORKDIR}/nezha-agent ] && download_agent \
&& decompression "${ZIP_FILE}" \
&& install_agent

rm -rf "${TMP_DIRECTORY}"
[-e ${WORKDIR}/start.sh ] && run_agent

安装完监控以后开始添加域名

Serv00 服务器哪吒 Agent 保活并启用网页实时输出监控

当然你也可以使用自带的域名

SSH 登录 Serv00,输入 cd domains/ 你的网站域名 /public_nodejs/

执行

mv public static
npm22 install express
npm install express morgan

Serv00 服务器哪吒 Agent 保活并启用网页实时输出监控新建个名为 app.js 的文件,粘贴以下内容,把 Serv00 登录用户名 修改成你自己的 Serv00 用户名


const express = require("express");
const path = require("path");
const fs = require("fs");
const {exec} = require("child_process");

const app = express();
const port = 3000;

// 配置参数
const user = "Serv00 登录用户名 ";
const processCommand = "/home/${user}/.nezha-agent/nezha-agent -c /home/${user}/.nezha-agent/config.yml";
const logDir = "/home/${user}/domains/ 你的域名 /logs";
const statusLogPath = path.join(logDir, "nz.log");

// 初始化日志目录
!fs.existsSync(logDir) && fs.mkdirSync(logDir, { recursive: true});

// 增强版日志清理(保留当前日志)function cleanLogs() {
  try {const now = Date.now();
    const files = fs.readdirSync(logDir);

    files.forEach(file => {
      // 跳过当前状态日志
      if (file === "nz.log") return;

      const filePath = path.join(logDir, file);
      const stats = fs.statSync(filePath);

      // 删除 10 分钟前的日志文件
      if ((now - stats.mtimeMs) > 600000) {fs.unlinkSync(filePath);
        console.log(` 已清理过期日志: ${file}`);
      }
    });

    // 日志轮换(保留最新 5 个)const logFiles = fs.readdirSync(logDir)
      .filter(f => f.startsWith("nz.log."))
      .sort()
      .reverse();

    if (logFiles.length > 5) {logFiles.slice(5).forEach(f => {fs.unlinkSync(path.join(logDir, f));
      });
    }
  } catch (err) {console.error(" 日志清理失败:", err);
  }
}

// 带日志轮换的进程检查
function checkProcessAlive() {exec(`pgrep -u ${user} -f '${processCommand}'`, (err, stdout) => {const timestamp = new Date().toISOString();
    const status = err || !stdout.trim() ? "down" : "up";

    // 每日日志轮换
    if (!fs.existsSync(statusLogPath)) {const rotatedLog = path.join(logDir, `nz.log.${new Date().toISOString().split('T')[0]}`);
      fs.existsSync(rotatedLog) || fs.copyFileSync(statusLogPath, rotatedLog);
    }

    // 写入状态日志
    fs.appendFile(statusLogPath, `[${timestamp}] Process ${status}\n`, (err) => {err && console.error(" 状态写入失败:", err);
    });

    if (status === "down") {exec(`nohup ${processCommand} >> ${logDir}/nezha.log 2>&1 &`,
        (err) => err && console.error(" 进程启动失败:", err)
      );
    }
  });
}

// 日志查看路由(实时读取)app.get("/status-log", (req, res) => {fs.readFile(statusLogPath, "utf8", (err, data) => {if (err) {res.status(500).type("text/plain").send(" 日志暂不可用 ");
    } else {res.type("text/plain").send(data);
    }
  });
});

// 静态文件服务
app.use(express.static(path.join(__dirname, "static")));

// 前端页面路由
app.get("/", (req, res) => {res.sendFile(path.join(__dirname, "static/index.html"));
});

// 启动定时任务
setInterval(checkProcessAlive, 5000);    // 5 秒进程检查
setInterval(cleanLogs, 600000);          // 10 分钟清理周期

app.listen(port, () => {
  console.log(` 服务运行中:- 监控页面:http://localhost:${port}
  - 实时日志:${statusLogPath}`);
});

再将 app.js 上传到服务器,完整路径是 /home/ 你的用户名 /domains/ 你的网站域名 /public_nodejs/,修改完成后 public_nodejs 目录下应该和我一样

需要你在日志目录下创建 nz.log 文件

如果服务启动不了请查看日志目录下 error.log

配套前端页面(static/index.html)


<!DOCTYPE html>
<html>
<head>
    <title> 进程状态监控 </title>
    <style>
        #log-container {
            background: #1a1a1a;
            color: #00ff00;
            padding: 20px;
            margin: 20px;
            border-radius: 5px;
            max-height: 70vh;
            overflow: auto;
            font-family: 'Courier New', monospace;
            white-space: pre-wrap;
        }
        .timestamp {color: #888;}
    </style>
</head>
<body>
    <h1 id='pk-menu-0'>Nezha 进程状态监控 </h1>
    <div id="log-container"> 正在加载实时日志...</div>

    <script>
        const logContainer = document.getElementById('log-container');
        
        async function updateLogs() {
            try {const response = await fetch('/status-log');
                const rawText = await response.text();
                const formattedText = rawText
                    .split('\n')
                    .map(line => line.replace(/($$\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$$)/,
                        '<span class="timestamp">$1</span>'
                    ))
                    .join('\n');
                
                logContainer.innerHTML = formattedText;
                logContainer.scrollTop = logContainer.scrollHeight;
            } catch (err) {logContainer.textContent = '日志更新失败:' + err.message;}
        }

        // 每 2 秒更新 + 首次加载
        setInterval(updateLogs, 2000);
        updateLogs();
    </script>
</body>
</html>

测试

Serv00 服务器哪吒 Agent 保活并启用网页实时输出监控

每当我们杀死程序的时候又会自己启动

网页监控随便找个都行,市面上有很多免费的

自动化网页监控项目推荐upptime,不需要有服务器,只需要有 Github 账号就能够进行部署

后续

可能清理日记还有些问题等以后优化吧

正文完
 0
linyu
版权声明:本站原创文章,由 linyu 于2025-02-14发表,共计6119字。
转载说明:
本文链接:
文章作者
Terblog
隐私政策
PrivacyPolicy
用户协议
UseGenerator
许可协议
NC-SA 4.0
评论(没有评论)