大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 Redis隊列實現高并發的步驟

Redis隊列實現高并發的步驟

更新時間:2022-12-08 10:47:02 來源:動力節點 瀏覽1116次

Redis隊列實現高并發的步驟是什么?動力節點小編來告訴大家。

高并發的業務場景:

我們做商品搶購功能,要面臨的第一個問題就是數據不能異常,而保證數據不異常我們的解決辦法有很多比如說數據庫的鎖機制,或者先改后查的方式都能解決,但是第二個問題來了如果我們用上述技術解決,數據是不會異常了,但是我們的服務器壓力就會很大了,從而使服務器宕機,那么我們如何使服務器壓力減小還能保證數據不異常呢,我們可以使用隊列的思想,下面我們介紹的是使用redis隊列解決高并發的問題。

設計思路

用戶在下訂單之前當然是先查詢到這個商品,在這個查詢的時候,將數據庫中商品的剩余數量存到redis中;

服務器在一瞬間接到成千上萬的下訂單請求,在控制層沒有直接處理請求數據,而是先根據redis中商品的剩余數量來判斷,如果>0,就將請求放到請求隊列中,否則直接響應客戶端“賣完了”;

考慮到數據的一致性,隊列的容量就是商品的剩余數量,隊列采用的是線程安全的隊列LinkedBlockingQueue(單臺服務器),然后通過新的線程異步處理這些請求,多臺服務器的話,可以考慮使用消息隊列MQ,單獨用一臺服務器去處理消息隊列中的請求;

客戶端發送訂單請求之后,會收到響應,要么是剩余數量不足(賣完了),要么是請求已經被放到隊列中,為下一步的輪詢訂單做準備;

如果響應狀態是賣完了,直接提示客戶,如果請求已經放入隊列中,就可以根據用戶id和商品id去輪詢訂單了;

實現步驟

說明:用java語言,springmvc框架+redis實現

準備工作,查詢商品信息,將剩余數量同步到redis中

Jedis jedis = jedisPool.getResource();
BuyGood good=buyGoodService.getById(good_id);
jedis.set("residue"+good_id, good.getResidue()+"");
jedisPool.returnResource(jedis);

下訂單的方法,下面直接展示代碼,包括請求對象,控制層方法,請求處理線程類的具體實現

請求封裝對象

public class BuyRequest {
private int good_id;//商品id
private int user_id;//用戶ID
private int order_id;//訂單id
private BuyOrders buyOrders;//訂單信息
private int response_status;//0:未處理;1:正常;2:異常
public BuyOrders getBuyOrders() {
return buyOrders;
}
public void setBuyOrders(BuyOrders buyOrders) {
this.buyOrders = buyOrders;
}
public int getGood_id() {
return good_id;
}
public void setGood_id(int good_id) {
this.good_id = good_id;
}
public int getOrder_id() {
return order_id;
}
public void setOrder_id(int order_id) {
this.order_id = order_id;
}
public int getResponse_status() {
return response_status;
}
public void setResponse_status(int response_status) {
this.response_status = response_status;
}
public int getUser_id() {
return user_id;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
}

處理請求的controller

@Controller
@RequestMapping("/buy")
public class BuyController {
private static BuyQueuebuyqueue =null;//線程安全的請求隊列
@RequestMapping("/addOrders.do")
@ResponseBody
public Object addOrders(BuyRequest buyrequest){
Mapresults = new HashMap<>();
Jedis jedis = jedisPool.getResource();
try {
//下訂單之前,先獲取商品的剩余數量
int residue = 
Integer.valueOf(jedis.get("residue"+buyrequest.getGood_id()));
if(residue<1){//如果剩余數量不足,直接響應客戶端“賣完了”
results.put("msg", "賣完了");
results.put("done", false);
BaseLog.info("addOrders results="+JSON.toJSONString(results));
return results;
}
//如果還有剩余商品,就準備將請求放到請求隊列中
if(buyqueue==null){//第一次初始化請求隊列,隊列的容量為當前的商品剩余數量
buyqueue=new BuyQueue(residue);
}
if(buyqueue.remainingCapacity()>0){//當隊列的可用容量大于0時,將請求放到請求隊列中
buyqueue.put(buyrequest);
}else{//當請求隊列已滿,本次請求不能處理,直接響應客戶端提示請求隊列已滿
results.put("msg", "搶購隊列已滿,請稍候重試!");
results.put("done", false);
return results;
}
if(!DealQueueThread.excute){//如果線程類的當前執行標志為未執行,即空閑狀態,通過線程池啟動線程
DealQueueThread dealQueue = new DealQueueThread(buyqueue);
ThreadPoolUtil.pool.execute(dealQueue);
BaseLog.info("Thread.activeCount()="+Thread.activeCount());
}
//請求放入到隊列中,即完成下單請求
results.put("done", true);
results.put("msg", "下訂單成功");
} catch (Exception e) {
results.put("done", false);
results.put("msg", "下單失敗");
BaseLog.info("addOrders results="+JSON.toJSONString(results));
BaseLog.error("addOrders",e);
}finally{
jedisPool.returnResource(jedis);
}
return results;
}
}

處理請求的線程類

@Component
public class DealQueueThread implements Runnable {
private static DealQueueThread dealQueueThread;
@Autowired
BuyGoodService buyGoodService;
@Autowired
BuyOrdersService buyOrdersService;
@Autowired
JedisPool jedisPool;
private Jedis jedis;
private BuyQueuebuyqueue;
public static boolean excute = false;//線程的默認執行標志為未執行,即空閑狀態
public DealQueueThread() {
}
public DealQueueThread(BuyQueuebuyqueue) {
this.buyqueue = buyqueue;
jedis = dealQueueThread.jedisPool.getResource();
}
@PostConstruct
public void init() {
dealQueueThread = this;
dealQueueThread.buyGoodService = this.buyGoodService;
dealQueueThread.buyOrdersService = this.buyOrdersService;
dealQueueThread.jedisPool = this.jedisPool;
}
@Override
public void run() {
try {
excute = true;//修改線程的默認執行標志為執行狀態
//開始處理請求隊列中的請求,按照隊列的FIFO的規則,先處理先放入到隊列中的請求
while (buyqueue != null && buyqueue.size() > 0) {
BuyRequest buyreq = buyqueue.take();//取出隊列中的請求
dealWithQueue(buyreq);//處理請求
}
} catch (InterruptedException e) {
BaseLog.error("DealQueueThread:", e);
} finally {
excute = false;
}
}
public synchronized void dealWithQueue(BuyRequest buyreq) {
try {
//為了盡量確保數據的一致性,處理之前先從redis中獲取當前搶購商品的剩余數量
int residue = Integer.valueOf(jedis.get("residue" + 
buyreq.getGood_id()));
if (residue < 1) {//如果沒有剩余商品,就直接返回
buyreq.setResponse_status(3);
return;
}
//如果有剩余商品,先在redis中將剩余數量減一,再開始下訂單
jedis.decr("residue" + buyreq.getGood_id());
//將數據庫中將剩余數量減一,這一步處理可以在隊列處理完成之后一次性更新剩余數量
dealQueueThread.buyGoodService.minusResidue(buyreq.getGood_id());
//處理請求,下訂單
BuyOrders bo = new BuyOrders();
bo.setGood_id(buyreq.getGood_id());
bo.setUser_id(buyreq.getUser_id());
int order_id = dealQueueThread.buyOrdersService.insert(bo);
BuyOrders orders = dealQueueThread.buyOrdersService.getById(order_id);
buyreq.setOrder_id(order_id);//訂單id
buyreq.setBuyOrders(orders);//訂單信息
buyreq.setResponse_status(1);//處理完成狀態
} catch (Exception e) {
buyreq.setResponse_status(2);//異常狀態
BaseLog.error("DealQueueThread dealWithQueue:", e);
}
}
}

輪詢訂單

思路:查詢訂單和剩余數量,有以下三種情況:

1.查到訂單,直接跳轉到確認訂單并支付的頁面完成支付;

2.還沒有查詢到訂單,但是剩余數量大于0,說明請求還在隊列中,繼續輪詢;

3.沒有查到訂單,剩余數量等于或小于0,說明搶購失敗了,直接響應客戶搶購失敗;

以上就是關于“Redis隊列實現高并發的步驟”介紹,大家如果想了解更多相關知識,不妨來關注一下本站的Redis教程,里面還有更豐富的知識等著大家去學習,相信對大家一定會有所幫助的。

提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 精品一区二区视频在线观看 | 99在线精品日韩一区免费国产 | 亚洲精品tv久久久久 | 福利视频一区 | 日本一区二区三 | 亚洲另类 专区 欧美 制服 | 亚洲精品欧美精品中文字幕 | 欧美高清在线视频在线99精品 | 日韩精品一区二区三区中文在线 | 国产一区二区三区视频在线观看 | 国产精品美女久久久久 | 国产成人精品一区二三区2022 | 四虎国产永久在线精品免费观看 | 不卡影院| 欧洲美女啪啪 | 久久婷婷午色综合夜啪 | 欧美成人h | 久久99国产精品二区不卡 | 成人国产一区二区三区 | 九九亚洲综合精品自拍 | 人人乳乳香蕉大免费 | 亚洲综合国产一区在线 | 四虎最新地址 | 狠狠操天天射 | 精品国产欧美一区二区最新 | 狠狠88综合久久久久综合网 | 亚洲视频在线观看地址 | 高清欧美一区二区免费影视 | 久99久热| 亚洲国产精品免费在线观看 | 久久成人综合 | 亚洲综合久久久久久中文字幕 | 天天做夜夜操 | 国产一区二区三区在线观看视频 | 日日操夜夜骑 | 国产在线公开视频 | 久操视频在线免费观看 | 香蕉视频在线观看男女 | 国产亚洲精品福利 | 校园春色男人天堂 | 久久久久久综合对白国产 |