部署准备
- 有一台已经解析过域名的服务器,没有的话只能通过Ip访问项目。
- 安装了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 进程
- 现在 Gunicorn 是我们手工启动的,一旦我们退出 shell,服务器就关闭了,服务就无法访问。就算在后台启动 Gunicorn,万一哪天服务器崩溃重启了又得重新登录服务器去启动,非常麻烦。为此使用 Supervisor 来管理 Gunicorn 进程,这样当服务器重新启动或者 Gunicorn 进程意外崩溃后,Supervisor 会帮我们自动重启 Gunicorn。
- 安装 Supervisor
pip install supervisor
- 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
-
浏览器输入域名,可以看到服务已经正常启动了。