天天生鲜项目经验
一、項目架構
前端:
- 用戶相關
- 商品相關
- 購物車相關
- 訂單相關
- 后臺管理
后端:
- 用戶模塊
- 商品模塊
- 購物車模塊
- 訂單模塊
- 后臺管理模塊
技術:
- mysql
- session 緩存服務器redis
- 異步任務處理celery
- 分布式文件存儲系統fastdfs
二、用戶認證模型
# django認證系統使用的用戶模型 AUTH_USER_MODEL = "users.User"1.類視圖
將視圖view以類的形式定義,通用類視圖基類:
django.views.generic.View
urls.py中配置路由使用類視圖的as_view()方法,由dispatch()方法具體將請求request分發至對應請求方式的處理方法中(get、post)等
2.django認證系統
| create_user | 創建用戶 |
| authenticate | 登錄驗證 |
| login | 記錄登錄狀態 |
| logout | 退出用戶登錄 |
| is_authenticated | 判斷用戶是否登錄 |
| login_required裝飾器 | 進行登錄判斷 |
3.django發送郵件
Django網站---->smtp服務器----->目的郵箱
SMTP的全程是Simple Mail Transfer Protocol,即簡單郵件傳輸協議。它是一組用于從源地址到目的地址傳輸郵件的規范,通過它來控制郵件的中轉方式。SMTP協議屬于TCP/IP協議簇,它幫助每臺計算機在發送獲中轉信件時找到下一個目的地,SMTP服務器就是遵循SMTP協議的發送郵件服務器,不同郵件服務商均有對應的smtp服務器地址,并且這個地址會提供給大家,方便大家使用Foxmail與outlook等專業郵件管理軟件時可以用得上。
4.celery:異步任務隊列
任務的發出者、中間人、任務的處理者可以在同一臺電腦上啟動,也可以不在同一臺電腦上。處理者也需要任務的代碼,任務處理者所在電腦必須有網
pip install celery
項目代碼(任務發出者)
—發出任務—>
任務隊列(中間人broker)redis
<—監聽任務隊列—任務處理者worker
1)使用
2)發出任務
@app.task def send_register_active_email(to_email, username, token):# 發送郵件的代碼pass# 發郵件:此方法會把發郵件的任務放到任務隊列中 send_register_active_email.delay(email, username, token)3)啟動worker
celery -A celery_tasks.tasks worker -l info5.用戶激活
使用itsdangerous加密用戶身份信息
1)加密碼用戶身份信息
2)解密用戶身份信息
serializer = Serializer(settings.SECRET_KEY, 3600) try:# 根據秘鑰解密info = serializer.loads(token)# 獲取待激活用戶的iduser_id = info['confirm']# 根據id獲取用戶信息user = User.objects.get(id=user_id)user.is_active = 1user.save()# 跳轉到登錄頁面return redirect(reverse('user:login')) except SignatureExpired as e:return HttpResponse('激活連接已過期!')6.用戶登錄
6.1 配置redis作為Django緩存和session后端
配置:
# Django的緩存配置 CACHES = {"default":{"BACKEND": "django_redis.cache.RedisCache","LOCATION": "redis://172.16.179.142:6379/9","OPTIONS":{"CLIENT_CLASS":"django_redis.client.DefaultClient",}} } # 配置sessiong存儲 SESSION_ENGINE = "django.contrib.sessions.backends.cache" SESSION_CACHE_ALIAS = "default"6.2 登錄判斷裝飾器loging_required
使用LoginRequireMixin:
from django.contrib.auth.decorators import login_requiredclass LoginRequiredMixin(object):@classmethoddef as_view(cls, **initkwargs):# 調用父類的as_viewview = super(LoginRequiredMinxin, cls).as_view(**initkwargs)return login_required(view)登錄后跳轉
# 獲取登錄后所需要跳轉的地址 # 默認跳轉到首頁 next_url = request.GET.get('next', reverse('goods:index')) # 跳轉到next_url response = redirect(next_url) # 重定向到新的地址6.3 用戶退出
logout 函數清楚登錄用戶的session信息
6.4 django-redis獲取redis連接
from django_redis import get_redis_connectioncon = get_redis_connection('default')商品模塊開發
1. 了解FastDFS分布式文件系統
集群
啟動FastDFS的方法,需要的操作
tracker_server = ip地址:22122
2.python對接fastdfs
3.項目上傳圖片和使用圖片流程
海量存儲,存儲容量擴展方便。
文件內容重復時只保留一份。
結合nginx提高網站訪問圖片的效率
4. Django二次開發對接FastDFS
三、商品首頁
采用的數據形式:每個用戶的購物車記錄用一條數據保存:
hash:
cart_用戶id:{‘SKU_ID1’:數量,‘sku_id2’:數量}
把原本動態的頁面處理結果保存成html文件,讓用戶直接訪問這個生成出來的靜態的html頁面
①使用celery生成靜態頁面
②配置nginx提供靜態頁面
③管理員修改首頁所使用表中的數據時,重新生成index靜態頁面
搜索引擎:
1)可以對表中的某些字段進行關鍵詞分析,簡歷關鍵詞對應的索引數據。
索引:字典目錄
全文檢索框架:可以幫助用戶使用搜索引擎。
用戶----》全文檢索框架haystack-----》搜索引擎whoosh
2) 搜索引擎的安裝和配置
①安裝python包:
②在settings.py文件中注冊應用haystack并做如下配置:
INSTALLED_APPS = ('haystack', # 全文檢索框架 ) . . . . # 全文檢索框架的配置 HAYSTACK_CONNECTIONS = {'default':{# 使用whoosh引擎'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine','PATH': os.path.join(BASE_DIR, 'whoosh_index')} }# 當添加、修改、刪除數據時,自動生成索引 HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'①在goods應用目錄下新建一個serach_indexes.py文件,在其中定義一個商品索引類。
②在templates下面新建目錄search/indexes/goods
③在此目錄下面新建一個文件goodssku_text.txt并編輯內容如下
④ 使用命令生成索引文件
python manage.py rebuild_index
四、訂單
mysql事務
- 原子性:一組事務,要么成功,要么撤回
- 穩定性:有非法數據(外鍵約束之類),事務撤回
- 隔離性:事務獨立運行。一個事務處理后的結果,影響了其他事務,那么其他事務會撤回。事務的100%隔離,需要犧牲速度
- 可靠性:軟、硬件崩潰后,InnoDB數據表驅動會利用日志文件重構修改。可靠性和高速度不可兼得,innodb_flush_log_at_trx_commit選項,決定什么時候把事務保存到日志里
- BEGIN/START TRANSACTION:顯式地開啟一個事務
- COMMIT,也可以用COMMIT WORK,提交事務
- ROLLBACK,也可以用ROLLBACK WORK,回滾,撤銷正在運行的所有未提交的修改。
- SAVEPOINT identifier;允許在事務中創建一個保存點
- RELEASE SAVEPOINT identifier;刪除一個事務的保存點
- ROLLBACK TO identifier;把事務回滾到標記點
SQL標準定義了4類隔離級別,包括了一些具體規則,用來限定事務內外的哪些改變是可見的,哪些是不可見的。低級別的隔離級一般支持更高的并發處理,并擁有更低的系統開銷。
- Read Uncommitted(讀取未提交內容)
在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別很少用于實際應用,因為它的性能不比其他級別好多少。讀取未提交的數據,也被稱之為臟讀
臟讀:某個事務已更新一份數據,另一個事務在此時讀取了同一份數據,由于某些原因,前一個RollBack了操作,則后一個事務所讀取的數據就會是不正確的。
- Read Committed(讀取提交內容)
這是大多數數據庫系統的默認隔離級別(但不是mysql默認的)。它滿足了隔離的簡單定義:一個事務智能看見已提交事務所做的改變。這種隔離級別也支持所謂的不可重復讀(Nonrepeatable Read),因為同一事務的其他實例在該實例處理期間可能會有新的commit,所以同一select可能返回不同結果
不可重復讀(Non-replacetable read):在一個事務的兩次查詢之中數據不一致,這可能是兩次查詢過程中間插入了一個事務更新的原油的數據。
- Repeatable Read(可重讀)
這是mysql的默認事務隔離級別,它確保同一事務的多個實例在并發讀取數據時,會看到同樣的數據行。不過理論上,這會導致另一個棘手的問題:幻讀。簡單的說,幻讀指當用戶讀取某一范圍的數據行時,另一個事務又在該范圍內插入了新行,當用戶再讀取該范圍的數據行時,會發現有新的“幻影”行。InnoDB和Falcon存儲引擎通過多版本并發控制(MVCC)機制解決了該問題。
幻讀(Phantom Read):在一個事務的兩次查詢中數據不一致,例如有一個事務查詢了幾行數據,而另一個事務卻在此時插入了新的幾行數據,先前的事務在接下來的查詢中,就會發現有幾行數據是它先前所沒有的。
- Serializable(可串行化)
這是最高的隔離級別,它通過強制事務排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,它是在每個讀的數據行上加上共享鎖。這個級別,可能導致大量的超時現象和鎖競爭。
打開mysql配置文件:sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
保存配置文件,重啟mysql服務:sudo service mysql restart
訂單并發處理
多個用戶同事請求數據庫
(1)悲觀鎖
select * from df_goods_sku where id = 17 for update;
悲觀鎖獲取數據時對數據進行了鎖定,其他事務要想獲取鎖,必須等原事務結束。
(2)樂觀鎖
查詢時不鎖數據,提交更改時進行判斷
update df_goods_sku set stock=0,sales=1 where id=17
沖突比較少的時候,使用樂觀鎖
沖突比較多的時候,使用悲觀鎖
五、項目部署
1.uwsgi
遵循wsgi協議的web服務器
pip install uwsgi
項目部署時,需要把settings.py文件夾下的:
- 啟動:uwsgi–ini 配置文件路徑,例如:uwsgi–ini uwsgi.ini
- 停止:uwsgi–stop uwsgi.pid路徑,例如:uwsgi–stop uwsgi.pid
2.nginx
django settings.py中配置收集靜態文件路徑:
STATIC_ROOT=收集的靜態文件路徑 例如:/var/www/dailyfresh/static;
django 收集靜態文件的命令:
python manage.py collectstatic
執行上面的命令會把項目中所使用的靜態文件收集到STATIC_ROOT指定的目錄下。
收集完靜態文件之后,讓nginx提供靜態文件,需要在nginx配置文件中增加如下配置:
location /static {
alias /var/www/dailyfresh/static/;
}
在location對應的配置項中增加proxy_pass轉發的服務器地址。
如:當用戶訪問127.0.0.1時,在nginx中配置把這個請求轉發給172.16.179.131:80(nginx)服務器,讓這臺服務器提供靜態首頁。
location = /{
proxy_pass http://172.16.179.131;
}
9.2.4 nginx配置upstream實現負載均衡
ngnix 配置負載均衡時,在server配置的前面增加upstream配置項。
upstream dailyfresh {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
總結
- 上一篇: java c3p0获取主键_Tomcat
- 下一篇: netflix会员和非会员的区别_Net