You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在系统关机时触发Flask应用发送通知邮件?

最优实现方案

一、Flask应用内监听关机信号

直接在Flask代码中添加信号处理逻辑,捕获系统发送的关机/重启信号(SIGTERM是系统服务停止时的标准信号,SIGINT用于本地测试),触发邮件发送后优雅退出。

步骤1:集成邮件发送功能

用flask-mail简化配置,先安装依赖:

pip install flask-mail

在Flask应用中配置邮箱参数并实现邮件发送函数:

from flask import Flask
from flask_mail import Mail, Message
import signal
import sys

app = Flask(__name__)

# 替换为你的实际邮箱配置
app.config['MAIL_SERVER'] = 'smtp.example.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = 'your-email@example.com'
app.config['MAIL_PASSWORD'] = 'your-app-specific-password'  # 用邮箱的应用专用密码,而非登录密码
app.config['MAIL_DEFAULT_SENDER'] = 'your-email@example.com'

mail = Mail(app)

def send_restart_alert():
    """发送服务器重启提醒邮件"""
    msg = Message(
        subject='服务器即将重启,Flask应用需手动重启',
        recipients=['your-notify-email@example.com']  # 替换为接收提醒的邮箱
    )
    msg.body = """
    注意:服务器即将执行强制系统更新并重启。
    重启完成后,请手动登录服务器,重启Flask应用。
    """
    try:
        with app.app_context():
            mail.send(msg)
        print("重启提醒邮件已发送")
    except Exception as e:
        print(f"发送邮件失败:{str(e)}")

步骤2:注册信号处理函数

添加信号监听,捕获关机信号并触发邮件发送:

def handle_shutdown_signal(signum, frame):
    """处理关机信号"""
    print(f"收到信号 {signum},即将发送重启提醒邮件")
    send_restart_alert()
    sys.exit(0)

# 注册信号处理
signal.signal(signal.SIGTERM, handle_shutdown_signal)
signal.signal(signal.SIGINT, handle_shutdown_signal)

@app.route('/')
def index():
    return 'Flask应用运行中'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

二、系统级兜底方案(避免信号被忽略)

如果系统重启时直接强制杀死进程(比如超时强制终止),Flask的信号处理可能来不及执行。这时候可以用systemd服务脚本,在服务停止前执行独立的邮件发送脚本。

步骤1:编写独立邮件发送脚本(send_alert.py)

抽离邮件逻辑为独立脚本,无需Flask上下文:

import smtplib
from email.mime.text import MIMEText

def send_restart_alert():
    # 替换为你的实际邮箱配置
    smtp_server = 'smtp.example.com'
    smtp_port = 587
    username = 'your-email@example.com'
    password = 'your-app-specific-password'
    sender = 'your-email@example.com'
    receiver = 'your-notify-email@example.com'

    msg = MIMEText("""
    注意:服务器即将执行强制系统更新并重启。
    重启完成后,请手动登录服务器,重启Flask应用。
    """, 'plain', 'utf-8')
    msg['Subject'] = '服务器即将重启,Flask应用需手动重启'
    msg['From'] = sender
    msg['To'] = receiver

    try:
        with smtplib.SMTP(smtp_server, smtp_port) as server:
            server.starttls()
            server.login(username, password)
            server.sendmail(sender, receiver, msg.as_string())
        print("重启提醒邮件已发送")
    except Exception as e:
        print(f"发送邮件失败:{str(e)}")

if __name__ == '__main__':
    send_restart_alert()

步骤2:配置systemd服务文件

创建/etc/systemd/system/flask-app.service:

[Unit]
Description=Flask Application
After=network.target

[Service]
User=your-user  # 替换为运行Flask应用的系统用户
WorkingDirectory=/path/to/your/flask/app
ExecStart=/usr/bin/python3 app.py
ExecStop=/usr/bin/python3 /path/to/send_alert.py  # 服务停止时执行邮件脚本
Restart=no  # 重启后无法自动登录,关闭自动重启
KillMode=process  # 确保先执行ExecStop再终止进程
TimeoutStopSec=30  # 给邮件发送留足够时间

[Install]
WantedBy=multi-user.target

重新加载systemd并启动服务:

sudo systemctl daemon-reload
sudo systemctl start flask-app
sudo systemctl enable flask-app

注意事项

  • 邮箱需使用应用专用密码:Gmail、Outlook等邮箱需开启两步验证后生成应用密码,不能用普通登录密码。
  • 测试信号触发:可通过kill -TERM <flask-pid>命令测试信号捕获和邮件发送功能。
  • 网络权限:确保服务器防火墙放行SMTP端口(如587),能正常连接邮箱SMTP服务器。

内容的提问来源于stack exchange,提问作者MrPeriodical

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:00:25