部署准備
- 有一台已經解析過域名的服務器,沒有的話只能通過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
-
瀏覽器輸入域名,可以看到服務已經正常啟動了。