2016年8月24日筆記

當我們再點下一頁,程序又正常工作了。剛剛出現的奇怪的那一幕,其實就是由于并發產生的沖突。

  1. 在什么地方我們做了并發操作了呢?其實就是在一個用戶瀏覽頁面的同時,
    還有人在往數據庫里面寫入數據。你會發現thinkPHP這樣的框架,還是PHPCMS
    這樣的開源系統,他們都存在這樣的bug。并發產生的問題,往往難以捕捉,更
    難以重現,而我們準備的這個案例,算是并發案例沖突中相對容易重新的典型案例

  2. 我們如果調整一下剛剛操作的順序,我們會得到一些其他的結果。
    比如說:我們分頁條目數是每頁5條,在用戶瀏覽某一頁的時候,后
    臺管理員發布了新的新聞,新聞的數量小于5條的情況下,我們點下
    一頁,會看到有幾條重復的新聞,也有更早的新聞這樣影響用戶體驗,
    但畢竟我們點一下一的頁時候內容還是能接的上的,用戶瀏覽某一頁
    的時候,后臺發布的新聞數量大于分頁條目數(5條)
    那么再點擊下一頁,其中會有若干條新聞被跳過去了,無論用戶點多
    少次下一頁,都看不到那些條目,這種產生的并發沖突后果是很嚴重
    的,而且普遍存在。他具有很好的隱蔽性,在過去很多年幾乎不被察覺

  3. 在大門戶網站時代,網站編輯并不會頻繁的發布新聞,而用戶也很
    少守著新聞列表去逐篇閱讀,然而在微博誕生以后,這種問題就暴露出來了。
    由于社區類應用信息的產生室友用戶產生的,不在是靠編輯在后臺發布的
    ,就好像微博,每時每分秒,都有很多用戶分享心得內容

  4. 這樣一來你在查看微博列表的同時,內容就已經更新 了 很多
    ,而且很多人打發無聊的時間,很多人也會去逐一查看,不停的上劃,
    把所有遺漏的條目全部看一遍

  5. 這是如果項目設計不合理,產生并發事故,就會對用戶體驗造成極大的影響。

  6. 來看一個更為常見的例子,大家可能還記得,我們在微信群搞的抽獎的互動,
    我們的上百份禮品,瞬間就被秒殺光。

  7. 在做這類搶購與秒殺抽獎等應用的時候,并發將導致更多的問題。通常
    比較容易出現的bug有實際商品的訂單量大于庫存量。通俗點來說就是,明
    明已經售完,但還是有用戶買到了商品,庫存值變為負的。又或者明明秒殺
    到商品的用戶,訂單失敗。

  8. 還有企業的項目,在商品秒殺期間,明明用戶數量不多,卻導致服務器
    宕機。諸如此類的問題就不一一列舉了。由于是文字直播,打字速度比較慢,
    大家可以看現在正在進行的視屏直播

  9. 看一下用常規思維來梳理業務流程程序是怎樣編寫的。

  10. 還是以商城秒殺業務為例。首先我們需要用產品庫存這樣的一個字段來記
    錄庫存信息,每當有用戶購買商品的時候,先查看庫存,判斷庫存大于0的時
    候,用戶才能購買

  11. 當用戶完成購買流程后,將庫存數量減一,直到所有商品賣完,重復此過
    程,直到庫存賣完秒殺活動結束。如果按常規的思路來設計,這樣的流程是沒
    有問題的,商品畢竟是一件一件賣出的,但是,在互聯網并發的情況下,就完
    全不是這樣的。

  12. 要知道熱銷商品很有可能在同一時間,有多個用戶都在進行購買流程操作

  13. 按照之前的業務設計,假如有ABCD 4個用戶同時在秒殺某件商品時,庫存
    僅剩2件,按照之前的業務流程設計查詢庫存大于0,就可以繼續后面的購買操
    作并付款然而當任意用戶購買成功后庫存即減一,ABCD4個用戶都認為自己查詢
    時都有庫存,因此他們都可以完成購買流程,導致的結果就是庫存數為負數。也
    就是說,商品實際銷售量大于活動的商品數量,這樣會導致公司的虧損。
    有些公司為了解決這個問題,采用了一種思路,雖說4個人同時操作,但是交易
    成功的這次網絡請求到達服務器的時間總會有個先后順序

  14. 那么可以將訂單支付成功之后的庫存減一之后的值也隨訂單保存,如果這個
    值小于0,就證明有用戶購買了產品,已經是賣完的,于是標記訂單失敗。

  15. 這樣看上去避免公司造成額外的損失,但卻會給用戶帶來極大的不滿,是一
    種極差的用戶體驗。它并沒有真正的解決我們的問題。當然還有些公司解決方案
    也不高明,我們知道無論是數據庫還是文件都可以給他加鎖,在很早期的程序設
    計和軟件開發里面,鎖是解決并發問題的萬能靈藥。無論是c++,或java,提到多
    進程或多線程的時候,往往也會提到鎖這個字。那么作為最早期的通用解決方案,
    用到秒殺方案是否合適呢?

  16. 看一下加鎖后的工作流程:還是ABCD 4個用戶同時秒殺,他們都去查詢庫存。
    當某一個用戶,比如A的請求,優先到達時,我們就將數據表鎖住,不讓其他的數
    據庫連接來動這張表,待用戶A完成購買流程,將庫存量減一后,把鎖打開,其他
    的連接才可以再次操作這張表。

  17. 如此一來,可以保障一個用戶查看庫存以及庫存減一這段時間內,不可能還有
    其他用戶可以對表做出修改,這一并發沖突的問題就沒有了。不過這樣的做法真的
    合適嗎?要知道ABCD 4個用戶都是在同一時間段去秒殺的,由于A用戶在操作中鎖
    表,導致其他用戶只能等待,而且A完成整個業務需要消耗一段時間,只能等A完成
    以后其他用戶才能操作

  18. 這樣一來單位時間內的業務處理量會大幅降低,我們所看到的現象就是網站卡
    死,或者服務器宕機關于并發性能如何設計,我們可能需要單獨的一次或幾次課來
    為大家講解。不過鎖這種很原始的并發沖突解決方案,我們可以看到他并不適合互
    聯網項目。之所以大家會有并發沖突的程序,是因為大部分程序員,思維模式都是
    線性的。

  19. 作為程序邏輯思維來講,線性思維是沒有錯的,因為計算機執行指令的時候本
    身就是線性的。然而如果把業務也看做是線性的,就會產生問題了。

  20. 任何一個程序操作,他都會消耗一定的時間,即便你的CPU速度再快,也只是
    縮短了這個時間范圍而已,如果只有一個用戶操作,比如我們在后臺發布文章,看
    自己發布的新聞,我們是無法感知并發帶來的沖突的。這就對我們的程序員提出了
    更高的要求。

  21. 理論上來講,所有跨越時間段的操作過程中如果涉及到數據修改就會有可能產
    生并發沖突,因此我們在設計程序的時候,要保障應用程序的質量,就需要去做并
    發沖突處理,只是實現業務需求與實現業務的同時做好質量需求,就是好程序員與
    壞程序員的差別。

  22. 那么分析了產生并發沖突的原因以后,就比較容易思考解決方案了。大體的思
    路有兩種:一種是將并發操作變為單線操作,另一種是讓所有跨越時間的段的操作
    不去更改數據。

  23. 我們現在來看一下分頁,或者上拉或者下拉刷新的解決方法。我們剛剛提出的
    2種的解決思路,哪一種比較合適呢?對于發布數據和瀏覽數據,比如微博,我們有
    可能把這種并發操作變為單線操作嗎?好像不太容易。那么我們能夠走得路就剩下
    第二條,也就是跨時間段的過程中不要改變數據,我們剛剛產生的bug到底是什么數
    據改變導致了bug?;仡櫹挛覀兊拇a實現的本質,就容易找到其中的緣由了。

  24. 通常我們在實現分頁的時候,首頁看到的是最新的數據,那么從數據庫中取數
    據的sel語句是select * from news order by desc limt 0,10,這樣取到
    最新的數據,如果點擊下一頁,查詢語句不變,只是分頁條目不在是第0-9,而是
    第10-19條,如果在這個過程中有新的數據插入,我們會發現有一個東西變了,就
    是原有數據在數據庫的排序序號變了,如果我新發布一條數據,原來的第一條最新
    的新聞就會變成第二條,原來的第10條會變成第11條。這就是一個時間段內的操作
    過程中有數據發生了改變。

  25. 既然我們無法把這樣的并發操作變成單線操作,我們可以選擇不讓數據發生改
    變,這樣并發bug就可以得到很好的解決了。

  26. 需要了解詳細解決方案的,我會把無bug程序實例分享給大家。課后可以聯系
    赫赫要資料,或者是聽我們的視屏直播課,陳老師有詳細的解決。

  27. 跨時間段的讓數據不改變不好走,那我們可以選擇第一種思路,讓并發操作變
    為單線操作,之前提到的加鎖是解決方案之一,但是對用戶體驗不好性能很差,基
    本上無法再互聯網項目中使用。如果不能加鎖,那么常用的解決方案是什么?

  28. 我們可以用隊列。如果我們將所有的用戶請求進行排隊,有一個服務來訂閱這
    個隊列,那么不管有多少用戶訪問,最終到服務器端,處理服務的就只有一個進程。
    這樣就實現了一個由并發操作轉換成單線操作。

  29. 關于消息隊列的使用以及本地服務的相關知識,在源代碼的技術經理/架構師
    在線課中為大家詳盡的展示。這個課程的眾籌將會在明天晚上8點開始,眾籌的規
    則和細節都已經出來了,前期眾籌的費用主要用來購買阿里云的服務,搭建實驗環境。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,214評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,315評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,699評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,882評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,441評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,189評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,388評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,613評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,112評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,334評論 2 377

推薦閱讀更多精彩內容