1. 程式人生 > >Java解決高併發秒殺

Java解決高併發秒殺

一:問題

首先我們要考慮的是為什麼要解決高併發,高併發瓶頸出現在哪裡,有了解過的朋友肯定知道是在資料庫,因為在大量請求去操作資料庫時會出現資料的錯亂,超賣,系統崩潰,mysql死鎖等現象。

二:思路

  • 1. 頁面靜態化:就是將整個頁面儲存到redis中,下次訪問時去讀取redis中的頁面值

  • 2. cdn:主要對整個網站的靜態資原始檔進行加速,如圖片,css,js等(去阿里看教程)

  • 3.數學驗證碼:使用者在計算驗證碼結果時可以減少大量請求同時進入,減少redis, mysql,伺服器的壓力。

  • 4:庫存標識:這是一個巨大優化,通過標識來判斷redis的庫存是否足夠,如不足就中斷去讀取redis庫存。例:boolean over = map.get(goodsId);當我們map通過key讀取到value值為true的時候,就返回錯誤提示給使用者, if(over) { return Result.error(‘庫存不足’); }.....這樣不管以後有多個請求進入都只執行兩行程式碼,以下的操作無法進入。

  • 5.生成動態url:主要是防止惡意使用者通過固定url進行提前秒殺商品(安全方面問題這個不可掉以輕心,你連安全措施都沒做好以下的那些操作都是白搭的)

  • 6. redis預減庫存:在使用者秒殺商品前去redis獲取當前的庫存數量,然後在秒殺時候直接減去redis儲存的庫存(大家放心這裡Redis和MySQL資料是同步的,只要進入MQ佇列操作完成下單,MySQL資料庫會-1數量),從而避開去MySQL讀取庫存資料。

  • 7. MQ訊息佇列:它是一箇中間訊息鍵,通過生產者傳送訊息給消費者,進行業務操作,而生產者無需知道執行結果,也就是使用者點選秒殺之後等待處理結果,之後再去輪詢查詢處理結果(非同步操作),這樣就避開了不斷請求去操作資料庫。(這裡的輪詢查詢也是直接從redis裡面去查詢,因為秒殺成功之後會將秒殺的結果放到redis中,輪詢時候通過key去查詢)

  • 8. Nginx:解決高併發的好方法,也就是我們多增加幾個tomcat伺服器。當用戶訪問的時候,請求可以提交到空閒的tomcat伺服器上。

  • 9.資料庫叢集、庫表雜湊

  ①大型網站都有複雜的應用,這些應用必須使用資料庫,那麼在面對大量訪問的時候,資料庫的瓶頸很快就能顯現出來,這時一臺資料庫將很快無法滿足應用,於是我們需要使用資料庫叢集或者庫表雜湊。

  ②在資料庫叢集方面,很多資料庫都有自己的解決方案,Oracle、Sybase等都有很好的方案,常用的MySQL提供的Master/Slave也是類似的方案,您使用了什麼樣的DB,就參考相應的解決方案來實施即可。

  ③上面提到的資料庫叢集由於在架構、成本、擴張性方面都會受到所採用DB型別的限制,於是我們需要從應用程式的角度來考慮改善系統架構,庫表雜湊是常用並且最有效的解決方案。

  ④我們在應用程式中安裝業務和應用或者功能模組將資料庫進行分離,不同的模組對應不同的資料庫或者表,再按照一定的策略對某個頁面或者功能進行更小的資料庫雜湊,比如使用者表,按照使用者ID進行表雜湊,這樣就能夠低成本的提升系統的效能並且有很好的擴充套件性。

  • 10.負載均衡

負載均衡將是大型網站解決高負荷訪問和大量併發請求採用的高階解決辦法。

  • 11.反向代理

客戶端直接訪問的伺服器並不是直接提供服務的伺服器,它從別的伺服器獲取資源,然後將結果返回給使用者。

代理伺服器和反向代理伺服器:

代理伺服器是代我們訪獲取資源,然後將結果返回。例如,訪問外網的代理伺服器。反向代理伺服器是我們正常訪問一臺伺服器的時候,伺服器自己呼叫了別的伺服器。

反向代理就是說,使用者的請求請求到負載均衡的裝置上,負載均衡裝置再講請求分發到空閒的應用伺服器上處理,處理完成之後再通過負載均衡裝置返回給使用者,這樣對於使用者來說,後來的分發是不可見的。

反向代理的實現

1)需要有一個負載均衡裝置來分發使用者請求,將使用者請求分發到空閒的伺服器上

2)伺服器返回自己的服務到負載均衡裝置

3)負載均衡將伺服器的服務返回使用者

代理伺服器我們主動使用,是為我們服務的,不需要有自己的域名;反向代理是伺服器自己使用的,我們並不知道,