簡介
uwsgi是中間件,用于連接Flask與nginx,nginx會監聽服務器接口,接收用戶的請求,然后將該請求反向代理給uwsgi,uwsgi再將請求發送給與之連接的Flask服務器實例。
環境搭建的簡單流程。
Flask相關
1.創建目錄 /home/flaskcode
2.將flask項目放入該目錄
3.構建python環境,這里使用virtualenv來構建環境,如下:
virtualenv venv (創建名為venv的虛擬環境)
>> New python executable in venv/bin/python
>> Installing setuptools, pip...done.
source venv/bin/activate (進入虛擬環境)
pip install uwsgi
pip install flask
pip install requests
pip install pymysql
嘗試運行flask項目
python agent.py
nginx相關
1.安裝nginx,ubuntu使用apt-get
apt-get install nginx
2.測試使用一下
/etc/init.d/nginx start #啟動
訪問127.0.0.1
nginx配置
ubuntu下通過apt-get安裝的nginx配置文件為 /etc/nginx/sites-enabled/default
,一個軟連接
vim /etc/nginx/sites-enabled/default
該文件最總會被include進入nginx的主配置文件中。
將配置文件中server的內容進行如下替換:
server { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
listen 80; ? ? ? ? ? ? ? ? ? # 服務器監聽端口 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
server_name 127.0.0.1; # 這里寫你的域名或者公網IP,測試時可使用127.0.0.1本地詢回地址 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
charset ? ? ?utf-8; ? ? ? ? ?# 編碼 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
client_max_body_size 75M; ? ?# 之前寫的關于GET和POST的區別,這里應該是原因之一吧 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
location / { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ?include uwsgi_params; ? ? ? ? # 導入uwsgi配置 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ?uwsgi_pass 127.0.0.1:8000; ? ?# 轉發端口,需要和uwsgi配置當中的監聽端口一致 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ?uwsgi_param UWSGI_PYTHON /home/自己創建的目錄/venv; ? ? ? # Python解釋器所在的路徑(這里為虛擬環境) ?
? ?uwsgi_param UWSGI_CHDIR /home/自己創建的目錄; ? ? ? ? ? ? # 項目根目錄 ? ?
? ?uwsgi_param UWSGI_SCRIPT agent:app; #比如你測試用test.py文件,文件中app = Flask(__name__),那么這里就填 ?test:app ? ? ? ? ? ? ? ? ? ? ? ?
} ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
}
重啟nginx
/etc/init.d/nginx restart
nginx中通過參數uwsgi_pass設置的地址進行請求轉發,將UWSGI也設置為該地址則可
centos7通過yum安裝的nginx,其配置文件為nginx.conf,這次我們直接修改主配置文件,之所以折騰完ubuntu又折騰centos7是因為公司需要……
因為centos7的yum默認是沒有nginx的,所以要添加相應的源,如下:
將Nginx添加到yum
sudo yum install epel-release
安裝Nginx
sudo yum install nginx
啟動Nginx
sudo systemctl start nginx
如果您正在運行防火墻,請運行以下命令以允許HTTP和HTTPS通信
sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload
需要在系統啟動時啟用Nginx,即開機自啟,命令如下:
sudo systemctl enable nginx
其主配置文件如下:
/etc/nginx/nginx.conf
配置內容跟ubuntu一樣,需要注意的一個坑是,使用yum安裝的nginx要想成功鏈接uwsgi還需要配置一下,因為yum安裝后,nginx的權限不是root,而我們后面創建uwsgi時,因為使用的root用戶再操作,所以創建文件的權限也會是root,此時nginx就無法直接把其調起。
這里講centos7系統中的selinux(安全模式)關閉則可(不知道會不會造成線上安全的等問題),修改selinux相關配置,如下
vi /etc/selinux/config
#SELINUX=enforcing #注釋掉
#SELINUXTYPE=targeted #注釋掉
SELINUX=disabled #增加
:wq! #保存退出
setenforce 0 #使配置立即生效
這樣selinux就不會阻止nginx調用uwsgi。自己遇到這個問題時,查看了nginx的報錯日志,發現nginx被權限拒絕,查了nginx會被權限拒絕的資料得到的解決方案,親測可行。
如果不知系統中nginx被安裝在哪或nginx相關的配置文件被放置在哪?可以使用find命令,如下
find / -name nginx
這樣find就可以搜索全局與nginx相關的文件目錄,之所以是全局是配置時,使用的范圍是 /
UWSGI配置
在Flask項目的根目錄下創建 uwsgi.ini
文件
uwsgi.ini
內容如下:
[uwsgi] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
socket = 127.0.0.1:8000 ? ? ? ? ? ? # uwsgi的監聽端口,與Nginx中配置相同 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
plugins = python ? ? ? ? ? ? ? ? ? ?# 這行一定要加上,不然請求時會出現-- unavailable modifier requested: 0 --錯誤提示 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
chdir = /home/flaskcode ? ? ? ? ? ? ? ?# 項目根目錄 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
wsgi-file = agent.py ? ? ? ? ? ? ? # flask程序的啟動文件,即app.run()所在文件 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
callable = app ? ? ? ? ? ? ? ? ? ? ?# 程序變量名
使用uwsgi啟動一下該文件,其實就是配置文件,以文件的形式存儲uwsgi的參數,方便使用
uwsgi --ini uwsgi.ini
Flask+uwsgi+nginx配置完成
nginx配置修改
因為公司需求,需要對多個不同域名請求都做相應,具體而言,公司服務器A具有唯一的IP,但有多個域名與該IP有對應關系,如 m1.test.com
、 m2.test.com
...等多個域名都對應著服務器A,要做的是,用戶范圍不同連接時,該服務器根據不同的鏈接URL請求不同的資源服務器,即服務器A簡單而言就是做個中轉。一開始考慮時自己想復雜了,往分布式架構那么想了,即nginx配置多個虛擬主機,具體而言就是nginx.conf中配置多個server主體,每個主體映射不同的主機,但其實這種需求并不需要使用分布式。
簡單而言,配置一下nginx,讓它可以響應多個域名的請求,再將請求發送給uwsgi則可,即uwsgi實例與Flask實例都是唯一的,其實只需要修改nginx的server_name字段,該字段表明要響應的請求,一開始我們設置為127.0.0.1,這里修改成相應的域名,該字段是支持正則的,具體如下:
server_name m*.test.com localhost;
這里加個localhost是為了方便測試,當然要測 m*.test.com
怎么測?因為需求時要更加這個地址讓服務器請求不同的資源,那么服務器代碼中的邏輯當然有處理 m*.test.com
的邏輯,如果報錯這部分邏輯沒問題。
兩個簡單的辦法,一是假設法,即設置一個url變量,該變量的值為 m1.test.com
,將其看成是Flask從請求中獲得的鏈接,從而驗證自己的邏輯。
如果想連nginx這樣配置是否可以行都驗證一下,那就修改一下本地的hosts文件,本地的hosts其實就是本地的DNS,修改它,將m1.test.com對應的IP改為服務器的IP,如下:
192.168.146.129 m1.test.com
192.168.146.129 m2.test.com
需要注意的是,hosts中的配置時不允許有端口的,即 192.168.146.129:5000
這樣配置hosts是無法生效的,我這里的服務器A是我本地VMWare安裝的centos7虛擬機,所以地址是私網地址,windows中要讓修改后的hosts立即生效,命令如下:
ipconfig /displaydns
ipconfig /flushdns
windows開發各種坑還是比較心累的,有條件的就趕緊棄了吧╮(╯▽╰)╭
這樣你就可以直接通過瀏覽器訪問m1.test.com了,實質上依舊是訪問192.168.146.129,ping一下這個域名就知道。
debug
配置過程中報錯解決思路,使用排除法。
如果配置了沒有效果,看本地機子與服務器A直接能否ping通,不可,則要關閉一下兩邊的服務器。
Flask配置了host=0.0.0.0,依舊不可外網訪問,最有可能的原因就是你的代碼在其他地方同樣導入的配置,因為我配置的Flask代碼是組長寫的,所以被坑了,因為將其配置一行注釋掉就好了,沒想到其他地方還導入了相關的配置。
進程監控
單獨一個uwsgi程序運行長時間可能面臨崩潰,所以配合使用supervisor對uwsgi進程簡單控制。
Supervisor:python編寫的進程管理工具,可以很方面的啟動、重啟、關閉進程,可以使用與任意進程,不僅是python進程
1.安裝,pip或apt-get均可安裝
apt-get install supervisor
或
pip install supervisor
2.配置supervisor
下面內容使用的supervisor是通過apt-get安裝的
supervisor有默認的全局配置文件,通常不修改它,而是生成新的配置文件進行配置
echo_supervisord_config > /Flask項目根目錄/supervisord.conf
生成在Flask項目根目錄方便管理
vim編輯該文件
vim supervisord.conf
vim進入文件末尾,命令為:
:$
添加如下內容:
[program:flaskcode] ? ? ? ? ?# project_name這里寫上你的項目名稱,即項目根目錄名
command = uwsgi --ini /Flask項目路徑/uwsgi.ini ?# 跟手動啟動的命令一樣
stopsignal=QUIT
autostart=true
autorestart=true
stdout_logfile=/Flask項目目錄/log/supervisor_out.log ? ? ?# 運行日志
stderr_logfile=/Flask項目目錄/log/supervisor_err.log ?# 錯誤日志
在Flask項目下使用mkdir創建log目錄,用于存放supervisor生成的日志文件
3.使用
重啟supervisor
sudo supervisord -c supervisord.conf
ubuntu虛擬機開啟supervisord效果如下,通過killall uwsgi關閉uwsgi程序,就會立刻被supervisord重啟開啟
4.supervisor相關命令
手動啟動:
supervisord -c supervisord.conf
手動關閉supervisord啟動的所有服務:
supervisordctl stop all
結尾
在公司使用自己熟悉的環境工作效率會提升很多,必須吐槽一下,一開始不想裝虛擬機,因為centos7的鏡像4GB多,下載也要挺久的,而在公司做了網絡限制,超量會被限速,這就更蛋疼了,叫組長給我弄了臺公司的測試服,不料,不怎么會用上古系統redhat4,各種配置坑,我已經不年輕了,不想折騰了,所以才屈服下載centos7與ubuntu 16.04的鏡像進行上述的配置。