Nginx+Gunicorn+Supervisor 部署 FastApi 项目

部署准备

  1. 有一台已经解析过域名的服务器,没有的话只能通过Ip访问项目。
  2. 安装了Gunicorn的虚拟环境,采用虚拟环境可以保障环境稳定性。
    采用conda创建虚拟环境:
    1.创建一个名为py3.6,版本为3.6的虚拟环境
        conda create --name py3.6 python=3.6
    2.进入虚拟环境:
        source activate py3.6
    3.安装gunicorn
        pip install gunicorn
    

3.确保你的项目在当前虚拟环境下可以正常运行。

使用gunicorn启动项目

1.在项目根目录,执行下面的命令启动服务,项目为FastAPI 项目:

```
gunicorn API_2_1_4:app -w 2 -k gthread --timeout 30 -b 0.0.0.0:8000
```

来解释一下各个参数的含义。
  • -w 2 表示启动 2 个 worker 用于处理请求(一个 worker 可以理解为一个进程),通常将 worker 数目设置为 CPU 核心数的 2-4 倍。

  • -k gthread 指定每个 worker 处理请求的方式,根据大家的实践,指定为 gthread 的异步模式能获取比较高的性能,因此我们采用这种模式。

  • -b 0.0.0.0:8000,将服务绑定到 8000 端口,运行通过公网 ip 和 8000 端口访问应用。

访问 ip:8000(ip 为你服务器的公网 ip),应用成功访问了,如果是flask或django项目,你可能要在此处收集静态文件,FastAPI 项目不需要。

Nginx 服务器

1.首先安装 Nginx:

yum install epel-release -y
yum install nginx -y

2.启动 Nginx 服务:

systemctl start nginx

3.配置nginx:

  • Nginx 的配置位于 /etc/nginx/nginx.conf 文件中,你可以打开这个文件看看里面的内容。
http
    {
        include       mime.types;
		#include luawaf.conf;

		include proxy.conf;

        default_type  application/octet-stream;

        server_names_hash_bucket_size 512;
        client_header_buffer_size 32k;
        large_client_header_buffers 4 32k;
        client_max_body_size 50m;

        sendfile   on;
        tcp_nopush on;

        keepalive_timeout 60;

        tcp_nodelay on;

        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
        fastcgi_buffer_size 64k;
        fastcgi_buffers 4 64k;
        fastcgi_busy_buffers_size 128k;
        fastcgi_temp_file_write_size 256k;
		fastcgi_intercept_errors on;

        gzip on;
        gzip_min_length  1k;
        gzip_buffers     4 16k;
        gzip_http_version 1.1;
        gzip_comp_level 2;
        gzip_types     text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
        gzip_vary on;
        gzip_proxied   expired no-cache no-store private auth;
        gzip_disable   "MSIE [1-6]\.";

        limit_conn_zone $binary_remote_addr zone=perip:10m;
		limit_conn_zone $server_name zone=perserver:10m;

        server_tokens off;
        access_log off;
    
    server
        {
            listen 888;
            server_name phpmyadmin;
            index index.html index.htm index.php;
            root  /www/server/phpmyadmin;
    
            #error_page   404   /404.html;
            include enable-php.conf;
    
            location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
            {
                expires      30d;
            }
    
            location ~ .*\.(js|css)?$
            {
                expires      12h;
            }
    
            location ~ /\.
            {
                deny all;
            }
    
            access_log  /www/wwwlogs/access.log;
        }
    # 导入自定义模块
    include /etc/nginx/conf.d/*.conf;
}
  • http 配置下有一个 server 模块,server 模块用于配置一个虚拟服务,使这个虚拟服务监听指定的端口和域名。你可以配置多个 server,这样就会启动多个虚拟服务,用于监听不同端口,或者是同一个端口,但是不同的域名,这样你就可以在同一服务器部署多个 web 应用了。

  • 为了模块化管理,我们将配置写到 /etc/nginx/conf.d/ 目录下。先在服务器的 conf.d 目录下新建一个配置文件,我把它叫做 fastapi.conf。

    server {
        charset utf-8;
        listen 80;
        server_name mytest.com 公网IP;

        location / {
            proxy_set_header Host $host;
            proxy_pass http://127.0.0.1:8000;
        }
    }
  • 首先我们配置了一个虚拟服务,编码方式为 utf-8,监听于 80 端口。

  • 服务的域名为 mytest.com,所有来自这个域名的请求都会被这个服务所处理。

  • 请求转发给运行在本机 8000 端口的应用程序处理,我们会在这个端口启动 Gunicorn 用于处理 Nginx 转发过来的请求。

4.重启 nginx 使得配置生效:

systemctl restart nginx

5.域名访问

  • 现在,访问配置的域名 mytest.com 就可以看到项目了。

管理 Gunicorn 进程

  1. 现在 Gunicorn 是我们手工启动的,一旦我们退出 shell,服务器就关闭了,服务就无法访问。就算在后台启动 Gunicorn,万一哪天服务器崩溃重启了又得重新登录服务器去启动,非常麻烦。为此使用 Supervisor 来管理 Gunicorn 进程,这样当服务器重新启动或者 Gunicorn 进程意外崩溃后,Supervisor 会帮我们自动重启 Gunicorn。
  2. 安装 Supervisor
pip install supervisor
  1. supervisor 目录结构
(py3.6) [root@iZbp11gqesu0znu7pkmgp7Z etc]# tree
.
├── supervisor
│   ├── conf.d
│   │   └── fig1.ini
│   └── var
│       ├── log
│       │   ├── supervisord.log
│       │   ├── wenda-stderr.log
│       │   ├── wenda-stdout.log
│       │   └── wenda-stdout.log.1
│       ├── supervisord.pid
│       └── supervisor.sock
└── supervisord.conf

4 directories, 8 files
  • 其中 supervisord.conf 是 Supervior 的配置文件,它会包含 conf.d 下的配置。var 目录下用于存放一些经常变动的文件,例如 socket 文件,pid 文件,log 下则存放日志文件。
  • 首先来建立上述的目录结构:
mkdir -p ~/etc/supervisor/conf.d
mkdir -p ~/etc/supervisor/var/log
  • 然后进入 ~/etc 目录下生成 Supervisor 的配置文件:
cd ~/etc
echo_supervisord_conf > supervisord.conf
  • 修改 supervisor.conf,让 Supervisor 进程产生的一些文件生成到上面我们创建的目录下,而不是其默认指定的地方。

    • 首先找到 [unix_http_server] 版块,将 file 设置改为如下的值,即让 socket 文件生成在 ~/etc/supervisor/var/ 目录下。注意 supervisor 不支持将 ~ 展开为用户 home 目录,所以要用绝对路径指定。:
    [unix_http_server]
    file=/root/etc/supervisor/var/supervisor.sock
    
    • 类似的修改 [supervisord] 板块下的 logfile 和 pidfile 文件的路径,还有 user 改为系统用户,这样 supervisor 启动的进程将以系统用户运行,避免可能的权限问题:
    [supervisord]
    logfile= /root/etc/supervisor/var/log/supervisord.log 
    pidfile=/root/etc/supervisor/var/supervisord.pid 
    user=root
    
    • [supervisorctl] 板块下:
    [supervisorctl]
    serverurl=unix:///root/etc/supervisor/var/supervisor.sock
    
    • [include] 版块,将 /home/yangxg/etc/supervisor/conf.d/ 目录下所有以 .ini 结尾的文件内容包含到配置中来,这样便于配置的模块化管理,和之前 Nginx 配置文件的处理方式是类似的。
    [include]
    files = /root/etc/supervisor/conf.d/*.ini
    
  • 然后我们到 conf.d 新建应用的配置

    (py3.6) [root@iZbp11gqesu0znu7pkmgp7Z conf.d]# cat fig1.ini
    [program:wenda_slmx]
    command=gunicorn API_2_1_4:app -w 2 -k gthread  --timeout 30 -b 0.0.0.0:8000
    directory=/www/wwwroot/solomon_wenda_20201105/
    autostart=true
    autorestart=unexpected
    user=root
    stdout_logfile=/root/etc/supervisor/var/log/wenda-stdout.log
    stderr_logfile=/root/etc/supervisor/var/log/wenda-stderr.log
    

    各项配置的含义:

      [program:wenda_slmx] 指明运行应用的进程,名为 wenda_slmx。
      
      command 为进程启动时执行的命令。
      
      directory 指定执行命令时所在的目录。
      
      autostart 随 Supervisor 启动自动启动进程。
      
      autorestart 进程意外退出时重启。
      
      user 进程运行的用户,防止权限问题。
      
      stdout_logfile,stderr_logfile 日志输出文件。
    
  • 启动 Supervisor

    supervisord -c ~/etc/supervisord.conf
    
    • -c 指定 Supervisr 启动时的配置文件。
    • 更新新的配置到supervisord
    supervisorctl update
    
    • 重新启动配置中的所有程序
    supervisorctl reload
    
  • 浏览器输入域名,可以看到服务已经正常启动了。

Nginx+Gunicorn+Supervisor 部署 FastApi 项目

上一篇:C#总结:.NET, 数据类型, 访问修饰符, 各部分的定义(一)


下一篇:C# Span 源码解读和应用实践