nginx搭建基于python的web環(huán)境的實現(xiàn)步驟
前言:
在搭建開始前,我們先來梳理下web服務(wù)工作流程,先看下圖:
1、用戶(PC)向web服務(wù)器發(fā)起http請求
2、web服務(wù)器判斷用戶請求文件是否為靜態(tài)文件,是則直接讀取靜態(tài)文件并返回給用戶,不是則通過WSGI協(xié)議將請求丟給web框架(django)代碼處理
3、看web框架是否啟動django中間件,如果啟用,則依據(jù)中間件對請求進行修改,如果不啟用,則進入下一步
4、web框架中的路由程序?qū)⒏鶕?jù)請求中的url文件名將請求路由至相應py文件
5、相應py文件收到請求后根據(jù)用戶提交的參數(shù)進行計算(期間可能會調(diào)用數(shù)據(jù)庫),然后返回計算后的結(jié)果和自定義頭部信息以及狀態(tài)碼返回
6、web框架將返回的數(shù)據(jù)打上通用標識符(頭部信息)后返回給web服務(wù)器
7、web服務(wù)器打上web服務(wù)器的通用標識符(頭部信息)后返回給用戶
8、用戶收到返回的數(shù)據(jù)
通過上面可以看到django框架基于WSGI協(xié)議和web服務(wù)器進行交互,那么WSGI協(xié)議又是什么呢? 咱們用代碼來說明(偽代碼。寫一個簡易的遵循WSGI協(xié)議的web服務(wù)器軟件和django程序):
WSGI服務(wù)器的程序:
class WSGI_WEB(object): def __init__(self): # 1. 創(chuàng)建套接字 self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 2. 綁定 self.tcp_server_socket.bind(("", 7890)) # 3. 變?yōu)楸O(jiān)聽套接字 self.tcp_server_socket.listen(128) def set_response_header(self, status, headers): self.status = status self.headers = [("server", "WSGI_simple_web v1.0")] self.headers += headers def run(self): new_socket, client_addr = self.tcp_server_socket.accept() env = new_socket.recv(1024) body = application(env, set_response_header) # env是web服務(wù)器接收到瀏覽器發(fā)送來的數(shù)據(jù)包;set_response_header為web服務(wù)器的一個方法地址,目的是讓django幫web服務(wù)器生成http頭部(不是以return的形式給web服務(wù)器);此外還有這里調(diào)用django里的應用還有一個最核心的任務(wù),就是獲取返回數(shù)據(jù)的body! header = self.status + self.headers response = header + body new_socket.send(response.encode("utf-8"))
django的app程序:
def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return [b"Hello World"]
問題:
在生產(chǎn)環(huán)境中使用django提供的簡易web服務(wù)器性能太差,一般只用于調(diào)試。強大的nginx又不支持WSGI,那么怎么辦呢?
方案:
在nginx和python應用之間加一層支持WSGI協(xié)議的web服務(wù)器。以后靜態(tài)文件由nginx進行處理,動態(tài)文件丟給WSGI服務(wù)器,然后WSGI服務(wù)器再丟給web框架處理。最理想的支持WSGI協(xié)議的web服務(wù)器就是uWSGI。
下面來詳細介紹下搭建uWSGI服務(wù)器以及與nginx聯(lián)動的方法:
1、安裝uWSGI(支持WSGI的WEB服務(wù)器):
centos下python3.6安裝uWSGI方法:
yum install -y gcc* pcre-devel openssl-devel python36-devel.x86_64 pip3.6 install uwsgi
2、開啟uWSGI服務(wù)
方式一:
uwsgi --http 192.168.31.123:80 --file teacher/wsgi.py --static-map=/static=static --http 監(jiān)聽IP端口 --file 項目wsgi.py文件路徑 --static-map 靜態(tài)文件路徑
注意: 執(zhí)行這條命令的時候:一定要在這個項目目錄中~
方式二(使用配置文件):
vi uwsgi.ini: [uwsgi] # 監(jiān)聽端口(nginx采用反向代理模式時必填) http = 0.0.0.0:8888 # 項目目錄 chdir=/opt/test/test1/ # 啟動uwsgi的用戶名和用戶組 uid=root gid=root # 指定項目的application(我猜是這里的“test1.wsgi”拼接上面的項目目錄后,就將項目中的wsgi.py文件和uWSGI服務(wù)器關(guān)聯(lián)起來了) module=test1.wsgi:application # 指定sock的文件路徑(nginx采用本地模式時必填) socket=/opt/test/script/uwsgi.sock # 啟用主進程 master=true # 進程個數(shù) workers=5 pidfile=/opt/test/script/uwsgi.pid # 自動移除unix Socket和pid文件當服務(wù)停止的時候 vacuum=true # 序列化接受的內(nèi)容,如果可能的話 thunder-lock=true # 啟用線程 enable-threads=true # 設(shè)置自中斷時間 harakiri=30 # 設(shè)置緩沖 post-buffering=4096 # 設(shè)置日志目錄 daemonize=/opt/test/script/uwsgi.log # 設(shè)置隔多久加載一次項目代碼 py-autoreload=1 執(zhí)行配置文件(注意:這里用什么賬戶執(zhí)行的,以后滲透進來獲取到的就是什么賬戶。所以這一步切忌不要用root執(zhí)行。): uwsgi --ini uwsgi.ini
彩蛋:
重啟uWSGI進程: uwsgi --reload uwsgi.pid # 代碼做變更后uWSGI進程不會立即加載,此時可以重啟一下uWSGI進程讓它生效。。。是不是感覺有點坑,沒事,可以在配置文件中設(shè)置py-autoreload 關(guān)閉uWSGI進程: uwsgi --stop uwsgi.pid
3、配置nginx
方式一(反向代理模式):
upstream uwsgi{ server 10.10.10.29:8888; } server { listen 80; server_name localhost; #charset koi8-r; #access_log /var/log/nginx/host.access.log main; location / { proxy_pass http://uwsgi; # 通過反向代理和uWSGI服務(wù)器關(guān)聯(lián) } }
方式二(本地模式):
server { listen 8080; server_name localhost; #charset koi8-r; #access_log /var/log/nginx/host.access.log main; location / { include uwsgi_params; # 指定nginx和uWSGI服務(wù)器的通信方式 uwsgi_connect_timeout 30; uwsgi_pass unix:/opt/test/script/uwsgi.sock; # 通過sock文件和uWSGI服務(wù)器關(guān)聯(lián)! 因為nginx會去讀取.sock文件,所以需要關(guān)閉selinux才行?。。? } }
4、此時訪問django的admin管理后臺時,靜態(tài)資源會調(diào)取失敗。這時可以將該項目所有靜態(tài)資源統(tǒng)一收集到一個文件夾下,然后由nginx統(tǒng)一去調(diào)取,真正做到動靜分離(動的給uWSGI,靜的由nginx直接調(diào)取):
在settings.py中加入:
TATIC_ROOT = os.path.join(BASE_DIR, 'static_file')
執(zhí)行如下命令(搜集項目中所有靜態(tài)文件至'static_file'目錄):
python3.6 manage.py collectstatic --noinput
此時會在項目目錄下生成一個'static_file'文件夾,內(nèi)含admin和所有app涉及的靜態(tài)文件 。
在nginx中配置靜態(tài)文件路徑(如果nginx和uWSGI不屬同一臺服務(wù)器可以使用反向代理的方式來調(diào)取靜態(tài)文件):
location /static/ { alias /opt/test/test1/static_file/; }
此時就可以訪問基于python后臺的web網(wǎng)站了
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- Docker構(gòu)建python Flask+ nginx+uwsgi容器
- 淺析python 定時拆分備份 nginx 日志的方法
- python實現(xiàn)的分析并統(tǒng)計nginx日志數(shù)據(jù)功能示例
- python監(jiān)控nginx端口和進程狀態(tài)
- Python開發(fā)之Nginx+uWSGI+virtualenv多項目部署教程
- Python運維自動化之nginx配置文件對比操作示例
- 詳解python使用Nginx和uWSGI來運行Python應用
- Python的Flask框架及Nginx實現(xiàn)靜態(tài)文件訪問限制功能
- 在阿里云服務(wù)器上配置CentOS+Nginx+Python+Flask環(huán)境
- python 檢測nginx服務(wù)郵件報警的腳本
相關(guān)文章
python中pandas.DataFrame的簡單操作方法(創(chuàng)建、索引、增添與刪除)
這篇文章主要介紹了python中pandas.DataFrame的簡單操作方法,其中包括創(chuàng)建、索引、增添與刪除等的相關(guān)資料,文中介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。2017-03-03使用Django開發(fā)簡單接口實現(xiàn)文章增刪改查
這篇文章主要介紹了使用Django開發(fā)簡單接口實現(xiàn)文章增刪改查,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-05-05OpenCV-Python使用分水嶺算法實現(xiàn)圖像的分割與提取
在圖像的處理過程中,經(jīng)常需要從圖像中將前景對象作為目標圖像分割或者提取出來。本文就介紹了使用分水嶺算法實現(xiàn)圖像的分割與提取,感興趣的可以了解一下2021-06-06python 調(diào)用win32pai 操作cmd的方法
下面小編就為大家?guī)硪黄猵ython 調(diào)用win32pai 操作cmd的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05python算法測試結(jié)果自動保存到excel表格的實現(xiàn)步驟
我們在進行算法評估是通常會針對每個樣本的算法處理結(jié)果進行統(tǒng)計,例如每個樣本正確預測數(shù)量、漏檢數(shù)量和誤檢數(shù)量、精度等,本文小編將給大家介紹python算法測試結(jié)果自動保存到excel表格的實現(xiàn)步驟,感興趣的朋友可以參考下2023-12-12