最近由于因為課程要求,使用nginx部署一個基于Django的網(wǎng)站。部署流程官網(wǎng)上寫的很詳細(xì)了,但由于剛開始對nginx不太熟悉,在部署的時候還是遇到一些坑的,于是在這里做一總結(jié)與分享。
0x00 What is nginx?
第一個坑就是什么是nginx,nginx是一個反向代理服務(wù)器(Reverse Proxy),那么問題來了,什么是反向代理服務(wù)器呢?大家可能對代理服務(wù)器都不陌生,比如當(dāng)你需要訪問一些不(bei)存(qiang)在的網(wǎng)站的時候,可能就會用到代理服務(wù)器,繞過阻礙,到達(dá)目的地。在這個過程中,代理服務(wù)器是代替客戶訪問網(wǎng)站的服務(wù)器,也許稱作「代理客戶」更容易理解,客戶是在「代理客戶」的后面。而反向代理則是代替網(wǎng)站服務(wù)器最先接受客戶的訪問,網(wǎng)站服務(wù)器是在「代理服務(wù)器」的后面。上圖非常直觀說明了反向代理服務(wù)器的原理。
0x01 Why nginx?
簡單來說,使用反向代理服務(wù)器的優(yōu)勢除了安全上的考慮之外,主要就是性能上的考慮。nginx主要負(fù)責(zé)處理靜態(tài)文件,當(dāng)客戶頻繁訪問靜態(tài)文件的時候就會影響后端服務(wù)器的響應(yīng),這里就可以考慮使用nginx作為靜態(tài)文件的緩存服務(wù)器,之前被客戶訪問過的靜態(tài)文件就可以由nginx服務(wù)器直接返回給客戶,從而減少對后端服務(wù)器的http請求,達(dá)到提高整體性能的目的。
0x02 uWSGI vs WSGI
首先,WSGI是python定義的Web服務(wù)器網(wǎng)管接口(Web Service Gateway Interface),它定義了web服務(wù)器如何跟web框架(如Django)交互規(guī)則,而uWSGI則是WSGI規(guī)則下的一個實現(xiàn),同樣在WSGI規(guī)則下的實現(xiàn)還有CherryPy等,簡單來說,WSGI是一套協(xié)議,而uWSGI則是協(xié)議的實現(xiàn)。在這里,uWSGI扮演了nginx與Django之間通信的通道:
client <-> nginx <-> uWSGI <-> Django
0x03 Tips
Virtualen
Virtualenv是一個非常好用的工具,可以讓你的某個項目的python依賴環(huán)境與主機的環(huán)境隔離。使用virtualenv有助于不同項目之間依賴的隔離,同時也方便項目復(fù)用以及團隊協(xié)作。常用的命令如下:
創(chuàng)建一個新的環(huán)境(在當(dāng)前目錄下):
$ virtualenv env
激活某個環(huán)境:
$ source env/bin/activate
將當(dāng)前依賴文件導(dǎo)出:
$ pip freeze > requirement.txt
依賴文件導(dǎo)入:
$ pip install -r requirement.txt
更加詳細(xì)的使用可以參見官方文檔。
Shell Script
啟動配置網(wǎng)站的參數(shù)太難記了,程序員都是懶人,懶人就要有懶人的方法,干脆就寫一個腳本自動化部署吧。腳本很簡單易用,在這里共享給大家:
if [ ! -n "$1" ]
then
echo "Usages: sh uwsgiserver.sh [start|stop|restart]"
exit 0
fi
if [ $1 = start ]
then
psid=`ps aux | grep "zh" | grep -v "grep" | wc -l`
if [ $psid -gt 4 ]
then
echo "uwsgi is running!"
exit 0
else
uwsgi --ini /path/to/your/uwsgi.ini
echo "Start uwsgi service [OK]"
fi
elif [ $1 = stop ];then
killall -s INT /home/ubuntu/.virtualenvs/zh/bin/uwsgi
echo "Stop uwsgi service [OK]"
elif [ $1 = restart ];then
killall -s INT uwsgi
uwsgi --ini /path/to/your/uwsgi.ini
echo "Restart uwsgi service [OK]"
else
echo "Usages: sh uwsgiserver.sh [start|stop|restart]"
fi
Error.log
nginx提供了非常強大的日志功能,通過查看日志可以迅速發(fā)現(xiàn)問題,例如:
$ tail -1 /var/log/nginx/error.log
2015/11/17 23:30:44 [crit] 13983#0: *86821 connect() to unix:///tmp/website.sock failed (2: No such file or directory) while connecting to upstream, client: 61.160.213.32, server: 128.199.67.228, request: "GET http://zc.qq.com/cgi-bin/chs/numreg/init? HTTP/1.0", upstream: "uwsgi://unix:///tmp/website.sock:", host: "zc.qq.com"
這里可以發(fā)現(xiàn).sock文件的路徑出錯導(dǎo)致網(wǎng)站無法訪問。
nginx還可以配置日志的路徑已經(jīng)格式,更多資料可以參看nginx官網(wǎng)
0x04 總結(jié)
雖然是個簡單的課程作業(yè),簡單使用nginx部署Django,但在這個過程中學(xué)習(xí)了很多有關(guān)運維的知識,深深體會到運維工程師工作的艱辛。雖然將來不會從事運維方面的工作,但作為一個有追求的程序員還是要了解服務(wù)器的工作原理,典型的網(wǎng)絡(luò)框架,以及部署網(wǎng)站的一些技巧。生命不息,折騰不止~