准備知識
1、django
一個基於python的開源web框架,請確保自己熟悉它的框架目錄結構。
2、uWSGI
一個基於自有的uwsgi協議、wsgi協議和http服務協議的web網關
3、nginx
常用高性能代理服務器
4、wsgi.py
django項目攜帶的一個wsgi接口文件
如果項目名叫mysite的話,此文件就位於[/mysite/mysite/wsgi.py]
項目運行流程
1、首先客戶端請求服務資源;
2、Nginx作為直接對外的服務接口,接收到客戶端發送過來的http請求,會解包、分析;
3、如果是靜態文件請求就根據Nginx配置的靜態文件目錄,返回請求的資源;
4、如果是動態的請求,Nginx就通過配置文件,將請求傳遞給uWSGI;uWSGI 將接收到的包進行處理,並轉發給WSGI;
5、WSGI根據請求調用Django工程的某個文件或函數,處理完后Django將返回值交給WSGI;
6、WSGI將返回值進行打包,轉發給uWSGI,
7、uWSGI接收后轉發給Nginx,Nginx最終將返回值返回給客戶端(如瀏覽器)。
注:不同的組件之間傳遞信息涉及到數據格式和協議的轉換
說明:
1、第一級的Nginx並不是必須的,uwsgi完全可以完成整個的和瀏覽器交互的流程;
2、在Nginx上加上安全性或其他的限制,可以達到保護程序的作用;
3、uWSGI本身是內網接口,開啟多個work和processes可能也不夠用,而Nginx可以代理多台uWSGI完成uWSGI的負載均衡;
4、django在debug=False下對靜態文件的處理能力不是很好,而用nginx來處理更加高效。
為方便理解,uWSGI,WSGI和uwsgi在網站項目流程圖中的功能如下:(圖片來自博客:https://www.cnblogs.com/new-rain/p/10089941.html)
uWSGI,WSGI和uwsgi的區別
(1)WSGI:全稱 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是為 Python 語言定義的 Web 服務器和 Web 應用程序或框架之間的一種簡單而通用的接口。也可以認為WSGI是一種通信協議。自從 WSGI 被開發出來以后,許多其它語言中也出現了類似接口。
WSGI 的官方定義是,Python Web Server Gateway Interface。從名字就可以看出來,這東西是一個Gateway,也就是網關。網關的作用就是在協議之間進行轉換。
WSGI 是作為 Web 服務器與 Web 應用程序或應用框架之間的一種低級別的接口,以提升可移植 Web 應用開發的共同點。WSGI 是基於現存的 CGI 標准而設計的。
WSGI是 Web 服務器(uWSGI)與 Web 應用程序或應用框架(Django)之間的一種低級別的接口
(2)uwsgi:是服務器和服務端應用程序的一種協議,規定了怎么把請求轉發給應用程序和返回;uwsgi是一種線路協議而不是通信協議,在此常用於在uWSGI服務器與其他網絡服務器的數據通信。
(3)uWSGI:是一種 Python Web Server 或稱為 Server/Gateway,uWSGI 是實現了 uwsgi 和 WSGI 兩種協議的Web服務器,負責響應 Python 的 Web 請求。
因為Apache、Nginx等,它們自己都沒有解析動態語言如 php 的功能,而是分派給其他模塊來做,比如 Apache 就可以說內置了php模塊,讓人感覺好像Apache就支持 php 一樣。
uWSGI實現了wsgi協議、uwsgi協議、http等協議。 Nginx中 HttpUwsgiModule 的作用是與 uWSGI 服務器進行交換。
一、CentOS7.4自帶Python2安裝Python3
# 查看python的執行位置
which python
# 安裝依賴,使用yum安裝
yum -y groupinstall "Development tools"
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel
# 下載python3的安裝包
wget -c https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz
# 創建安裝目錄
mkdir /usr/local/python3
# 解壓安裝包
tar -zxvf Python-3.7.0.tgz
# 進入解壓目錄
cd Python-3.7.0
# 編譯源碼包代碼,--prefix參數,指定稍后源碼包程序的安裝路徑
./configure --prefix=/usr/local/python3
# 生成二進制安裝程序
make
# 運行二進制的服務程序安裝包
make install
注意,在這里可能會報以下錯誤
File "/usr/local/src/Python-3.7.0/Lib/ctypes/__init__.py", line 7, in <module> from _ctypes import Union, Structure, Array ModuleNotFoundError: No module named ‘_ctypes‘ make: *** [install] Error 1
安裝libffi-devel即可解決,yum install libffi-devel,安裝完記得再次運行 make install
安裝成功的界面:
# 創建軟鏈接,安裝完成之后,建立軟鏈接,添加變量,方便在終端中直接使用python3
ln -s /usr/local/python3/bin/python3 /usr/bin/python3
# pip3創建軟鏈接,Python3安裝完成之后pip3也一塊安裝完成,不需要再單獨安裝,一樣建立軟鏈接
ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3
# 清理源碼包臨時文件
make clean
# 查看Python3和pip3安裝情況
二、安裝MySQL
安裝的方式使用rpm包方式安裝,要是想用yum安裝見另一篇博客,https://www.cnblogs.com/opsprobe/p/10681063.html
# 下載安裝MySQL
wget https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.25-1.el7.x86_64.rpm-bundle.tar
# 解壓安裝包
tar -vxf mysql-5.7.25-1.el7.x86_64.rpm-bundle.tar
# 查看mysql相關
whereis mysql
# 移除mysql相關的lib(可選項操作,建議操作)
yum remove mysql-libs
#安裝mysql rpm相關的包,相互之見存在依賴關系,按照順序安裝 common --> libs --> clients --> server
rpm -ivh mysql-community-common-5.7.25-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-5.7.25-1.el7.x86_64.rpm
rpm -ivh mysql-community-client-5.7.25-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-compat-5.7.25-1.el7.x86_64.rpm
rpm -ivh mysql-community-server-5.7.25-1.el7.x86_64.rpm
下面的截圖是其他機器上用yum安裝時的顯示,可以看到依賴關系:
注意:安裝時可能會報以下錯誤:安裝yum -y install numactl,即可解決
# 這個在后面安裝 msyqlclient 需要依賴的包 rpm -ivh mysql-community-devel-5.7.25-1.el7.x86_64.rpm
# 安裝完成之后,啟動服務
systemctl start mysqld
注意: 可能出現警告 [warning: mysql-community-server-5.7.19-1.el6.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 5072e1f5: NOKEY](https://www.cnblogs.com/royfans/p/7243641.html)
解決方法,安裝時加上命令:rpm -ivh mysql-community-server-5.7.19-1.el6.x86_64.rpm --force --nodeps
# 查看服務狀態
systemctl status mysqld
至此MySQL安裝完成
配置MySQL相關:修改MySQL密碼
# 登錄mysql
mysql -u root -p
# 在此時需要密碼,密碼隱藏在log中,查找默認隨機密碼
grep 'password' /var/log/mysqld.log
然后執行 mysql -u root -p ,輸入上面查到的密碼進入,用該密碼登錄后,必須馬上修改新的密碼,不然操作會報如下錯誤:
# 修改密碼,獲取隨機密碼之后,登錄修改密碼(由於mysql密碼策略限制,密碼需要包含大小寫數字,特殊字符)
alter user 'root'@'localhost' identified by 'xxxxx';(或者用 set password=password("youpassword");)
密碼設置太簡單,會報以下錯誤
這個其實與validate_password_policy的值有關。
validate_password_policy有以下取值:
默認是1,即MEDIUM,所以剛開始設置的密碼必須符合長度,且必須含有數字,小寫或大寫字母,特殊字符。
有時候,只是為了自己測試,不想密碼設置得那么復雜,譬如說,我只想設置root的密碼為123456。
必須修改兩個全局參數:
首先,修改validate_password_policy參數的值
mysql> set global validate_password_policy=0;
validate_password_length(密碼長度)參數默認為8,我們修改為1
mysql> set global validate_password_length=1;
完成之后再次執行修改密碼語句即可成功
mysql> alter user 'root'@'localhost' identified by '123456';
刷新權限
flush privileges;
重新登錄MySQL
mysql -u root -p
安裝virtualenv ,建議大家都安裝一個virtualenv,方便不同版本項目管理(pip3安裝的包都在 /data/environment/lab_reports/lib/python3.7/site-packages/ 目錄下)。
pip3 install virtualenv
在這里要是出現如下錯誤提示,就需要更新pip
運行以下命令更新pip,更新pip完成后重新運行命令pip3 install virtualenv
python3 -m pip install --upgrade pip
建立軟鏈接
ln -s /usr/local/python3/bin/virtualenv /usr/bin/virtualenv
安裝成功在根目錄下建立兩個文件夾,主要用於存放environment和網站文件的。(個人習慣,其它人可根據自己的實際情況處理)
mkdir -p /data/environment
mkdir -p /data/wwwroot
切換到 cd /data/environment/ 下,創建指定版本的虛擬環境。
virtualenv --python=/usr/bin/python3 blog(blog是自定義的)
然后進入cd /data/environment/blog/bin/
啟動虛擬環境:source activate
退出虛擬環境:deactivate
留意紅框標記的位置,出現(blog),說明是成功進入虛擬環境。(注意:以下的操作都需要在虛擬環境下進行)
安裝Django:
pip3 install django (如果用於生產的話,則需要指定安裝和你項目相同的Django版本)
例如:在Windows下查看Django的版本,如下圖所示,可以看到是2.1.5版本的Django
在服務器上虛擬環境下安裝2.1.5版本的Django
pip3 install django==2.1.5
卸載指定版本 django 的命令
pip3 uninstall django==2.1.5
在本地生成並導出依賴包(導出依賴包的兩種方式,參考自其他博客:https://www.cnblogs.com/clement-jiao/p/9905611.html)
# 進入項目目錄,運行以下命令,導出依賴包,我是在PyCharm下操作的
pip3 freeze > requirements.txt
或者:pipreqs ./ --encoding=utf8
# 導出的默認位置就在項目的根目錄下
Django 靜態文件收集
命令:python manage.py collectstatic
運行靜態文件收集命令時,先需要在 settings.py 里配置這個STATIC_ROOT,收集完后,還需要改回來。
注意!!!
它可能會和 STATICFILES_DIRS 沖突,視情況而定。
Django 靜態文件,自強學堂做了很好的說明:https://code.ziqiangxuetang.com/django/django-static-files.html
切換到網站目錄/data/wwwroot,上傳Django項目到這里,包括剛生成的項目依賴文件requirements.txt
安裝依賴包
# 安裝項目依賴(注意:安裝依賴時可能會有錯誤,請百度自行解決)
pip3 install -r requirements.txt
# 接下來需要先在MySQL數據庫里手動新建項目連接的數據庫,然后在項目目錄下,運行下面的命令進行數據庫表的初始化操作
python3 manage.py makemigrations
python3 manage.py migrate
測試運行項目
# 運行項目,0.0.0.0地址為任意客戶端IP都可以訪問,端口自定義
python3 manage.py runserver 0.0.0.0:8000
# 在客戶端的瀏覽器通過服務器的公網地址訪問項目,若能訪問到項目,說明項目部署成功。
Django正常運行之后我們就開始配置uWSGI和nginx,接着還是在虛擬環境里用pip3安裝uWSGI
pip3 install uWSGI
在項目根目錄下創建uwsgi.ini文件,輸入如下內容:
# 指定uwsgi配置
[uwsgi]
# 指定部署項目之后的HTTP訪問,和后面Nginx配置文件里的uwsgi_pass 127.0.0.1:8080處要一致
socket = 127.0.0.1:8080
#http=47.106.218.225:8080(使用uwsgi代理時)
# 指定項目的絕對路徑
chdir=/data/wwwroot/blogs/mysite
# 指定wsgi文件
wsgi-file=mysite/mysite/wsgi.py
# 指定啟動進程數量processes/workers
processes=4
# 指定啟動線程數量
threads=2
# 指定啟動主進程管理
master=true
# 指定存放進程編號的id文件
pidfile=uwsgi.pid
# 指定進程停止時清楚垃圾數據
vacuum=true
# 指定啟用日志記錄(這里指定了uWSGI日志的存儲路徑。)
daemonize=uwsgi.log
# 指定靜態文件映射
#static-map=/static=static_file(使用uwsgi代理時)
:wq 退出,保存
至此,uwsgi+django就完美結合了,但是,光有uwsgi還不夠,uwsgi處理動態請求能力高,但對於靜態請求(如static文件,css,js文件等)處理能力差,此時就要結合nginx一起使用
安裝nginx和配置nginx.conf文件(nginx下載地址:http://nginx.org/en/download.html)
wget -c http://nginx.org/download/nginx-1.16.0.tar.gz
下載完成后,執行解壓命令:
tar -zxvf nginx-1.16.0.tar.gz
進入解壓后的nginx-1.16.0/目錄:cd nginx-1.16.0/
依次執行以下命令:
./configure
make
make install
make clean
nginx一般默認安裝好的路徑為/usr/local/nginx
在/usr/local/nginx/conf/中先備份一下nginx.conf文件,以防意外。
cp nginx.conf nginx.conf-backup
然后打開nginx.conf,把原來的內容刪除,直接加入以下內容:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
server {
listen 90; # 我要監聽那個端口
server_name 172.27.0.6; # 服務器上ifconfig命令查出來的IP地址
charset utf-8; # Nginx編碼
access_log /data/wwwroot/blogs/mysite/nginx_access.log;
error_log /data/wwwroot/blogs/mysite/nginx_error.log; # access_log和error_log是定義nginx訪問日志和錯誤日志的存放路徑。
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8080; # 是指uWSGI綁定的監聽地址,端口與原來的uwsgi.ini中設置的端口一致
uwsgi_param UWSGI_SCRIPT mysite.wsgi;
uwsgi_param UWSGI_CHDIR /data/wwwroot/blogs/mysite/; # 項目的絕對路徑
}
# 指定靜態文件路徑
location /static/ {
alias /data/wwwroot/blogs/mysite/static/;
}
}
}
這里需要注意的就是項目路徑,一定要寫對,我剛開始就把項目路徑搞錯了,導致花了很多時間去找錯誤。
啟動項目,訪問項目的頁面。(再次提醒,注意:以下操作是在虛擬環境下進行)
進入cd /usr/local/nginx/sbin/目錄
執行 ./nginx -t 命令先檢查配置文件是否有錯,沒有錯就執行以下命令,啟動nginx:
./nginx
終端沒有任何提示就證明nginx啟動成功。
重啟nginx命令:./nginx -s reload(注意:nginx啟動時,才能使用該命令,否則會報錯)
進入網站項目目錄
cd /data/wwwroot/blogs/mysite
執行下面命令,通過配置文件啟動:
uwsgi --ini uwsgi.ini
# 停掉uwsig
uwsgi --stop uwsgi.pid
以上步驟都沒有出錯的話,就在客戶端瀏覽器里訪問你的項目地址!(服務器的IP地址:nginx的端口號/項目路徑)
如果啟動時就報錯,查看終端信息,解決錯誤。
如果終端沒有報錯,但是瀏覽時出現500、502等錯誤,就去項目目錄查看nginx日志和uWSGI日志,解決錯誤。
ps aux命令
a:顯示現行終端機下的所有程序,包括其他用戶的程序
u:以面向用戶的格式顯示進程
x:顯示所有程序,不以終端機來區分
# 分別查看系統nginx和uwsgi進程信息
ps aux | grep nginx
ps aux | grep uwsgi
# 強制殺死nginx和uwsgi的進程
killall -9 nginx
killall -9 uwsgi
查看python安裝路徑以及pip安裝的包,參考自其它博客:https://blog.csdn.net/mr_cat123/article/details/80435861
CentOS7設置Nginx為開機啟動:參考自博客:https://www.cnblogs.com/xiaojf/p/7891345.html