基本環(huán)境
- 安裝mysql
- python虛擬環(huán)境中安裝你項目中的包
decode編碼問題:'str' object has no attribute 'decode'
(困惑好久,因為部署到服務(wù)器端了找御,所以感覺程序沒有問題了,后來開了DEBUG露泊,找到了問題),/data/env/pyweb/lib/python3.7/site-packages/django/db/backends/mysql/operations.py in last_executed_query, line 146
decode->encode
-
mysqlclient版本問題
,需要注釋源碼(可能是當(dāng)前版本的bug)
pip freeze >requirements.txt
打包本地安裝的包文件(在本地環(huán)境中)
pip install - r requirements.txt
服務(wù)器中安裝包(在服務(wù)器的虛擬環(huán)境中)
- 安裝redis旅择,修改redis.config文件(注釋bind惭笑,守護進程啟動,關(guān)閉保護模式)
安裝FastDFS
- 安裝fastDFS需要安裝依賴的包
libfastcommon-master-master.zip
yum install unzip
unzip libfastcommon-master-master.zip
chmod +x make.sh
./make.sh
sudo ./make.sh install
- 安裝fastdfs
https://my.oschina.net/harlanblog/blog/466487?fromerr=cqe6bTu2 - 修改配置文件
mv /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf
mv /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf
vim tracker.conf
< base_path /創(chuàng)建的空文件夾/tracker>
vim storage.conf
<base_path /創(chuàng)建的空文件夾/storage>
<storage_path0= /創(chuàng)建的空文件夾/storage>
<tracker_server=ip:22122> ip是你ifconfig得到的ip - 啟動
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf
- 驗證服務(wù)
ps aux|grep tracker&&storage
- 測試
修改clinet.conf 里面的 tracker_server 為ip:22122
vim filename.txt
fdfs_upload_file client.conf filename.txt
出現(xiàn)group....txt -———————— > 成功
FastDFS配合Nginx使用
Nginx安裝及其模塊的添加
- 下載Nginx壓縮包
- 解壓
- 執(zhí)行預(yù)編譯命令生真,指定安裝的路徑(--prefix= / 路徑 / )脖咐,及添加模塊操作(--add module=文件夾/src)
cd nginx目錄中
./configure --prefix=/usr/local/nginx/ --add-module=fdfs_nginx模塊目錄/src
- 修改一些內(nèi)容,否則在執(zhí)行make時會報錯(
Fatal error
)
chmod 777 /windowsfile/fastdfd_nginx_module/src/config
vim /windowsfile/fastdfd_nginx_module/src/config
下面的內(nèi)容發(fā)生了更改
ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"
CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
- 進入nginx源碼目錄
./configure --add-module= /windowsfile/fastdfs-nginx-module/src
make
make install
- 未出現(xiàn)什么異常汇歹,添加第三方模塊完成。
- 編譯安裝
make
make install
- 模塊要和nginx的版本對應(yīng)偿凭,否則會報錯
https://github.com/downgoon/hello-world/wiki/FastDFS-Install-&-Upload-&-Download
Nginx相關(guān)的配置
- fdfs模塊的配置
cp /windowsfile/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs/
vim mod_fastdfs.conf
<timeout為10>
<tracker-server ip:22122>
<url_has_group_name為 true> -
nginx.conf
- 啟動nginx后就可以在瀏覽器中顯示圖片了
目前本地的程序已經(jīng)可以基本運行了产弹,因為redis,fdfs就位,差celery異步痰哨。下一步就是在服務(wù)器運行程序胶果。
uwsgi 配置
- 在項目中創(chuàng)建
uwsgi.ini
,內(nèi)容
[uwsgi]
# 直接作為web服務(wù)器使用 python manage.py runserver ip:port
# http=127.0.0.1:8080
socket = 127.0.0.1:8080
# 項目的文件目錄
chdir=/項目目錄
# wsgi文件在你的項目目錄的哪里 基于上面的目錄
wsgi-file=daily_fresh/wsgi.py
processes=4
threads=2
master=True # 有主進程
# 保存主進程的進程號
pidfile=uwsgi.pid
# 作為守護進程斤斧,并保存日志
daemonize=uwsgi.log
# 虛擬環(huán)境的目錄
virtuaenv=/虛擬環(huán)境的目錄
- 啟動:
uwsgi --ini /配置文件目錄
- 停止:
uwsgi --stop uwsgi.pid路徑
例如:uwsgi --ini uwsgi.ini早抠;
uwsgi --stop uwsgi.pid或者 pkill -f uwsgi -9
uwsgi + Nginx(做)
- 將項目拷貝到服務(wù)器,修改
DEBUG = False撬讽,ALLOWED_HOSTS = ['*']
蕊连,并在settings中設(shè)置STATIC_ROOT = '/data/www/static'
指定靜態(tài)文件收集的目錄(這個目錄應(yīng)該是已創(chuàng)建的) - 這個文件夾要搞一下權(quán)限
chmod 777 /data/www/static
- 改一下mysql
否則會提示mysqlclient錯誤: /data/env/pyweb/lib/python3.7/site-packages/django/db/backends/mysql/base.py,修改環(huán)境下的lib/python3.7/site···文件,或者將本地已經(jīng)改好的base.py復(fù)制過去 - 執(zhí)行 收集靜態(tài)文件
python manage.py collectstatic
1750 static files copied to '/data/www/static'.成功
靜態(tài)文件已經(jīng)收集好了游昼,剩下要讓nginx顯示 - 配置nginx.conf
location / {
inlcude uwsgi_params; # 參數(shù)也要包含
uwsgi_pass 127.0.0.1:8080; # 轉(zhuǎn)交給uwsgi
}
location /static {
alias /data/www/static/; # 指定靜態(tài)文件的目錄
}
- 重啟nginx
sbin/nginx -s reload
nginx還未完成
celery的配置
- celery任務(wù)中有導(dǎo)入app的模塊甘苍,所以需要django的環(huán)境
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE','dailyfresh.settings')
#或者os.environ['DJANGO_SETTINGS_MODULE'] ='daily_fresh.settings')
django.setup()
- 進入虛擬環(huán)境執(zhí)行,報錯(goods/admin.py)can't import index_html
理論上應(yīng)該是沒有問題烘豌,但是不能導(dǎo)入载庭,就是時機不對,太早了廊佩,所以在使用到這個函數(shù)的時候在導(dǎo)入囚聚,寫在里面就好了
class BaseAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
super().save_model(request, obj, form, change)
from celery_tasks.tasks import generate_static_index_html
generate_static_index_html.delay()
cache.delete('index_page_data')
def delete_model(self, request, obj):
super().delete_model(request, obj)
from celery_tasks.tasks import generate_static_index_html
generate_static_index_html.delay()
cache.delete('index_page_data')
- 沒有haystack.backends.whoosh_cn_backend'
這個是自己修改的,所以將本地的拷貝到服務(wù)器中haystack中的文件夾中 - 啟動celery時遇到錯誤标锄,
無法連接redis://ip:6379
,把ip改為了本機ip改為內(nèi)網(wǎng)地址應(yīng)該成功顽铸,我該為了127.0.0.1成功。 - 再次啟動成功鸯绿,但是執(zhí)行任務(wù)時出錯跋破,
靜態(tài)首頁時報錯,應(yīng)該返回一個dict瓶蝴,而不是一個request對象
毒返,將context = 字典后,不對他進行封裝舷手。 - 遇到ImageFilefield Error拧簸,模板中的問題,將模板文件中的圖片image.url,去掉了url男窟。暫時好了盆赤,但是生成的頁面圖片地址不對,后來知道是fdfs_client的原因歉眷,下面也有牺六。
- stmp郵箱遇到錯誤,無法連接到stmp
將settings文件中的EMAIL_USE_TSL = False改為 EMAIL_USE_SSH = True
成功發(fā)送郵件。
uwsgi + Nginx(釋)
- 在將項目拷貝到服務(wù)器之前汗捡,改
DEBUG = False淑际,ALLOWED_HOSTS = ['*']
,這樣在服務(wù)器端靜態(tài)文件不會生效,需要用到nginx
- 思路: 1. 用戶訪問一個地址春缕,由nginx接受參數(shù)盗胀,并判斷是靜態(tài)請求還是動態(tài)請求
這步判斷就是nginx的路由匹配
location /url/ { }
- 如果是靜態(tài)請求,就是請求了一些圖片锄贼,css票灰,js等資源,我們實現(xiàn)把這些資源放在一個文件中宅荤,并設(shè)置nginx的路由匹配屑迂,將匹配結(jié)果導(dǎo)向我們的文件位置。
- 如果是動態(tài)請求膘侮,那么就轉(zhuǎn)交給uwsgi屈糊,讓uwsgi在調(diào)用application() 訪問django系統(tǒng),系統(tǒng)返回參數(shù)給uwsgi琼了,再通過nginx返回到用戶界面逻锐。
nginx配置文件,里面的http{}
中全是一些serve{}
雕薪。
有listen
:監(jiān)聽的端口號昧诱,
server_name
:監(jiān)聽的ip地址
location ‘url’{ }
:路由,括號里面類似于django的urls所袁。
靜態(tài)請求
1 如果像直接返回靜態(tài)文件盏档,不提交到uwsgi服務(wù)器,那么里面直接寫本機中的文件路徑燥爷,新建一個存放靜態(tài)文件的路徑蜈亩。/data/www/daily_fresh/static
,然后在nginx.conf中指定當(dāng)訪問/static
路徑時,就去找/data/www/daily_fresh/static
目錄
location /static {
# 指定存放靜態(tài)文件的目錄
alias /data/www/daily_fresh/static
}
在setting的文件中指定STATIC_ROOT的值為剛才的路徑/data/www/daily_fresh/static
,
執(zhí)行 python manage.py collectstatic
收集靜態(tài)文件前翎。
權(quán)限不夠的話稚配, chmod 777 /data/daily_fresh/static/
1.2 當(dāng)用戶請求的靜態(tài)文件不在此電腦上時可以,可以通過ip訪問到另一nginx的上的靜態(tài)文件
location = / {
指定存放靜態(tài)文件nginx的ip地址港华,及端口道川,沒寫就是默認(rèn)80
proxy_pass http://ip:port;
}
動態(tài)請求
- 如果是要提交給uwsgi服務(wù)器,同時還要提交傳入的參數(shù)給uwsigi, 就需要uwsgi的端口號和地址立宜。
# 包含uwsgi的請求參數(shù)
include uwsgi_params;
# 轉(zhuǎn)交給 uwsgi 的ip和端口
uwsgi_pass 127.0.0.1:8080;
配置nginx的時候冒萄,小心分號,少寫會報錯橙数。
項目總體
每一個部分都可以在不同的電腦上尊流。
- django項目跑在uwsgi服務(wù)器上,可以在項目中多創(chuàng)建幾個uwsgi.ini灯帮,注意其中的socket端口不能相同奠旺,還有就是uwsgi.pid和log的名字也要變化
- 靜態(tài)頁面的服務(wù)器和應(yīng)用服務(wù)器時分離的蜘澜,實現(xiàn)了前后端分離。
- 在調(diào)度服務(wù)器中可以通過ip:port訪問靜態(tài)文件响疚。
- 調(diào)度服務(wù)器中負(fù)載均衡,要修改conf文件瞪醋,加上
upstream somename{
server ip:port1
server ip:port2
當(dāng)用戶訪問時忿晕,會輪流執(zhí)行
}
之前是將請求直接返回給了uwsgi,現(xiàn)在银受,較給somename践盼,讓他決定哪個應(yīng)用服務(wù)器執(zhí)行。
**
location / {
include uwsgi_parms;
uwsgi_pass somename;
}
**
- mysql宾巍,fstdfs咕幻,redis也可不在同一臺電腦中,通過ip:port連接顶霞。
其中fdfs的訪問要通過nginx實現(xiàn)肄程,讓他監(jiān)聽網(wǎng)站的某個端口來實現(xiàn)上傳和下載。
- 部署時选浑,先檢查項目跑起來有沒有問題
python manage.py runserver
,如果有問題就是項目中存在問題蓝厌,可能是你在本地的改了配置文件,但是在服務(wù)器中虛擬環(huán)境中沒有更改古徒,例如mysqlclient的問題
拓提,decode的問題
,haystack中添加了配置的文件
- 上一步完成就添加一個uwsgi文件
- 修改nginx配置文件
- 讓uwsgi的配置文件生效
- 啟動nginx
- celery中的任務(wù)隧膘,要填加上django的環(huán)境
在tasks中的前面要加上django啟動時的環(huán)境代态,但是啟動時的環(huán)境導(dǎo)入這任務(wù)中的函數(shù)就會出錯,報import異常疹吃,所以要把import放在里面蹦疑,什么時候用,什么時候import互墓。
出現(xiàn)的問題
TypeError: context must be a dict rather than RequestContext:
這個問題是django版本的問題必尼,出現(xiàn)在生成靜態(tài)首頁的位置,我們需要得到html頁面篡撵,并保存在本地判莉,而不需要返回
# 使用模板
# 加載模板文件
temp = loader.get_template('static_index.html')
# 定義模板上下文
context = RequestContext(request,context)
# 模板渲染
static_index_html = temp.render(context)
# 生成首頁對應(yīng)的靜態(tài)文件
save_path = os.path.join(settings.BASE_DIR, 'static/index.html')
with open(save_path,'w') as f:
f.write(static_index_html)
問題的關(guān)鍵是context必須是一個字典
繼續(xù)上面的nginx
- 把項目部署到服務(wù)器上時,收集了靜態(tài)文件到一個目錄
/data/www/daily_fresh/static
這個不是我的項目目錄 - 然后在nginx的配置中育谬,匹配/static的就去找
/data/www/daily_fresh/static/
, 匹配/的就轉(zhuǎn)交給uwsgi :# 包含uwsgi的請求參數(shù)
include uwsgi_params;
# 轉(zhuǎn)交給 uwsgi 的ip和端口
uwsgi_pass 127.0.0.1:8080;
但是始終不能訪問券盅,位置也換過,文件夾的權(quán)限也改過膛檀,這里猜想可能是因為這里的static并沒有被訪問锰镀,因為沒有給項目中的static配置娘侍,所以訪問不到。但是靜態(tài)頁面也應(yīng)該出現(xiàn)個畫呀泳炉,不知道是什么問題憾筏。
于是我采取了曲線救國的策略,又配置了一臺nginx server
server 配置81端口
location / {
root /data/daily_fresh/static/; #我的項目路徑
index index.html index.htm
}
location /static { # 右邊沒有/
alias /data/daily_fresh/static/; #我的項目路徑
}
啟動這臺服務(wù)器花鹅,然后訪問網(wǎng)站的81端口(在服務(wù)器中打開端口氧腰,重啟防火墻,在阿里云客戶端添加81端口)刨肃,成功古拴。
主nginx精確匹配 / 時,轉(zhuǎn)交給這臺nginx
nginx.conf
user root;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 8888;
server_name 47.100.179.209;
location ~/group[0-9]/ {
ngx_fastdfs_module;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 81;
server_name 47.100.179.209;
location / {
# autoindex on;
root /data/daily_fresh/static/;
index index.html index.htm;
}
location /static{
alias /data/daily_fresh/static/;
}
}
# upstream daily_fresh{
# server 127.0.0.1:8080;
# server 127.0.0.1:8081; # 將下面的uwsgi_pass 中的127.0.0.1換成daily_fresh
# } 前提是有兩個uwsgi.ini文件真友,啟動兩個uwsgi黄痪,nginx 負(fù)責(zé)發(fā)牌式的負(fù)載均衡
server {
listen 80;
server_name 47.100.179.209;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8080;
#uwsgi_pass daily_fresh;
}
location = /{
proxy_pass http://47.100.179.209:81;
}
location /static{
alias /data/www/static/;
}
}
出現(xiàn)的問題
圖片類型沒有發(fā)布,ImageFileField is not 發(fā)布
- 使用celery發(fā)布任務(wù)時盔然,得到錯誤桅打,
ImageFileField is not 發(fā)布
,將頁面中的sku.image.url改為sku.image后可以正常的發(fā)布任務(wù)轻纪,可以正常生成靜態(tài)頁面油额,但是有問題,路徑不太對刻帚,好像是缺了端口還是什么潦嘶,反正不能正常顯示圖片。最后想到在windows中安裝的fdfs_client應(yīng)該是不匹配linux系統(tǒng)的崇众,而在執(zhí)行pip install -r requirement.txt
時掂僵,安裝的是windows版本的fdfs_client,所以卸載顷歌,傻瓜安裝不放心锰蓬,所以下載安裝包安裝,cd 進去眯漩,python setup.py install ,發(fā)布任務(wù)就沒發(fā)現(xiàn)錯誤
自己傻了
- 一開始訪問的fdfs地址就不對芹扭,還有靜態(tài)文件的目錄也不對,查驗后使用的之前的index.html,使用自己生成的靜態(tài)文件后成功
總結(jié):
出現(xiàn)問題后程序的問題不大赦抖,前提是在windows端出現(xiàn)的錯誤改了之后(指改mysqlclient舱卡,django/db里面的源碼)
- 仔細看看有沒有操作失誤,指在各種conf中有沒有配置錯誤队萤,拼寫錯誤轮锥,拼寫錯誤,拼寫錯誤要尔。舍杜。新娜。
- 如果是靜態(tài)文件,打開F12看看出現(xiàn)什么問題既绩,路徑錯誤就去模板html中再看看概龄,settings中的幾項配置STATICFILES_DIRS,STATIC_URL,STATIC_ROOT看看,多斜杠熬词,少斜杠
- 打開DEBUG看看有什么錯誤旁钧,這個是最管用的,記得把ALLOW_HOSTS=[‘*’]
- linux和windows的不兼容問題互拾,出問題的是什么插件,就去百度下有沒有類似的錯誤嚎幸,有沒有相關(guān)的資料颜矿。
5.再來一遍。