背景
在本地做完的flask後端和vue前端工程,需要將前後端打包到服務器上去跑。
整體流程
我們平時寫前後端的時候是flask跑起來,有一個地址,例如localhost:5000
然後前端通過這個localhost:5000來和後端連接進行數據交互。同時前端再提供一個地址例如localhost:8080,打開瀏覽器進入localhost:8080就可以訪問前端的頁面。
首先是將整個後端的代碼上傳到服務器,使用gunicorn讓後端代碼跑起來;然後前端vue項目通過npm run build
打包成dist的文件夾。將這個文件夾放到服務器,然後配置nginx告訴nginx我們把這個dist文件夾放在哪裏了。
使用gunicorn是爲了讓後端遇到異常的時候不至於停下來,同時可以通過gunicorn的日誌文件查看前後端的交互情況。
服務器上有兩種接口數據交互:一種是我們本地的瀏覽器去訪問服務器前端的網頁時,需要向服務器發送頁面請求的url地址;另外一種是服務器前端向後端索要數據時傳遞的api地址。服務器上的api地址會被nginx截獲,所以我們需要配置nginx讓它知道哪些是傳給前端的地址,哪些是傳給後端的地址。
這裏需要注意兩個點:
- 後端:所有上傳到服務器的.py文件的第一行開頭都必須添加:
# coding=utf-8
注意不能寫成這種形式:
# coding = utf-8
這麼做是爲了告訴服務器上的python我們的文字編碼格式爲utf-8,不註釋這一行的話會報錯
2.前端,我們平時碼代碼的時候會使用axios設置基準路徑,這個url地址是前端和後端數據交互的地址:
使用npm run build
打包成dist文件夾之前需要將這個代碼註釋掉,因爲配置nginx的時候自身會定義地址。如果不註釋掉或刪掉這個axios路徑,後面我們是無法訪問頁面的,會顯示跨域訪問的問題。
服務器跑後端
運行
我後端flask的代碼結構如下:
其中runserver是整個後端項目的入口文件,長這個樣子:
# coding=utf-8
from application import app
if __name__ == "__main__":
app.run(
host='0.0.0.0',
debug=True)
服務器上先用python安裝gunicorn。(一般保存在/usr/local/bin路徑下)
安裝好之後,使用gunicorn啓動後端。有兩種方式,一種是直接給指令:
gunicorn -D -w 4 -b 0.0.0.0:5000 runserver:app
參數含義如下:
參數 | 含義 |
---|---|
-D | 後臺運行 |
-w 4 | 進程數量爲4 |
-b | 後端綁定的IP和端口號 |
runserver | 整個後端的啓動文件 |
app | 將該gunicorn運行的程序命名爲app |
也可以通過配置gunicorn的配置文件來運行。寫個gunicorn_conf.py(gunicorn的配置文件必須是.py結尾的文件):
# 並行工作進程數
workers = 4
# 綁定的IP和端口號
bind = '127.0.0.1:5000'
# 後臺運行
daemon = 'true'
# 設置進程文件目錄
pidfile = './/gunicorn.pid'
# 設置訪問日誌和錯誤信息日誌路徑
accesslog = './acess.log'
errorlog = './error.log'
然後通過下面的指令運行gunicorn:
gunicorn -c gunicorn_conf.py runserver:app
檢測
可以通過下面的指令查看gunicorn是否成功運行:
pstree -ap | grep gunicorn
如果後面調整了後端代碼的話需要重啓gunicorn:
kill -HUP gunicorn_pid
其中gunicorn_pid是前面通過pstree查出來的gunicorn的進程號
同時終止gunicorn的命令如下:
kill -9 gunicorn_pid
服務器加載前端
前端代碼註釋掉axios的路由路徑後,使用npm run dev
打包成dist文件,只需要將該dist文件傳到服務器即可。
然後安裝nginx,打開nginx的配置文件(一般在/etc/nginx/nginx.conf這個地方),配置如下:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
log_format access '{'
'"time": "$time_iso8601", '
'"auth_project": "$http_x_auth_project", '
'"auth_user": "$cookie_AUTH_USER", '
'"remote_addr": "$remote_addr", '
'"host": "$host", '
'"hostname": "$hostname", '
'"referer": "$http_referer", '
'"request": "$request", '
'"request_method": "$request_method", '
'"request_uri": "$uri", '
'"request_args": "$args", '
'"response_time": $request_time, '
'"size": $body_bytes_sent, '
'"status": $status, '
'"trace_id": "$http_trace_id", '
'"upstream": "$upstream_addr", '
'"proxy_host": "$proxy_host", '
'"xff": "$http_x_forwarded_for"'
'}';
access_log /var/log/nginx/access.log access;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
log_format error '{'
'"time": "$time_iso8601", '
'"auth_project": "$http_x_auth_project", '
'"auth_user": "$cookie_AUTH_USER", '
'"remote_addr": "$remote_addr", '
'"host": "$host", '
'"hostname": "$hostname", '
'"referer": "$http_referer", '
'"request": "$request", '
'"request_method": "$request_method", '
'"request_uri": "$uri", '
'"request_args": "$args", '
'"response_time": $request_time, '
'"size": $body_bytes_sent, '
'"status": $status, '
'"trace_id": "$http_trace_id", '
'"upstream": "$upstream_addr", '
'"proxy_host": "$proxy_host", '
'"xff": "$http_x_forwarded_for"'
'}';
error_log /var/log/nginx/error.log error;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
server {
listen 80;
server_name localhost;
#root /home/zhouxianming/html;
#index index.html;
location / {
root /path/to/your/dist/file;
index index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:5000;
}
}
}
比較主要的配置是這個地方:
當nginx檢測到/api/開頭的路由請求會發送給後端(服務器監聽5000端口)
當nxinx檢測到其他的路由請求時,會發送給前端的文件dist。
如果前端重寫,重新生成上傳了dist文件,需要重新加載一下nginx:
nginx -r reload
主要涉及到的指令
gunicorn
gunicorn -c gunicorn_conf.py runserver:app
gunicorn -D -w 4 -b 0.0.0.0:5000 runserver:app
pstree -ap | grep gunicorn
kill -HUP gunicorn_pid
kill -9 gunicorn_pid
nginx
sudo nginx
service nginx start
sudo service nginx restart
sudo nginx -s reload
sudo nginx -s stop
ps aux | grep nginx
查看所有IP、端口的使用情況
sudo nestat -tulpn