本文目录导读:

我来为你详细介绍如何编写自动启动服务并实现监控功能,涵盖Linux和Windows两个主要平台。
Linux 系统服务(Systemd)
创建服务单元文件
# /etc/systemd/system/myapp.service [Unit] Description=My Application Service After=network.target Wants=network-online.target [Service] Type=simple User=myapp Group=myapp WorkingDirectory=/opt/myapp Environment="NODE_ENV=production" ExecStart=/usr/bin/node /opt/myapp/app.js Restart=always RestartSec=10 StartLimitIntervalSec=60 StartLimitBurst=5 # 安全配置 CapabilityBoundingSet= NoNewPrivileges=true PrivateTmp=true ProtectSystem=full ProtectHome=true [Install] WantedBy=multi-user.target
监控脚本示例
#!/bin/bash
# /opt/myapp/monitor.sh
# 配置
SERVICE_NAME="myapp"
LOG_FILE="/var/log/myapp-monitor.log"
HEALTH_URL="http://localhost:3000/health"
TIMEOUT=10
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
check_service() {
# 检查进程是否存在
if ! systemctl is-active --quiet "$SERVICE_NAME"; then
log "ERROR: Service $SERVICE_NAME is not running"
return 1
fi
# 检查健康端点
if [ -n "$HEALTH_URL" ]; then
if ! curl -s --max-time "$TIMEOUT" "$HEALTH_URL" > /dev/null; then
log "WARNING: Health check failed for $SERVICE_NAME"
return 1
fi
fi
return 0
}
restart_service() {
log "Restarting $SERVICE_NAME..."
systemctl restart "$SERVICE_NAME"
sleep 5
# 验证重启成功
if check_service; then
log "Service restarted successfully"
return 0
else
log "ERROR: Service restart failed"
return 1
}
}
monitor_loop() {
local failures=0
local max_failures=3
while true; do
if ! check_service; then
((failures++))
if [ "$failures" -ge "$max_failures" ]; then
restart_service
failures=0
fi
else
failures=0
fi
sleep 30
done
}
# 主流程
case "$1" in
start)
log "Starting monitor..."
monitor_loop &
echo $! > /var/run/myapp-monitor.pid
;;
stop)
kill $(cat /var/run/myapp-monitor.pid)
;;
status)
check_service && echo "Running" || echo "Stopped"
;;
*)
echo "Usage: $0 {start|stop|status}"
;;
esac
Systemd监控服务
# /etc/systemd/system/myapp-monitor.service [Unit] Description=My Application Monitor After=network.target Requires=myapp.service [Service] Type=forking ExecStart=/opt/myapp/monitor.sh start ExecStop=/opt/myapp/monitor.sh stop PIDFile=/var/run/myapp-monitor.pid Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target
Windows 服务
C# Windows 服务示例
// MyService.cs
using System;
using System.Diagnostics;
using System.IO;
using System.ServiceProcess;
using System.Timers;
public partial class MyService : ServiceBase
{
private Timer _healthCheckTimer;
private Process _workerProcess;
private EventLog _eventLog;
public MyService()
{
InitializeComponent();
this.ServiceName = "MyAppService";
_eventLog = new EventLog();
if (!EventLog.SourceExists("MyAppService"))
{
EventLog.CreateEventSource("MyAppService", "Application");
}
_eventLog.Source = "MyAppService";
_eventLog.Log = "Application";
}
protected override void OnStart(string[] args)
{
_eventLog.WriteEntry("Service starting...", EventLogEntryType.Information);
try
{
StartWorkerProcess();
// 设置健康检查定时器
_healthCheckTimer = new Timer(30000); // 30秒
_healthCheckTimer.Elapsed += HealthCheckTimer_Elapsed;
_healthCheckTimer.AutoReset = true;
_healthCheckTimer.Start();
_eventLog.WriteEntry("Service started successfully", EventLogEntryType.Information);
}
catch (Exception ex)
{
_eventLog.WriteEntry($"Failed to start service: {ex.Message}",
EventLogEntryType.Error);
throw;
}
}
protected override void OnStop()
{
_eventLog.WriteEntry("Service stopping...", EventLogEntryType.Information);
_healthCheckTimer?.Stop();
_healthCheckTimer?.Dispose();
StopWorkerProcess();
_eventLog.WriteEntry("Service stopped", EventLogEntryType.Information);
}
private void StartWorkerProcess()
{
_workerProcess = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "node",
Arguments = "app.js",
WorkingDirectory = @"C:\MyApp",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
};
_workerProcess.Exited += WorkerProcess_Exited;
_workerProcess.EnableRaisingEvents = true;
_workerProcess.Start();
}
private void StopWorkerProcess()
{
if (_workerProcess != null && !_workerProcess.HasExited)
{
_workerProcess.Kill();
_workerProcess.WaitForExit(5000);
}
}
private void WorkerProcess_Exited(object sender, EventArgs e)
{
_eventLog.WriteEntry("Worker process exited unexpectedly",
EventLogEntryType.Warning);
// 自动重启
if (!_workerProcess.HasExited)
{
StartWorkerProcess();
}
}
private void HealthCheckTimer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
// 健康检查逻辑
if (_workerProcess == null || _workerProcess.HasExited)
{
_eventLog.WriteEntry("Health check failed: process not running",
EventLogEntryType.Warning);
StartWorkerProcess();
}
// HTTP健康检查
using (var client = new System.Net.Http.HttpClient())
{
client.Timeout = TimeSpan.FromSeconds(10);
var response = client.GetAsync("http://localhost:3000/health")
.GetAwaiter().GetResult();
if (!response.IsSuccessStatusCode)
{
_eventLog.WriteEntry($"Health check returned {response.StatusCode}",
EventLogEntryType.Warning);
}
}
}
catch (Exception ex)
{
_eventLog.WriteEntry($"Health check failed: {ex.Message}",
EventLogEntryType.Warning);
}
}
}
安装服务
# install-service.ps1
$serviceName = "MyAppService"
$servicePath = "C:\MyApp\MyService.exe"
# 检查服务是否存在
if (Get-Service $serviceName -ErrorAction SilentlyContinue) {
Write-Host "Service already exists, removing..."
Stop-Service $serviceName -Force
& "C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe" /u $servicePath
}
# 安装服务
& "C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe" $servicePath
# 配置服务
Set-Service -Name $serviceName -StartupType Automatic
Start-Service $serviceName
Write-Host "Service installed and started successfully"
配置自动重启策略
Linux Systemd 配置
[Service] Restart=always RestartSec=10 StartLimitInterval=600 StartLimitBurst=10 # 限制内存使用 MemoryMax=500M MemoryHigh=400M # CPU限制 CPUQuota=80%
Windows Service 配置
# 配置服务恢复选项 sc failure $serviceName reset=86400 actions=restart/30000/restart/60000/restart/120000 sc.exe failureflag $serviceName 1
高级监控集成
Prometheus 指标暴露
# metrics.py
from prometheus_client import start_http_server, Gauge, Counter
import psutil
import time
class ServiceMonitor:
def __init__(self):
self.service_up = Gauge('service_up', 'Service status')
self.cpu_usage = Gauge('cpu_usage_percent', 'CPU usage')
self.memory_usage = Gauge('memory_usage_mb', 'Memory usage')
self.restart_count = Counter('restart_total', 'Total restarts')
def collect_metrics(self):
while True:
self.cpu_usage.set(psutil.cpu_percent())
self.memory_usage.set(psutil.virtual_memory().used / 1024 / 1024)
time.sleep(15)
if __name__ == '__main__':
monitor = ServiceMonitor()
start_http_server(8000)
monitor.collect_metrics()
邮件告警
# alert.py
import smtplib
from email.mime.text import MIMEText
import requests
def send_alert(service_name, error_message):
msg = MIMEText(f"""
Service: {service_name}
Status: DOWN
Time: {time.ctime()}
Error: {error_message}
""")
msg['Subject'] = f'ALERT: {service_name} is down'
msg['From'] = 'monitor@example.com'
msg['To'] = 'admin@example.com'
with smtplib.SMTP('smtp.example.com') as server:
server.login('user', 'password')
server.send_message(msg)
最佳实践建议
-
日志管理
- 使用结构化日志 (JSON格式)
- 实施日志轮转
- 集中日志收集
-
健康检查
- 实现多种检查方式 (进程、HTTP、端口)
- 设置合理的超时时间
- 避免检查本身成为新故障点
-
重启策略
- 设置最大重启次数防止循环重启
- 增加指数退避机制
- 记录重启原因和次数
-
监控指标
- CPU、内存、磁盘使用率
- 响应时间、错误率
- 连接数、请求数
-
安全考虑
- 最小权限原则运行服务
- 使用服务账户而非管理员账户
- 加密敏感配置
这个方案可以根据你的具体需求调整,确保服务稳定运行并快速响应故障,好的监控不仅要发现问题,还要帮助快速定位和解决问题。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播