秒殺項目具備不少的重要知識點,本片博客記錄在解決秒殺項目中產生的各類問題時,遇到的一些小知識點和問題以及解決方案。css
根據項目中的使用和網上的一些貼子,我我的總結如下內容html
@Component,就是把普通pojo實例化到spring容器中,至關於配置文件中的<bean id="" class=""/>前端
若是在項目中遇到須要把一個類實例化注入到spring容器中,可是此類不在一些掃描的包下,好比controller、service,就能夠加上次註解,進行注入jquery
此處是秒殺項目中,經過消息中間件獲取消息的類GetMessageUtils,它不在被掃描的包下,加上此註解,就可注入spring容器中redis
次註解做用的類是全局捕獲異常類,只要做用在@RequestMapping上,全部的異常都會被捕獲spring
項目中使用了異常捕獲返回json給前端的方法,後臺報異常,同時返回給前端,本項目中使用了自定義異常,包含各類失敗信息,而使用次註解就能捕獲全部異常類數據庫
能夠獲取當前url中的參數,經過名稱便可獲取json
function GetQueryString(name){後端
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);//search,查詢?後面的參數,並匹配正則
if(r!=null)return unescape(r[2]); return null;
}
項目使用先後端分離,頁面在跳轉時帶有參數,就可使用該方法,在獲取是調用該方法,直接經過名稱課能夠獲取
秒殺項目中會用到倒計時插件,在這裏記錄一下我使用的倒計時插件以及使用緩存
引入js: <script src="http://cdn.bootcss.com/jquery.countdown/2.1.0/jquery.countdown.min.js"></script>
代碼中使用:
seckillBox.countdown(beginTime, function (event) { -----------此處beginTime爲活動開始時間,從後臺獲取服務器時間
//時間格式
var format = event.strftime('秒殺倒計時: %D天 %H時 %M分 %S秒 '); ---------------此處初始化倒計時時間格式
seckillBox.html(format); ------------------此處爲把此時間格式添加到頁面中
}).on('finish.countdown', function () { -------------------此處爲倒計時插件的倒計時結束後執行方法 ,倒計時結束執行此方法
seckillStart(itemPromo.id,itemPromo.itemId,token,username); -----------此處爲倒計時結束後執行的方法,可本身根據業務需求編寫方法
});
在獲取商品詳情頁面中,因爲用戶數量多,刷新頁面頻繁,致使訪問量大,咱們採起redis做爲緩存,可是即便如此,訪問量也是很大,因此採用guava cache做爲一級緩存,緩存到本地,用戶訪問詳情頁面,先從本地獲取,若是沒有,在從redis緩存中獲取,若是尚未,則訪問數據庫,點擊此連接獲取guava具體使用方法:http://www.javashuo.com/article/p-naefnjlu-dv.html
具體代碼:(該方法在service層中實現)
public ItemPromoDetail getItemById(int itemId) {
ItemPromoDetail promo = null;
//由於活動未開始時,用戶會一直刷新詳情頁,因此加一個緩存
//Guava Cache 作一級緩存,用redis作二級緩存
//商品詳情和庫存分別存放
Object obj = localCacheService.getFromCommonCache("ITEMID:" + itemId);
if (obj == null) {
//從redis中獲取
if (jedisClient.exists("ITEMID:"+ itemId )){
String jsonObj = jedisClient.get("ITEMID:"+itemId);
promo = JsonUtils.jsonToPojo(jsonObj, ItemPromoDetail.class);
}else {
promo = promoMapper.getItemById(itemId);
//將庫存也存放如redis中
int stockNum = promo.getStock();
jedisClient.set("ITEM_STOCK:"+itemId,stockNum+"");
//獲取商品時,根據庫存能夠設置大閘的數量
jedisClient.set("ITEM_DAZHA:"+itemId,(stockNum*5)+"");
String json = JsonUtils.objectToJson(promo);
jedisClient.set("ITEMID:"+itemId, json);
localCacheService.setCommonCache("ITEMID:"+itemId,promo);
}
}else {
promo = (ItemPromoDetail) obj;
}
promo.setStock(Integer.valueOf(jedisClient.get("ITEM_STOCK:"+itemId)));
return promo;
}