好幾天沒有寫博客了,一直忙這寫這個積分投票-兌換禮包系統.有不少血淚的教訓來分享下:
以前,我一直是寫手機接口的,跟前端基本上沒有交集,即便有也是給內部提供管理平臺,此次能夠說給我上了一堂課:
1.實時性:大量的操做是創建在memcache緩存的基礎上的,mysql數據庫是爲了提供數據持久性和記錄日誌的.所以查詢以前會先訪問緩存,若是緩存不存在或者失效,去訪問數據庫.
2.數據量比較大:數據庫的索引沒有創建到最好.
3.權限的問題,不是全部人都擁有權限能夠投票,因而我把擁有權限的用戶id放入了一個數組中並放在緩存,同步到數據庫裏面,最後發現此次投票人數特別多,每次查詢一個用戶的權限,須要把全部人的權限都拿出來,使用in_array(),來判斷,主管發現後,果斷改啊,每一個用戶使用獨立的key來保存是否擁有權限.
4.安全性:從前端傳遞過來的參數要假設是不可靠的,在兌換禮包的時候,我從前端傳遞過來了禮包的類型和要扣除的積分,放入數據庫中,哎!首先悲劇的就是要扣除的積分不能是傳遞過來的,而是根據禮包的類型來判斷.而且要把禮包的類型作出範圍配置來檢查是否合法.剛寫完程序的時候,主管看了看而後請求了一個url: www.example.com/?type=6&score=1,原本第六個禮包要扣除積分80個,結果如今只扣除1個積分用戶就領取到了第六個禮包.而後要判斷禮包只有六中type應該大於1,小於7.寫成配置文件來判斷以下:html
/** * @brief 將禮包對應扣除的積分寫成配置,不要相信用戶提交的數據, * @return array(); */ public function getTypes() { return array( 11 => 5, //禮包1對應扣除的積分5,同下 12 => 10, 13 => 20, 14 => 30, 15 => 50, 16 => 80 ); }
5.防止刷積分的處理:若是用機器大量快速請求,有可能出現服務器掛掉,且出現一我的領取多個禮包,所以將用戶id:uid和禮包類型:type作惟一索引:
UNIQUE KEY unique_uid_type
(uid
,type
),
在memcache中存入一個1s過時的key,保證一個uid每秒只能領取一次禮包.前端
6.一些非實時的數據,採用數據查詢時從緩存中讀取,不存在再從數據庫讀取;增刪改時清除該key的緩存.下次從數據庫讀取.結果因爲只改變了查詢的時候的緩存的key,沒有改 增刪改 數據時緩存的key,致使數據所有從數據庫中讀取..所以必定要保證,寫入緩存和讀取緩存的key保持一致.不然...mysql
7.因爲有不少頁面,須要共享用戶的信息,而用戶信息須要通過處理,就把用戶的信息放到了__construct()裏面,也就是說全部的頁面都會處理用戶信息,結果有幾個頁面是不使用用戶信息的...sql
8.命名的規範:對緩存命名時必須遵循團隊規範,不然可能會和其餘開發人員發生緩存key衝突.數據庫
9.特殊字符的編碼處理:用戶名是utf-8編碼的,而程序中是gbk編碼的,結果轉碼後發現,用戶名凌亂了.處理辦法:copy到txt文檔中使用記事本打開,從新複製一遍,不少的用戶名中會出現特殊字符好比雙引號等,使用:htmlspecialchars();json
10.數據表中增長一個create_time,用來記錄時間排除bug數組
11.緩存設置的時間要根據具體的業務邏輯來設計,好比下面的場景:用戶投票和兌換積分通常時間不會超過十分鐘,所以,一些非實時的緩存的過時時間設置成10分鐘就夠了緩存
12.將全部權限的檢測封裝到一個函數中統一處理,是代碼更簡潔方便安全
13.json_encode()不能處理gbk編碼:json_encode('gbk','utf-8',$array);服務器
此次的任務作的太失敗了,太凌亂了,寫出來的總結感受也很凌亂,心情不爽,之後慢慢改吧!記錄下來作日誌,防止再犯一樣的錯誤