背景:最近打算自己寫一個小網(wǎng)站狭魂,接口不多阅茶,就打算用Django來寫了被廓,正好提升一下自己的python的代碼水平坏晦。這篇博客主要是用來記錄從本地運行到部署服務(wù)器這過程遇到的一些小問題。
提示:
如果是阿里云的服務(wù)器嫁乘,我們要去阿里云的后臺管理業(yè)去配置安全規(guī)則昆婿,開放我們即將要使用的那些端口的權(quán)限,他很多的端口都是默認(rèn)不開放的蜓斧。
Djano簡單介紹
我使用的IDE是PyCharm仓蛆,操作簡單,可直接創(chuàng)建Django項目挎春,然后python版本選擇3.x看疙。
簡單的說兩句Django。這個框架個人感覺上手容易直奋,畢竟框架做了比較好的分層能庆,不同文件的只能劃分也是很明確的,當(dāng)然里面涉及一些配置參數(shù)什么的脚线,這個大家可以去網(wǎng)上找Django的教程搁胆,先看看入門。
在目錄結(jié)構(gòu)中我們可以看到一個venv的文件邮绿,這個算是給我們創(chuàng)建的一個虛擬環(huán)境渠旁,為應(yīng)用提供了隔離的Python運行環(huán)境,解決了不同應(yīng)用間多版本的沖突問題斯碌。這個大家可以自己去查一下加深理解。
在本地敲代碼的時候肛度,使用到某些庫的時候我們會使用 pip install xxxxx 來安裝傻唾。使用了venv這種虛擬環(huán)境,所有的包默認(rèn)安裝在本項目下承耿,新的項目使用的話需要再安裝冠骄。
前期的本地工作就沒什么了,從網(wǎng)上找到教程一點一點的學(xué)習(xí)就可以了加袋。當(dāng)然了凛辣,我們要準(zhǔn)備部署到服務(wù)器的時候,首先得保證本地能成功的運行职烧,本地都跑不了扁誓,那配置到服務(wù)器上肯定也不會防泵,別的不說,代碼首先別有問題蝗敢。
必要依賴包的安裝
之前呢捷泞,搞過幾次java,當(dāng)時記得是把項目打成war包寿谴,然后上傳锁右,有點笨。把Django項目壓縮一下再上傳應(yīng)該也是可以的讶泰。但是何必呢咏瑟,我們直接把代碼傳到github(或者自己存代碼的地方)上面,然后在登上服務(wù)器痪署,直接git clone多好~ 有的時候太緊張码泞,或者把事情想的太難了。
我們在本地pip install的那些包惠桃,到了服務(wù)器那邊還是要再重新install的浦夷。
在服務(wù)器端,clone下項目來之后辜王,cd到當(dāng)前項目劈狐,我們可以把之前安裝的包再一個一個的重新pip install,但是太多了我們也不一定記得清楚有哪些呐馆,所以我們現(xiàn)在本地生成一個記錄引用的包的文件肥缔。
依賴文件生成 (本地操作)
pip freeze > requirements.txt
依賴文件安裝 (服務(wù)器端操作)
pip install -r requirement.txt
我們創(chuàng)建項目時候用的python的版本要跟服務(wù)器上面的版本相同,我的服務(wù)器系統(tǒng)是centos7汹来,記得好像是自帶的是python2.x续膳,然后我項目使用的python3.x, 所以我要在服務(wù)器上裝python3.x, 具體的安裝操作,大家自己搜索一下收班。
安裝完高版本的python之后坟岔,運行pip,可能會出現(xiàn)一些問題摔桦,我忘記當(dāng)時的報錯了社付,好像是pip的版本問題,因為Django的版本邻耕,所以需要安裝pip3, 這地方安裝有些啰嗦鸥咖,大家不要著急,慢慢的裝兄世,遇到報什么錯就去相應(yīng)的搜索一下啼辣。
有時候會提醒你升級pip,然你使用這個pip install --upgrade pip
命令御滩,個人建議不要亂試鸥拧,我就是使用這個升級之后党远,pip和pip3都找不到了。
如果pip install顯示 ‘沒有那個文件或目錄’ 的時候住涉,可以嘗試一下下面這個命令 python -m pip install xxx
麸锉。
如果沒什么別的報錯了的話我們繼續(xù)執(zhí)行pip install -r requirement.txt
來安裝我們需要的包。
下面我遇到了讓我糾結(jié)了一天的一個錯誤舆声。
其實主要的問題就是在安裝mysqlclient的過程中mysql_config not found
我這還特地上Stack Overflow上問了問花沉,也沒人回到我。我在網(wǎng)上搜索了關(guān)于這個問題的錯誤媳握,嘗試了所有能嘗試的方法都沒能解決碱屁。
我搜索了一下,我的文件里壓根就沒有mysql_config這個文件蛾找,太氣了娩脾。
其中有幾個比較靠譜的方法,是讓安裝yum install mysql-devel
這個東西打毛,我也跟著做運行了這個命令柿赊,不過安裝出問題了,從終端上的提示來看幻枉,是有沖突碰声,是與數(shù)據(jù)庫有沖突,很抱歉我忘記截圖了熬甫,但是我從網(wǎng)上的一片文章中也找到了一樣的問題胰挑,大家參看一下。
--> Running transaction check
---> Package mysql-devel.x86_64 0:5.1.69-1.el6_4 will be installed
--> Processing Dependency: mysql = 5.1.69-1.el6_4 for package: mysql-devel-5.1.69-1.el6_4.x86_64
--> Running transaction check
---> Package mysql.x86_64 0:5.1.69-1.el6_4 will be installed
--> Processing Conflict: MySQL-client-5.5.30-1.el6.x86_64 conflicts mysql
--> Processing Conflict: MySQL-server-5.5.30-1.el6.x86_64 conflicts mysql
--> Processing Conflict: mysql-5.1.69-1.el6_4.x86_64 conflicts MySQL
--> Finished Dependency Resolution
Error: mysql conflicts with MySQL-devel-5.5.30-1.el6.x86_64
You could try using --skip-broken to work around the problem
You could try running: rpm -Va --nofiles --nodigest
可以看得出來有幾個Conflict, 最可氣的是底下他還教你通過--skip-broken
來避開這些沖突椿肩,我照做了瞻颂,結(jié)果依然不管用,問題就出在這個沖突上郑象。
好吧贡这,你不是說跟MySQL沖突嗎,我就把MySQL卸載了再說(我很早之前學(xué)習(xí)MySQL的時候就安裝了)厂榛。
具體的MySQL移除過程我就不多說了盖矫,只提下面兩個點:
使用 rpm -qa|grep mysql
查看mysql的安裝情況
rpm -e 文件名 --nodeps
來移除
如果有不管用的地方大家看一下下面這兩篇文章,說的還不錯噪沙,借鑒一下炼彪。
http://834945712.iteye.com/blog/1979042
https://blog.csdn.net/lsa000/article/details/77374351
然后就是重新安裝MySQL,步驟可借鑒下面這篇文章
http://www.reibang.com/p/d679db1ab27f
反正我的項目在重新安裝了MySQL之后就好了吐根,mysql_config文件也有了正歼,再一次執(zhí)行pip install -r requirement.txt
,然后所有的包都順利的安裝完成拷橘。
最后執(zhí)行python manager.py runserver局义,就可以看到我們的項目跑起來了 ~
但是呢喜爷,這樣運行使用Django自帶的WSGI Server運行的,是有性能缺陷的萄唇,并發(fā)承受能力不行 ~ 要不然為什么我們還要使用uWSGI+Nginx呢
具體差距看一下這篇對比文章
django自帶wsgi server vs 部署uwsgi+nginx后的性能對比
uWSGI
首先在使用之前檩帐,我們得先大致了解他們到底是什么東西,為什么要使用另萤。
了解uWSGI
uWSGI旨在為部署分布式集群的網(wǎng)絡(luò)應(yīng)用開發(fā)一套完整的解決方案湃密。主要面向web及其標(biāo)準(zhǔn)服務(wù)。由于其可擴(kuò)展性四敞,能夠被無限制的擴(kuò)展用來支持更多平臺和語言泛源。uWSGI是一個web服務(wù)器,實現(xiàn)了WSGI協(xié)議忿危,uwsgi協(xié)議达箍,http協(xié)議等。
uWSGI又很多優(yōu)點铺厨,具體對uWSGI的講解看這個
http://www.reibang.com/p/679dee0a4193
具體uWSGI的安裝我就不詳細(xì)的說了缎玫,網(wǎng)上教程很多,我想說的是配置文件的問題解滓,因為我搜了很多關(guān)于uWSGI的文章赃磨,可能是由于我們每個人的項目的結(jié)構(gòu)不同,或者別的愿意伐蒂,所以總感覺這個配置文件很難寫煞躬。
網(wǎng)上大多數(shù)的教程在教我們使用uWSGI的時候會讓我們新建一個test.py的文件,然后uwsgi --http :8000 --wsgi-file test.py
, 檢測是否能正常運行逸邦。
運行成功的話就說明uWSGI這個橋梁是起作用的~
下面這個說明我很喜歡
the web client <-> uWSGI <-> Python
但是我們使用uWSGI是為了服務(wù)于Django項目的恩沛,所以說我壓根就沒嘗試上面這一步,而是直接嘗試通過uwsgi命令來運行django項目缕减。
這里會有一點小分歧雷客,因為我從網(wǎng)上搜到的很多教程是說運行了一個.wsgi的文件,但是我整個項目中就沒有發(fā)現(xiàn)這么一個文件桥狡,只有一個wsgi.py的文件搅裙,所以我就是用了下面這個命令來運行整個項目
uwsgi --http :8000 --wsgi-file wsgi.py
注意后面wsgi.py的路徑問題.
結(jié)果還不錯,項目跑得起來了裹芝。
配置uwsgi
我其實并不是真的明白為什么要配置這個.ini文件部逮,聽別人說是這樣的:
如果你喜歡用命令行的方式(如shell)敲命令,那可以省去任何配置嫂易。
但是兄朋,絕大多數(shù)人,還是不愿意記那么長的命令怜械,反復(fù)敲的颅和。所以uwsgi里傅事,就給大家提供了多種配置,省去你啟動時候峡扩,需要敲一長串命令的過程蹭越。
配置的方式很多,我選擇使用ini的方式教届,也是因為網(wǎng)上教程多响鹃。
我們在根目錄下面建一個.ini的文件,由于最初跟著網(wǎng)上的教程學(xué)案训,所以起了個test.ini的名字茴迁。
下面是這個文件里面的內(nèi)容,首先我得成人有很多我是不知道什么意思的萤衰,而且網(wǎng)上教程中的配置會有各種各樣的參數(shù)堕义,這個以后我再慢慢研究。
http = :8000
chdir = /root/myblog/
module = blog.wsgi:application
processes = 4
threads = 2
master = true
enable-threads = true
daemonize = /root/searchmarket/marketSearch/uwsgi.log
buffer-size = 21573
稍微解釋一下脆栋,不一定多倦卖,可作參考。
chdir是當(dāng)前項目的路徑
module算是wsgi.py這個文件的路徑嗎 椿争?好像是的怕膛,但是為什么要寫成這樣子呢 ?
(在我的項目中秦踪,myblog目錄下有一個blog文件夾庵佣,wsgi.py就在這個blog文件夾中~是在搞不懂為啥要寫成blog.wsgi而且后面還加上個 :application)
daemonize是放log日志的地方狸驳,自己創(chuàng)建好文件叼架,路徑貼上青瀑。
差不多了...
然后運行uwsgi --ini test.ini
這個命令就行了 ~
運行完之后,從終端里我看不出來倒是成功了沒有景馁,我用postman請求了一下試了試板壮,失敗的話我就從那個.log文件中看日志,然后處理問題合住。
成功的話绰精,那就是uWSGI部分成功了。
注:也許會碰到端口占用的問題
我的端口使用的8000 然后執(zhí)行這個命令lsof -i:8000
, 然后你會看到PID透葛, 然后kill xxx
笨使,就行了。
我發(fā)現(xiàn)了一個快速的方法
killall -9 uwsgi
Nginx
啟動Nginx
我使用的是yum安裝僚害,簡單易操作硫椰。
yum -y install nginx
就OK了
然后nginx啟動頁非常簡單,直接nginx
就好了。
在啟動nginx時候碰到一個小問題最爬,我干了什么導(dǎo)致的我也不太清楚,反正就是報了這么個錯:
Job for nginx.service failed because the control process exited with error code
就是沒啟動的了门岔,我忽然想起來之前看的一篇博客爱致,在啟動之前他檢測了80端口的狀態(tài),我就隱隱感覺是80端口已經(jīng)被占用的緣故寒随。
然后我運行了這個命令netstat -ntpl
來查看當(dāng)前活躍的鏈接
netstat -ntpl 查看一下80端口是否被占用
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 14267/mysqld
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 709/redis-server 12
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4225/nginx: master
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1184/sshd
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 4212/uwsgi
發(fā)現(xiàn)nginx已經(jīng)被我啟動過一次了糠悯,我也記不清楚了,反正現(xiàn)在啟動nginx沒有什么提示妻往。(網(wǎng)上一些文章顯示有一個OK的提示)互艾。
然后可以kill 4225
, 在nginx
讯泣,就好了 ~
用瀏覽器打開 xxx.xxx.xxx.xx:80 (xx代表我們服務(wù)器的ip)纫普,就可以看到nginx啟動成功的標(biāo)識了。
配置Nginx
yum在線安裝會將nginx的安裝文件放在系統(tǒng)的不同位置好渠,可以通過命令 rpm -ql nginx
來查看安裝路徑
[root@sunxb ~]# rpm -ql nginx
/etc/logrotate.d/nginx
/etc/nginx
/etc/nginx/conf.d
/etc/nginx/conf.d/default.conf
/etc/nginx/fastcgi_params
/etc/nginx/koi-utf
/etc/nginx/koi-win
/etc/nginx/mime.types
/etc/nginx/modules
/etc/nginx/nginx.conf
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params
/etc/nginx/win-utf
/etc/sysconfig/nginx
/etc/sysconfig/nginx-debug
/usr/lib/systemd/system/nginx-debug.service
/usr/lib/systemd/system/nginx.service
/usr/lib64/nginx
/usr/lib64/nginx/modules
/usr/libexec/initscripts/legacy-actions/nginx
/usr/libexec/initscripts/legacy-actions/nginx/check-reload
/usr/libexec/initscripts/legacy-actions/nginx/upgrade
/usr/sbin/nginx
/usr/sbin/nginx-debug
/usr/share/doc/nginx-1.14.0
/usr/share/doc/nginx-1.14.0/COPYRIGHT
/usr/share/man/man8/nginx.8.gz
/usr/share/nginx
/usr/share/nginx/html
/usr/share/nginx/html/50x.html
/usr/share/nginx/html/index.html
/var/cache/nginx
/var/log/nginx
配置config文件
vim /etc/nginx/conf.d/default.conf
然后把location / {} 里面改為如下
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8000;
uwsgi_param UWSGI_SCRIPT blog.wsgi;
uwsgi_param UWSGI_CHDIR /root/myblog;
index index.html index.htm;
client_max_body_size 35m;
}
uwsgi_pass 必須和uwsgi中的設(shè)置一致
UWSGI_CHDIR和UWSGI_SCRIPT 其實也跟uwsgi中差不多昨稼,一個項目路徑,一個wsgi文件的路徑拳锚。
保存之后假栓,Nginx的配置就完成了。最后我們得稍微修改一下uwsgi中的一條配置霍掺。
之前在test.ini文件中是 http = :8000
我們要改為socket = :8000
匾荆。
重新運行uwsgi,重啟nginx杆烁。
結(jié)束牙丽。