如何在Linux服务器上后台持久运行Gunicorn

如何在Linux服务器上后台持久运行Gunicorn

  • **问题概述**
  • **解决方案一:使用`nohup`命令**
  • **解决方案二:使用`systemd`服务**
    • **创建`systemd`服务文件**
    • **修改`systemd`服务文件以使用虚拟环境**
    • 日志管理
    • **激活并启动服务:**
    • 如何设置用户和组
      • **确认用户和组存在**
      • 如何赋予用户和组对应用程序目录和所需资源有正确的权限
      • 如何查看我的目前系统中的用户和组
  • **结论**

问题概述

在使用SSH远程连接到服务器并在终端启动**gunicorn时,关闭SSH窗口后常常导致gunicorn**进程终止,这导致无法访问API接口,尽管端口侦听似乎仍在进行。

解决方案一:使用nohup命令

nohup命令可用于在退出登录或关闭终端后继续运行进程。要使用nohup,您可以在命令前加上**nohup,并在命令最后添加&**,将进程放入后台运行。

nohup gunicorn -w 4 --bind 0.0.0.0:6666 --reload run:app --timeout 120 --access-logfile - --error-logfile - &

这个命令将**gunicorn的输出重定向到一个名为nohup.out的文件中,即使SSH会话关闭,gunicorn**进程也会继续运行。

解决方案二:使用systemd服务

创建systemd服务文件

创建一个新的服务文件**/etc/systemd/system/gunicorn.service(服务文件名你可以自己定义,例如answerai.service)**,文件内容如下:

[Unit]
Description=gunicorn daemon for my web application
After=network.target

[Service]
User=myuser
Group=mygroup
WorkingDirectory=/path/to/your/app
ExecStart=/path/to/your/virtualenv/bin/gunicorn --workers 4 --bind 0.0.0.0:6666 run:app
StandardOutput=append:/path/to/your/logs/gunicorn.out
StandardError=append:/path/to/your/logs/gunicorn.err

[Install]
WantedBy=multi-user.target

替换**myusermygroup/path/to/your/app/path/to/your/virtualenv/bin/gunicorn**为您的实际信息。

在这个文件中:

  • 我们设定了描述和在网络服务启动之后启动**gunicorn**。

  • 在**[Service]**部分,我们定义了运行服务的用户(myuser)和组(mygroup),服务的工作目录(/path/to/your/app),以及启动命令。

  • **ExecStart行指定了启动服务时要执行的命令。在这里,我们告诉gunicorn**使用4个工作进程

    ExecStart 中的命令实际上定义了如何启动 gunicorn 以及它将如何与您的应用程序进行通信。这里有两种常见的绑定方式:

    1. 绑定到一个 UNIX 套接字:

      ExecStart=/var/www/myapp/venv/bin/gunicorn --workers 4 --bind unix:/var/www/myapp/myapp.sock myapp.wsgi:application
      

      这条命令将 gunicorn 绑定到一个 UNIX 套接字文件 myapp.sock。这种方式在与 Nginx 等 Web 服务器配合时很常见,因为它们可以直接通过 UNIX 套接字与 gunicorn 通信,这比 TCP 套接字更高效,因为它们不需要进行网络堆栈的额外处理。

    2. 绑定到 TCP 端口:

      ExecStart=/path/to/your/virtualenv/bin/gunicorn --workers 4 --bind 0.0.0.0:6666 run:app
      

      这条命令将 gunicorn 绑定到所有接口的 6666 端口。这种方式在您直接通过 HTTP 访问 gunicorn 时很有用,或者在测试环境中很常见,因为它允许从任何 IP 地址通过指定端口访问应用程序。

      选择哪种方式取决于您的部署需求和安全考虑。UNIX 套接字通常更安全,因为它们在文件系统中作为文件存在,不对外暴露端口,而且通常会配合 Web 服务器一起使用。如果您直接使用 TCP 端口绑定,那么可能需要考虑使用防火墙规则来限制对该端口的访问。

  • 最后,在**[Install]**部分,我们定义了这个服务将如何被安装和启动,这里是在多用户目标下。

    在**systemd服务文件中的[Install]部分,WantedBy是一个指令,它定义了当该服务被enable时应该被哪个“目标”(target)所拉起。目标是systemd**中用于定义系统启动过程中的不同阶段的一个单位。

    **multi-user.target是一个目标,它相当于传统的运行级别(runlevel)。它通常用于设置一个多用户的文本模式环境,没有图形界面,但网络服务已启动并可以使用。当您设置一个服务WantedBy=multi-user.target并启用它(使用systemctl enable命令)时,您告诉systemd**在达到多用户文本模式时,也就是系统启动过程中达到相应的点时,应该启动这个服务。

    简单来说,**WantedBy=multi-user.target**确保了您的服务会在系统启动到多用户运行级别时自动启动。这是大多数后台服务的标准配置,使得在系统启动时无需手动启动服务。

修改systemd服务文件以使用虚拟环境

如果您需要在Python虚拟环境中运行**gunicorn,您应该在systemd服务文件的ExecStart命令中指定虚拟环境中的gunicorn**可执行文件的完整路径。这样,服务在启动时会使用虚拟环境中的Python和依赖包。

您的服务文件中的**ExecStart**部分应该看起来像这样:

[Service]
...
ExecStart=/path/to/your/virtualenv/bin/gunicorn --workers 4 --bind 0.0.0.0:6666 run:app
...

在这里,**/path/to/your/virtualenv/bin/gunicorn是您虚拟环境中gunicorn的完整路径。您需要将/path/to/your/virtualenv**替换为您的虚拟环境实际所在的路径。

举例说明:

假设您的虚拟环境位于**/home/myuser/myappenv,并且您的应用程序目录是/home/myuser/myapp**。服务文件可能会是这样的:

[Unit]
Description=gunicorn daemon for myapp web application
After=network.target

[Service]
User=myuser
Group=myuser
WorkingDirectory=/home/myuser/myapp
ExecStart=/home/myuser/myappenv/bin/gunicorn --access-logfile - --workers 4 --bind 0.0.0.0:6666 myapp.wsgi:application

[Install]
WantedBy=multi-user.target

这里的关键是确保**ExecStart指向了虚拟环境中的gunicorn**。

日志管理

使用**systemd来管理gunicorn服务时,systemd本身提供了日志管理功能,它会自动处理服务的输出,并存储在系统的日志中,可以通过journalctl命令来访问。因此,如果您使用systemd,通常不需要nohup来重定向输出到文件中,systemd**会更好地为您服务。

不过,如果您仍然想要将**gunicorn的输出重定向到特定的文件,您可以在systemd服务文件的[Service]部分使用StandardOutputStandardError**指令来指定输出和错误日志的路径。

例如:

[Service]
...
ExecStart=/path/to/your/virtualenv/bin/gunicorn --workers 4 --bind 0.0.0.0:6666 run:app
StandardOutput=append:/path/to/your/logs/gunicorn.out
StandardError=append:/path/to/your/logs/gunicorn.err
...

这里,StandardOutput=append:/path/to/your/logs/gunicorn.out指令将会把stdout输出追加到指定的文件中,StandardError=append:/path/to/your/logs/gunicorn.err则将错误信息追加到另一个文件。您需要确保这些文件是可写的,并且gunicorn运行的用户(在[Service]部分指定的User)具有写入这些文件的权限。

请注意,使用**append是在systemd较新版本中引入的选项,如果您的系统中的systemd版本不支持,您可能需要去掉append:**并直接写文件路径。

此外,如果您想保留使用**nohup的原始方法并重定向输出到文件,那么您就不需要systemd服务。您只需在命令行中启动gunicorn**,如下所示:

nohup /path/to/your/virtualenv/bin/gunicorn --workers 4 --bind 0.0.0.0:6666 run:app > /path/to/your/logs/gunicorn.out 2>&1 &

在这里,>是将标准输出(stdout)重定向到文件,2>&1是将标准错误(stderr)也重定向到同一个文件中。结尾的**&是将进程放到后台运行。这样做,即使SSH会话关闭,gunicorn进程也会继续运行,并且它的输出会被记录到/path/to/your/logs/gunicorn.out**文件中。

激活并启动服务:

在创建和配置好服务文件之后,以下命令将帮助您管理服务:

# 重新加载systemd以识别新的服务
sudo systemctl daemon-reload

# 启动gunicorn服务
sudo systemctl start gunicorn.service

# 设置gunicorn服务开机启动
sudo systemctl enable gunicorn.service

# 检查gunicorn服务的状态
sudo systemctl status gunicorn.service

# 查看gunicorn服务的日志
journalctl -u gunicorn.service

这样一来,您的**gunicorn**进程就会在指定的Python虚拟环境中运行,而且即使在SSH会话关闭后也能持续运行。

如何设置用户和组

确认用户和组存在

在您的**systemd服务文件中指定的用户(User)和组(Group**)应该是系统中已存在的。使用以下命令查看系统中的用户和组:

  • 查看所有用户:cat /etc/passwdgetent passwd
  • 查看所有组:cat /etc/groupgetent group

如果需要,您可以创建一个新的用户和组:

sudo adduser myuser
sudo addgroup mygroup
sudo adduser myuser mygroup

确保这个用户和组对应用程序目录和所需资源有正确的权限。

在Linux系统中,当您创建一个新用户时,默认情况下,系统会为该用户创建一个同名的用户组,并且这个用户会自动成为那个组的成员。这个默认组被称为用户的"主组"(primary group)。每个文件都有一个所有者和一个组,且新文件的默认组设置通常是其所有者的主组。

然而,如果您需要让用户属于额外的组,您需要手动将用户添加到这些组中。这就是**sudo adduser myuser mygroup命令的作用。它将用户myuser添加到组mygroup**,作为它的附加组(secondary group)。

这样做的原因可能是:

  • 权限共享:如果您希望**myuser能够访问由mygroup**组拥有的文件或目录,您需要将该用户添加到该组。
  • 应用需求:某些应用程序可能要求用户必须属于特定的组才能运行。
  • 安全控制:通过将用户分配给特定的组,您可以更细粒度地控制用户的权限,而不是给予他们更广泛的权限。

所以,最后这步**sudo adduser myuser mygroup是为了确保myuser不仅拥有其主组的权限,还能够获取其他组如mygroup的组权限。如果mygroup**是您创建的特定目的的组,您需要执行这个命令来实现这一点。如果不需要额外的组权限,这一步则不是必需的。

如何赋予用户和组对应用程序目录和所需资源有正确的权限

  1. 更改所有者: 使用 chown 命令将您的应用目录的所有权更改为正确的用户和组。

    sudo chown -R 用户名:组名 /应用目录路径
    

    替换 用户名组名 为实际的用户名和组名,/应用目录路径 为您的应用实际所在的路径。

  2. 设置权限: 使用 chmod 命令为目录设置权限。

    • 让用户有完全的权限:

      sudo chmod -R 700 /应用目录路径
      
    • 让组有读取和执行权限:

      sudo chmod -R 750 /应用目录路径
      
    • 验证权限
      使用**ls -l**命令来验证权限和所有权是否正确设置。

      ls -l /path/to/your/app
      
    • 测试权限
      切换到您的**gunicorn**用户,尝试读取和写入应用程序目录中的文件。

      sudo -u myuser -g mygroup touch /path/to/your/app/testfile
      

    如果命令执行没有错误,表示权限设置正确。

    确保在设置权限时,您明白每个权限的含义,以及为什么要分配它们。不恰当的权限设置可能会导致安全风险,特别是在生产环境中。通常,最佳实践是赋予最小必要权限,以避免潜在的安全问题。

    需要注意的是:

    root 用户在Linux系统中具有最高权限。root 能够访问和操作系统上的所有文件和命令,无论这些文件的权限设置是什么。这意味着即使一个文件的权限被设置为只允许特定用户访问,root 用户仍然可以操作这个文件。

    当您使用 root 用户时,您需要特别小心,因为具有这样的权限也意味着您能够执行任何可能对系统造成损害的操作。所以通常建议对于日常操作使用普通用户,并仅在需要进行系统级更改时使用 root 权限。

在这里插入图片描述

如何查看我的目前系统中的用户和组

您可以通过几个不同的命令在Linux系统中查看存在的用户和组。

查看用户列表:

  1. 查看**/etc/passwd**文件,这个文件包含了系统上每个用户的信息:

    cat /etc/passwd
    
  2. 使用**getent**命令:

    getent passwd
    

这些命令会列出所有用户,其中每一行代表一个用户,行中的第一个字段是用户名。

查看组列表:

  1. 查看**/etc/group**文件,这个文件包含了系统上每个组的信息:

    cat /etc/group
    
  2. 使用**getent**命令:

    getent group
    

这些命令会列出所有组,其中每一行代表一个组,行中的第一个字段是组名。

结论

无论您选择**nohup还是systemd,关键是确保您的gunicorn进程在后台稳定运行,并且能够在系统重启后自动启动。systemd提供了一个更强大和可配置的解决方案,适合生产环境。而nohup**是一个快速且简单的临时解决方案,适合开发或测试环境。请确保使用正确的用户和组,并为服务和日志文件设置适当的权限。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/135377.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FPGA高端项目:图像采集+GTX+UDP架构,高速接口以太网视频传输,提供2套工程源码加QT上位机源码和技术支持

目录 1、前言免责声明本项目特点 2、相关方案推荐我这里已有的 GT 高速接口解决方案我这里已有的以太网方案 3、设计思路框架设计框图视频源选择OV5640摄像头配置及采集动态彩条视频数据组包GTX 全网最细解读GTX 基本结构GTX 发送和接收处理流程GTX 的参考时钟GTX 发送接口GTX …

在 WSL 上启用 NVIDIA CUDA

环境要求 Windows 11 或 Windows 10 版本 21H2特定版本的GPU驱动: 安装支持 NVIDIA CUDA 的 WSL 驱动程序: https://www.nvidia.com/download/index.aspx具体安装哪个版本,查阅:https://docs.nvidia.com/cuda/wsl-user-guide/in…

基于Python+Django的图书管理系统

项目介绍 图书是人类文明传播的一个重要方式,很多历史悠久的文明都是通过图书来进行传递的,虽然随着时代的进步电子信息技术发展很快,但是纸质图书的地位仍然是非常稳固的,为了能够让知识拥有更加快捷方便的传递方式我们开发了本…

asp.net员工管理系统VS开发sqlserver数据库web结构c#编程包括出差、请假、考勤

一、源码特点 asp.net员工管理系统是一套完善的web设计管理系统(主要包括出差、请假、考勤基础业务管理),系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010 ,数据库为sqlserver2008&a…

postman设置动态token, 每次登录更新token

postman设置动态token, 每次登录更新token 文章目录 postman设置动态token, 每次登录更新token问题1. 设置全局变量2. 新建登录接口3. 设置脚本4. 切换环境5. 配置动态token 问题 token过期时间一般比较短, 每次使用postman调用接口都token非常麻烦 实现token过期后, 调用一次…

Swift 常用类别整理

生成颜色,传入16进制数字生成对应颜色 个人不喜欢传字符串的写法,比如 "0x0080FF" 或者 "0080FF",原因如下: 传了字符串最后还是要解析成数字参与颜色运算的,需要额外做字符串转数字的操作&…

人工智能领域200例教程专栏—学习人工智能的指南宝典

🎉🎊🎉 你的技术旅程将在这里启航! 🚀 本专栏:人工智能领域200例教程专栏 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 …

Kotlin基础——接口和类

接口 使用 : 表示继承关系&#xff0c;只能继承一个类&#xff0c;但可以实现多个接口override修饰符表示重写可以有默认方法&#xff0c;若父类的默认方法冲突&#xff0c;则需要子类重写&#xff0c;使用super<XXX>.xxx()调用某一父类方法 interface Focusable {fun …

Rt-Thread 移植6--多线程(KF32)

6.1 就绪列表 6.1.1 线程就绪优先级组 线程优先级表的索引对应的线程的优先级。 为了快速的找到线程在线程优先级表的插入和移出的位置&#xff0c;RT-Thread专门设计了一个线程就绪优先级组。线程就绪优先组是一个32位的整型数&#xff0c;每一个位对应一个优先级&#xff…

Spark算子

一、编写spark程序的准备工作&#xff08;程序入口 SparkContext&#xff09; 1.创建SparkConf val conf new SparkConf().setMaster("local[2]").setAppName("hello-app") 2.创建sparkContext val sc: SparkContext new SparkContext(conf) 二、基…

可视化 | echarts饼图改编

echarts模板来源 &#x1f4da;改编点 &#x1f407;基本样式 去掉legend、label&#xff1a;show: false背景透明&#xff1a;backgroundColor: "transparent"去除功能标签添加载入动态animationEasing: elasticOut, animationDelay: function (idx) {return Mat…

Python字符串字母大小写变换

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 说明&#xff1a; 字符串就是一系列字符&#xff0c;在Python中用引号括起来的都是字符串&#xff0c; 引号可以是单引号&#xff0c;也可以是双引号&#xff0…

基于猕猴感觉运动皮层的神经元Spike信号分析

公开数据集中文版详细描述参考前文&#xff1a;https://editor.csdn.net/md/?not_checkout1&spm1011.2124.3001.6192 目录 0. 公开数据集1. 神经元的raster和PSTH图1.1 Raster1.2 PSTH 2. 运动轨迹图 (center_out)3. 神经元的运动调制曲线 (tuning curve) 0. 公开数据集 …

区块链游戏,游戏开发

区块链游戏是一种基于区块链技术的新兴游戏类型&#xff0c;它具有去中心化、安全性高、透明度高、可追溯等特点。与传统的游戏开发相比&#xff0c;区块链游戏开发需要更多的技术和知识储备&#xff0c;同时也需要更加注重游戏本身的玩法和用户体验。 在区块链游戏中&#xff…

Java必刷入门递归题×5(内附详细递归解析图)

目录 1.求N的阶乘 2.求12...N的和 3.顺序打印数字的每一位 4.求数字的每一位之和 5.求斐波拉契数列 1.求N的阶乘 &#xff08;1&#xff09;解析题目意思 比如求5的阶乘&#xff0c;符号表示就是5&#xff01;&#xff1b;所以5&#xff01;5*4*3*2*1我们下面使用简单的…

ZDH-智能营销-执行流程解析

目录 项目源码 预览地址 安装包下载地址 通过2个方向解读ZDH流程图 图执行方向 数据流转方向 项目源码 zdh_web: GitHub - zhaoyachao/zdh_web: 大数据采集,抽取平台 zdh_magic_mirror: https://github.com/zhaoyachao/zdh_magic_mirror 预览地址 后台管理-登陆 用户…

C++套接字库sockpp介绍

sockpp是一个开源、简单、现代的C套接字库&#xff0c;地址为&#xff1a;https://github.com/fpagliughi/sockpp&#xff0c;最新发布版本为0.8.1&#xff0c;license为BSD-3-Clause。目前支持Linux、Windows、Mac上的IPv4、IPv6和Unix域套接字。其它*nix和POSIX系统只需很少的…

基于JavaWeb的网上体育商城的设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。你想解决的问题&#xff0c;今天给大家介绍…

Docker容器编排

文章目录 基本概念Docker ComposeSwarm分布式NodeTaskservice集群搭建弹性伸缩 基本概念 针对容器生命周期的管理&#xff0c;对容器生命周期进行更方便更快捷的方式进行管理。 依赖管理&#xff1a;当一个容器必须在另一个容器运行完成后&#xff0c;才能运行时&#xff0c;…

【Windows Docker:安装nginx】

拉镜像 docker pull nginx运行初始镜像 docker run -d -p 80:80 --name nginx nginx拷贝文件 docker cp nginx:/etc/nginx/nginx.conf D:/dockerFile/nginx/nginx.conf docker cp nginx:/etc/nginx/conf.d D:/dockerFile/nginx/conf.d docker cp nginx:/usr/share/nginx/htm…