解决关闭终端窗口导致服务挂掉的问题

在使用 ./start.sh 启动服务后,关闭终端窗口却导致服务挂掉,如何确保服务在关闭终端后依然稳定运行。

问题原因分析

在终端中运行 ./start.sh 启动一个服务时,通常该服务作为前台进程运行,并且与当前终端会话紧密关联。关闭终端窗口时,操作系统会向所有与该终端关联的进程发送 SIGHUP(挂起信号),这会导致进程终止。因此,服务在终端关闭后挂掉,主要是因为其依赖于终端会话的存在。

解决方法

为了确保服务在关闭终端后仍然运行,您可以采用以下几种方法:

  1. 使用 nohup 命令
  2. 使用 &disown
  3. 使用 screentmux 工具
  4. 配置为 systemd 服务

下面将详细介绍每种方法的具体操作步骤和优缺点。


方法一:使用 nohup 命令

nohup(No Hang Up)命令用于运行不受挂起信号影响的程序。通过 nohup 启动服务,可以确保服务在终端关闭后继续运行。

步骤

  1. 启动服务并使用 nohup

    nohup ./start.sh > output.log 2>&1 &
    
    • nohup:忽略挂起信号。
    • ./start.sh:您的启动脚本。
    • > output.log:将标准输出重定向到 output.log 文件。
    • 2>&1:将标准错误重定向到标准输出。
    • &:将进程放入后台运行。
  2. 验证服务是否在后台运行

    使用 pspgrep 命令查找进程:

    ps aux | grep start.sh
    # 或
    pgrep -fl start.sh
    

优缺点

  • 优点

    • 简单易用,无需额外安装软件。
    • 输出和错误信息可重定向到文件,便于日志管理。
  • 缺点

    • 无法轻松地重新连接到进程的终端。
    • 不适合需要交互的服务。

方法二:使用 &disown

这种方法将进程放入后台运行,并使用 disown 命令将其与当前终端会话脱离,从而防止进程在终端关闭时被终止。

步骤

  1. 启动服务并放入后台

    ./start.sh &
    
  2. 使用 disown 将进程与终端脱离

    disown
    
  3. 验证服务是否在后台运行

    使用 jobs 查看后台作业,或使用 ps 命令查找进程:

    jobs
    ps aux | grep start.sh
    

优缺点

  • 优点

    • 简单快捷。
    • 允许将多个进程与终端脱离。
  • 缺点

    • 需要手动执行 disown
    • nohup 类似,无法重新连接到进程的终端。

方法三:使用 screentmux 工具

screentmux 是强大的终端多路复用器,允许您创建多个独立的终端会话,即使关闭原始终端,服务仍在运行。您可以随时重新连接到这些会话,查看或控制服务。

使用 screen

  1. 安装 screen

    如果尚未安装,可以使用包管理器安装:

    # 对于 Debian/Ubuntu 系统
    sudo apt-get install screen
    
    # 对于 CentOS/RHEL 系统
    sudo yum install screen
    
  2. 创建一个新的 screen 会话

    screen -S myservice
    
    • -S myservice:为会话命名为 myservice,便于管理。
  3. screen 会话中启动服务

    ./start.sh
    
  4. 分离 screen 会话

    按下 Ctrl+A,然后按 D 键,将会话分离,服务将在后台继续运行。

  5. 重新连接到 screen 会话

    screen -r myservice
    

使用 tmux

  1. 安装 tmux

    如果尚未安装,可以使用包管理器安装:

    # 对于 Debian/Ubuntu 系统
    sudo apt-get install tmux
    
    # 对于 CentOS/RHEL 系统
    sudo yum install tmux
    
  2. 创建一个新的 tmux 会话

    tmux new -s myservice
    
    • -s myservice:为会话命名为 myservice
  3. tmux 会话中启动服务

    ./start.sh
    
  4. 分离 tmux 会话

    按下 Ctrl+B,然后按 D 键,将会话分离,服务将在后台继续运行。

  5. 重新连接到 tmux 会话

    tmux attach -t myservice
    

优缺点

  • 优点

    • 支持多会话和窗口管理。
    • 允许随时重新连接到会话,查看或控制服务。
    • 适合需要长期运行并可能需要交互的服务。
  • 缺点

    • 需要学习基本的 screentmux 命令。
    • 占用一定的系统资源。

方法四:配置为 systemd 服务

systemd 是现代 Linux 发行版中常用的初始化系统和服务管理器。将您的服务配置为 systemd 服务,可以实现自动启动、自动重启、日志管理等高级功能。

步骤

  1. 创建 systemd 服务文件

    使用文本编辑器创建一个新的服务文件,例如 /etc/systemd/system/myservice.service

    [Unit]
    Description=My Custom Service
    After=network.target
    
    [Service]
    Type=simple
    ExecStart=/path/to/start.sh
    Restart=always
    User=yourusername
    WorkingDirectory=/path/to/working/directory
    StandardOutput=file:/var/log/myservice/output.log
    StandardError=file:/var/log/myservice/error.log
    
    [Install]
    WantedBy=multi-user.target
    
    • 字段说明
      • Description:服务描述。
      • After:指定服务启动的顺序,此处表示在网络服务启动后再启动。
      • Type:服务类型,simple 表示简单服务。
      • ExecStart:启动服务的命令或脚本的完整路径。
      • Restart:指定服务崩溃后的重启策略,always 表示总是重启。
      • User:运行服务的用户。
      • WorkingDirectory:服务的工作目录。
      • StandardOutputStandardError:日志输出路径。
  2. 创建日志目录并设置权限

    sudo mkdir -p /var/log/myservice
    sudo chown yourusername:yourusername /var/log/myservice
    
  3. 重新加载 systemd 配置

    sudo systemctl daemon-reload
    
  4. 启动服务

    sudo systemctl start myservice
    
  5. 设置服务开机自启

    sudo systemctl enable myservice
    
  6. 检查服务状态

    sudo systemctl status myservice
    

优缺点

  • 优点

    • 服务可配置性强,支持自动启动、自动重启、日志管理等。
    • 与系统集成良好,适用于生产环境。
    • 提供丰富的管理命令,如启动、停止、重启、查看状态等。
  • 缺点

    • 配置文件相对复杂,需要一定的学习成本。
    • 需要管理员权限进行配置。

总结

在关闭终端窗口后服务挂掉的问题,主要是由于服务进程与终端会话绑定,关闭终端导致进程接收到挂起信号 (SIGHUP) 而终止。通过上述四种方法,您可以有效地解决这一问题:

  1. nohup:适用于简单场景,快速将服务放入后台。
  2. &disown:灵活性较高,适用于无需交互的服务。
  3. screentmux:适合需要长期运行且可能需要交互的服务。
  4. systemd 服务:适用于生产环境,提供全面的服务管理功能。

根据具体需求和使用场景,选择最适合的方法即可。

posted on   滚动的蛋  阅读(134)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2019-11-22 SpringBoot AOP注解式拦截与方法规则拦截

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示