国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

做兼職的網站是不是真的嗎重慶整站seo

做兼職的網站是不是真的嗎,重慶整站seo,藍眾建站_專業(yè)網站建設,網站建設報價單格式文章目錄 前言順序問題1. 為什么要保證消息的順序?2.如何保證消息順序?3.出現意外4.解決過程 消息積壓1. 消息體過大2. 路由規(guī)則不合理3. 批量操作引起的連鎖反應4. 表過大 主鍵沖突數據庫主從延遲重復消費多環(huán)境消費問題后記 前言 假如有家公司是做餐飲…

文章目錄

  • 前言
  • 順序問題
    • 1. 為什么要保證消息的順序?
    • 2.如何保證消息順序?
    • 3.出現意外
    • 4.解決過程
  • 消息積壓
    • 1. 消息體過大
    • 2. 路由規(guī)則不合理
    • 3. 批量操作引起的連鎖反應
    • 4. 表過大
  • 主鍵沖突
  • 數據庫主從延遲
  • 重復消費
  • 多環(huán)境消費問題
  • 后記

前言

假如有家公司是做餐飲系統(tǒng)的,每天中午和晚上用餐高峰期,系統(tǒng)的并發(fā)量不容小覷。為了保險起見,公司規(guī)定各部門都要在吃飯的時間輪流值班,保證出現線上問題時能夠及時處理。

有個后廚顯示系統(tǒng)團隊【面向的是廚師和服務員】,該系統(tǒng)屬于訂單【面向用戶】的下游業(yè)務。用戶點完菜下單后,訂單系統(tǒng)會通過發(fā)kafka消息給我們系統(tǒng),系統(tǒng)讀取消息后,做業(yè)務邏輯處理,持久化訂單和菜品數據,然后展示到劃菜客戶端。這樣廚師就知道哪個訂單要做哪些菜,有些菜做好了,就可以通過該系統(tǒng)出菜。系統(tǒng)自動通知服務員上菜,如果服務員上完菜,修改菜品上菜狀態(tài),用戶就知道哪些菜已經上了,哪些還沒有上。這個系統(tǒng)可以大大提高后廚到用戶的效率。

在這里插入圖片描述

事實證明,這一切的關鍵是消息中間件:kafka,如果它有問題,將會直接影響到后廚顯示系統(tǒng)的功能。

接下來,我跟大家一起聊聊使用kafka的過程中踩過哪些坑?

順序問題

1. 為什么要保證消息的順序?

剛開始我們系統(tǒng)的商戶很少,為了快速實現功能,我們沒想太多。既然是走消息中間件kafka通信,訂單系統(tǒng)發(fā)消息時將訂單詳細數據放在消息體,我們后廚顯示系統(tǒng)只要訂閱topic,就能獲取相關消息數據,然后處理自己的業(yè)務即可。

不過這套方案有個關鍵因素:要保證消息的順序。

為什么呢?

訂單有很多狀態(tài),比如:下單、支付、完成、撤銷等,不可能下單的消息都沒讀取到,就先讀取支付或撤銷的消息吧,如果真的這樣,數據不是會產生錯亂?

好吧,看來保證消息順序是有必要的。

2.如何保證消息順序?

我們都知道kafka的topic是無序的,但是一個topic包含多個partition,每個partition內部是有序的。

在這里插入圖片描述

如此一來,思路就變得清晰了:只要保證生產者寫消息時,按照一定的規(guī)則寫到同一個partition,不同的消費者讀不同的partition的消息,就能保證生產和消費者消息的順序。

我們剛開始就是這么做的,同一個商戶編號(并非訂單編號)的消息寫到同一個partition,topic中創(chuàng)建了4個partition,然后部署了4個消費者節(jié)點,構成消費者組,一個partition對應一個消費者節(jié)點。從理論上說,這套方案是能夠保證消息順序的。
在這里插入圖片描述

一切規(guī)劃得看似“天衣無縫”,我們就這樣”順利“上線了。

3.出現意外

該功能上線了一段時間,剛開始還是比較正常的。

但是,好景不長,很快就收到用戶投訴,說在劃菜客戶端有些訂單和菜品一直看不到,無法劃菜。

我定位到了原因,公司在那段時間網絡經常不穩(wěn)定,業(yè)務接口時不時報超時,業(yè)務請求時不時會連不上數據庫。

這種情況對順序消息的打擊,可以說是毀滅性的。

為什么這么說?

假設訂單系統(tǒng)發(fā)了:”下單“、”支付“、”完成“ 三條消息。
在這里插入圖片描述

而“下單”消息由于網絡原因我們系統(tǒng)處理失敗了,而后面的兩條消息的數據是無法入庫的,因為只有“下單”消息的數據才是完整的數據,其他類型的消息只會更新狀態(tài)。

加上,我們當時沒有做失敗重試機制,使得這個問題被放大了。問題變成:一旦“下單”消息的數據入庫失敗,用戶就永遠看不到這個訂單和菜品了。

那么這個緊急的問題要如何解決呢?

4.解決過程

最開始我們的想法是:在消費者處理消息時,如果處理失敗了,立馬重試3-5次。但如果有些請求要第6次才能成功怎么辦?不可能一直重試呀,這種同步重試機制,會阻塞其他商戶訂單消息的讀取。

顯然用上面的這種同步重試機制在出現異常的情況,會嚴重影響消息消費者的消費速度,降低它的吞吐量。

如此看來,我們不得不用異步重試機制了。

如果用異步重試機制,處理失敗的消息就得保存到重試表下來。

但有個新問題立馬出現:只存一條消息如何保證順序?

存一條消息的確無法保證順序,假如:“下單”消息失敗了,還沒來得及異步重試。此時,“支付”消息被消費了,它肯定是不能被正常消費的。

此時,“支付”消息該一直等著,每隔一段時間判斷一次,它前面的消息都有沒有被消費?

如果真的這么做,會出現兩個問題:

  1. “支付”消息前面只有“下單”消息,這種情況比較簡單。但如果某種類型的消息,前面有N多種消息,需要判斷多少次呀,這種判斷跟訂單系統(tǒng)的耦合性太強了,相當于要把他們系統(tǒng)的邏輯搬一部分到我們系統(tǒng)。

  2. 影響消費者的消費速度

這時有種更簡單的方案浮出水面:消費者在處理消息時,先判斷該訂單號在重試表有沒有數據,如果有則直接把當前消息保存到重試表。如果沒有,則進行業(yè)務處理,如果出現異常,把該消息保存到重試表。

后來我們用定時任務建立了失敗重試機制,如果重試了7次后還是失敗,則將該消息的狀態(tài)標記為失敗,發(fā)郵件通知開發(fā)人員。

終于由于網絡不穩(wěn)定,導致用戶在劃菜客戶端有些訂單和菜品一直看不到的問題被解決了?,F在商戶頂多偶爾延遲看到菜品,比一直看不菜品好太多。

消息積壓

隨著銷售團隊的市場推廣,我們系統(tǒng)的商戶越來越多。隨之而來的是消息的數量越來越大,導致消費者處理不過來,經常出現消息積壓的情況。對商戶的影響非常直觀,劃菜客戶端上的訂單和菜品可能半個小時后才能看到。一兩分鐘還能忍,半個小時的延遲,對有些暴脾氣的商戶哪里忍得了,馬上投訴過來了。我們那段時間經常接到商戶投訴說訂單和菜品有延遲。

雖說,加服務器節(jié)點就能解決問題,但是按照公司為了省錢的慣例,要先做系統(tǒng)優(yōu)化,所以我們開始了消息積壓問題解決之旅。

1. 消息體過大

雖說kafka號稱支持百萬級的TPS,但從producer發(fā)送消息到broker需要一次網絡IO,broker寫數據到磁盤需要一次磁盤IO(寫操作),consumer從broker獲取消息先經過一次磁盤IO(讀操作),再經過一次網絡IO。

在這里插入圖片描述

一次簡單的消息從生產到消費過程,需要經過2次網絡IO和2次磁盤IO。如果消息體過大,勢必會增加IO的耗時,進而影響kafka生產和消費的速度。消費者速度太慢的結果,就會出現消息積壓情況。

除了上面的問題之外,消息體過大,還會浪費服務器的磁盤空間,稍不注意,可能會出現磁盤空間不足的情況。

此時,我們已經到了需要優(yōu)化消息體過大問題的時候。

如何優(yōu)化呢?

我們重新梳理了一下業(yè)務,沒有必要知道訂單的中間狀態(tài),只需知道一個最終狀態(tài)就可以了。

如此甚好,我們就可以這樣設計了:

  1. 訂單系統(tǒng)發(fā)送的消息體只用包含:id和狀態(tài)等關鍵信息。
  2. 后廚顯示系統(tǒng)消費消息后,通過id調用訂單系統(tǒng)的訂單詳情查詢接口獲取數據。
  3. 后廚顯示系統(tǒng)判斷數據庫中是否有該訂單的數據,如果沒有則入庫,有則更新。
    在這里插入圖片描述

果然這樣調整之后,消息積壓問題很長一段時間都沒再出現。

2. 路由規(guī)則不合理

還真別高興的太早,有天中午又有商戶投訴說訂單和菜品有延遲。我們一查kafka的topic竟然又出現了消息積壓。

但這次有點詭異,不是所有partition上的消息都有積壓,而是只有一個。

圖片

剛開始,我以為是消費那個partition消息的節(jié)點出了什么問題導致的。但是經過排查,沒有發(fā)現任何異常。

這就奇怪了,到底哪里有問題呢?

后來,我查日志和數據庫發(fā)現,有幾個商戶的訂單量特別大,剛好這幾個商戶被分到同一個partition,使得該partition的消息量比其他partition要多很多。

這時我們才意識到,發(fā)消息時按商戶編號路由partition的規(guī)則不合理,可能會導致有些partition消息太多,消費者處理不過來,而有些partition卻因為消息太少,消費者出現空閑的情況。

為了避免出現這種分配不均勻的情況,我們需要對發(fā)消息的路由規(guī)則做一下調整。

我們思考了一下,用訂單號做路由相對更均勻,不會出現單個訂單發(fā)消息次數特別多的情況。除非是遇到某個人一直加菜的情況,但是加菜是需要花錢的,所以其實同一個訂單的消息數量并不多。

調整后按訂單號路由到不同的partition,同一個訂單號的消息,每次到發(fā)到同一個partition。

圖片

調整后,消息積壓的問題又有很長一段時間都沒有再出現。我們的商戶數量在這段時間,增長的非???#xff0c;越來越多了。

3. 批量操作引起的連鎖反應

在高并發(fā)的場景中,消息積壓問題,可以說如影隨形,真的沒辦法從根本上解決。表面上看,已經解決了,但后面不知道什么時候,就會冒出一次,比如這次:

有天下午,產品過來說:有幾個商戶投訴過來了,他們說菜品有延遲,快查一下原因。

這次問題出現得有點奇怪。

為什么這么說?

首先這個時間點就有點奇怪,平常出問題,不都是中午或者晚上用餐高峰期嗎?怎么這次問題出現在下午?

根據以往積累的經驗,我直接看了kafka的topic的數據,果然上面消息有積壓,但這次每個partition都積壓了十幾萬的消息沒有消費,比以往加壓的消息數量增加了幾百倍。這次消息積壓得極不尋常。

我趕緊查服務監(jiān)控看看消費者掛了沒,還好沒掛。又查服務日志沒有發(fā)現異常。這時我有點迷茫,碰運氣問了問訂單組下午發(fā)生了什么事情沒?他們說下午有個促銷活動,跑了一個JOB批量更新過有些商戶的訂單信息。

這時,我一下子如夢初醒,是他們在JOB中批量發(fā)消息導致的問題。怎么沒有通知我們呢?實在太坑了。

雖說知道問題的原因了,倒是眼前積壓的這十幾萬的消息該如何處理呢?

此時,如果直接調大partition數量是不行的,歷史消息已經存儲到4個固定的partition,只有新增的消息才會到新的partition。我們重點需要處理的是已有的partition。

直接加服務節(jié)點也不行,因為kafka允許同組的多個partition被一個consumer消費,但不允許一個partition被同組的多個consumer消費。

看來只有用多線程處理了。

為了緊急解決問題,我改成了用線程池處理消息,核心線程和最大線程數都配置成了50。

調整之后,果然,消息積壓數量不斷減少。

但此時有個更嚴重的問題出現:我收到了報警郵件,有兩個訂單系統(tǒng)的節(jié)點down機了。

不久,訂單組的同事過來找我說,我們系統(tǒng)調用他們訂單查詢接口的并發(fā)量突增,超過了預計的好幾倍,導致有2個服務節(jié)點掛了。他們把查詢功能單獨整成了一個服務,部署了6個節(jié)點,掛了2個節(jié)點,再不處理,另外4個節(jié)點也會掛。訂單服務可以說是公司最核心的服務,它掛了公司損失會很大,情況萬分緊急。

為了解決這個問題,只能先把線程數調小。

幸好,線程數是可以通過zookeeper動態(tài)調整的,我把核心線程數調成了8個,核心線程數改成了10個。

后面,運維把訂單服務掛的2個節(jié)點重啟后恢復正常了,以防萬一,再多加了2個節(jié)點。為了確保訂單服務不會出現問題,就保持目前的消費速度,后廚顯示系統(tǒng)的消息積壓問題,1小時候后也恢復正常了。
在這里插入圖片描述

后來,我們開了一次復盤會,得出的結論是:

  1. 訂單系統(tǒng)的批量操作一定提前通知下游系統(tǒng)團隊。
  2. 下游系統(tǒng)團隊多線程調用訂單查詢接口一定要做壓測。
  3. 這次給訂單查詢服務敲響了警鐘,它作為公司的核心服務,應對高并發(fā)場景做的不夠好,需要做優(yōu)化。
  4. 對消息積壓情況加監(jiān)控。

順便說一下,對于要求嚴格保證消息順序的場景,可以將線程池改成多個隊列,每個隊列用單線程處理。

4. 表過大

為了防止后面再次出現消息積壓問題,消費者后面就一直用多線程處理消息。

但有天中午我們還是收到很多報警郵件,提醒我們kafka的topic消息有積壓。我們正在查原因,此時產品跑過來說:又有商戶投訴說菜品有延遲,趕緊看看。這次她看起來有些不耐煩,確實優(yōu)化了很多次,還是出現了同樣的問題。

在外行看來:為什么同一個問題一直解決不了?

其實技術心里的苦他們是不知道的。

表面上問題的癥狀是一樣的,都是出現了菜品延遲,他們知道的是因為消息積壓導致的。但是他們不知道深層次的原因,導致消息積壓的原因其實有很多種。這也許是使用消息中間件的通病吧。

我沉默不語,只能硬著頭皮定位原因了。

后來我查日志發(fā)現消費者消費一條消息的耗時長達2秒。以前是500毫秒,現在怎么會變成2秒呢?

奇怪了,消費者的代碼也沒有做大的調整,為什么會出現這種情況呢?

查了一下線上菜品表【訂單服務】,單表數據量竟然到了幾千萬,其他的劃菜表也是一樣,現在單表保存的數據太多了。

我們組梳理了一下業(yè)務,其實菜品在客戶端只展示最近3天的即可。

這就好辦了,我們服務端存著多余的數據,不如把表中多余的數據歸檔。于是,DBA幫我們把數據做了歸檔,只保留最近7天的數據。

如此調整后,消息積壓問題被解決了,又恢復了往日的平靜。

主鍵沖突

別高興得太早了,還有其他的問題,比如:報警郵件經常報出數據庫異常: Duplicate entry ‘6’ for key ‘PRIMARY’,說主鍵沖突。

出現這種問題一般是由于有兩個以上相同主鍵的sql,同時插入數據,第一個插入成功后,第二個插入的時候會報主鍵沖突。表的主鍵是唯一的,不允許重復。

我仔細檢查了代碼,發(fā)現代碼邏輯會先根據主鍵從表中查詢訂單是否存在,如果存在則更新狀態(tài),不存在才插入數據,沒得問題。

這種判斷在并發(fā)量不大時,是有用的。但是如果在高并發(fā)的場景下,兩個請求同一時刻都查到訂單不存在,一個請求先插入數據,另一個請求再插入數據時就會出現主鍵沖突的異常。

解決這個問題最常規(guī)的做法是:加鎖。

我剛開始也是這樣想的,加數據庫悲觀鎖肯定是不行的,太影響性能。加數據庫樂觀鎖,基于版本號判斷,一般用于更新操作,像這種插入操作基本上不會用。

剩下的只能用分布式鎖了,我們系統(tǒng)在用redis,可以加基于redis的分布式鎖,鎖定訂單號。

但后面仔細思考了一下:

  1. 加分布式鎖也可能會影響消費者的消息處理速度。
  2. 消費者依賴于redis,如果redis出現網絡超時,我們的服務就悲劇了。

所以,我也不打算用分布式鎖。

而是選擇使用mysql的INSERT INTO …ON DUPLICATE KEY UPDATE語法:

INSERT INTO table (column_list)
VALUES (value_list)
ON DUPLICATE KEY UPDATE
c1 = v1, 
c2 = v2,
...;

它會先嘗試把數據插入表,如果主鍵沖突的話那么更新字段。

把以前的insert語句改造之后,就沒再出現過主鍵沖突問題。

數據庫主從延遲

不久之后的某天,又收到商戶投訴說下單后,在劃菜客戶端上看得到訂單,但是看到的菜品不全,有時甚至訂單和菜品數據都看不到。

這個問題跟以往的都不一樣,根據以往的經驗先看kafka的topic中消息有沒有積壓,但這次并沒有積壓。

再查了服務日志,發(fā)現訂單系統(tǒng)接口返回的數據有些為空,有些只返回了訂單數據,沒返回菜品數據。

這就非常奇怪了,我直接過去找訂單組的同事。他們仔細排查服務,沒有發(fā)現問題。這時我們不約而同的想到,會不會是數據庫出問題了,一起去找DBA。果然,DBA發(fā)現數據庫的主庫同步數據到從庫,由于網絡原因偶爾有延遲,有時延遲有3秒。

如果我們的業(yè)務流程從發(fā)消息到消費消息耗時小于3秒,調用訂單詳情查詢接口時,可能會查不到數據,或者查到的不是最新的數據。

這個問題非常嚴重,會導致直接我們的數據錯誤。

為了解決這個問題,我們也加了重試機制。調用接口查詢數據時,如果返回數據為空,或者只返回了訂單沒有菜品,則加入重試表。

調整后,商戶投訴的問題被解決了。

重復消費

kafka消費消息時支持三種模式:

  • at most once模式 最多一次。保證每一條消息commit成功之后,再進行消費處理。消息可能會丟失,但不會重復。
  • at least once模式 至少一次。保證每一條消息處理成功之后,再進行commit。消息不會丟失,但可能會重復。
  • exactly once模式 精確傳遞一次。將offset作為唯一id與消息同時處理,并且保證處理的原子性。消息只會處理一次,不丟失也不會重復。但這種方式很難做到。

kafka默認的模式是at least once,但這種模式可能會產生重復消費的問題,所以我們的業(yè)務邏輯必須做冪等設計。

而我們的業(yè)務場景保存數據時使用了INSERT INTO …ON DUPLICATE KEY UPDATE語法,不存在時插入,存在時更新,是天然支持冪等性的。

多環(huán)境消費問題

我們當時線上環(huán)境分為:pre(預發(fā)布環(huán)境) 和 prod(生產環(huán)境),兩個環(huán)境共用同一個數據庫,并且共用同一個kafka集群。

需要注意的是,在配置kafka的topic的時候,要加前綴用于區(qū)分不同環(huán)境。pre環(huán)境的以pre_開頭,比如:pre_order,生產環(huán)境以prod_開頭,比如:prod_order,防止消息在不同環(huán)境中串了。

但有次運維在pre環(huán)境切換節(jié)點,配置topic的時候,配錯了,配成了prod的topic。剛好那天,我們有新功能上pre環(huán)境。結果悲劇了,prod的有些消息被pre環(huán)境的consumer消費了,而由于消息體做了調整,導致pre環(huán)境的consumer處理消息一直失敗。

其結果是生產環(huán)境丟了部分消息。不過還好,最后生產環(huán)境消費者通過重置offset,重新讀取了那一部分消息解決了問題,沒有造成太大損失。

后記

除了上述問題之外,我還遇到過:

  • kafka的consumer使用自動確認機制,導致cpu使用率100%。
  • kafka集群中的一個broker節(jié)點掛了,重啟后又一直掛。

這兩個問題說起來有些復雜,我就不一一列舉了。

使用消息中間件kafka的經歷,雖說遇到過挺多問題,踩了很多坑,走了很多彎路,但是實打實的讓我積累了很多寶貴的經驗,快速成長了。

其實kafka是一個非常優(yōu)秀的消息中間件,我所遇到的絕大多數問題,都并非kafka自身的問題(除了cpu使用率100%是它的一個bug導致的之外)。

原文地址:https://mp.weixin.qq.com/s/YPkE3Tsu3RVbhfVZCBt1pQ

http://m.aloenet.com.cn/news/1357.html

相關文章:

  • 西安做網站比較好的公司臺州seo排名外包
  • 怎樣做單頁銷售網站軟文范例大全100字
  • 站酷網站源碼永久免費域名注冊
  • 哪個網站可以做試卷上海牛巨微seo關鍵詞優(yōu)化
  • 番禺做網站哪家強北京seo公司網站
  • 新聞網站建設合同谷歌優(yōu)化師
  • 最新獲取網站訪客qq接口成人職業(yè)技術培訓學校
  • 萊蕪網站優(yōu)化招聘網sem是什么的英文縮寫
  • 微信公眾平臺推廣簡述seo的概念
  • 專注網站開發(fā)網站頁面seo
  • 做直播網站需要什么騰訊企點qq
  • 鹵菜店加盟優(yōu)化排名推廣技術網站
  • 常州做網站包括哪些優(yōu)化網站收費標準
  • 頁面設計好嗎seo怎么發(fā)布外鏈
  • 網站建設資金報告網站宣傳文案范例
  • 深圳網站建設_請到中投網絡!四平網站seo
  • 互聯(lián)網營銷師證書是國家認可的嗎北京seo優(yōu)化wyhseo
  • 二級a做爰片免費視網站淘寶推廣方法有哪些
  • 怎么做班級網站南通做網站推廣的公司
  • 佰聯(lián)軸承網做的網站網站seo優(yōu)化培訓
  • 地方網站域名選擇史上最強大的搜索神器
  • 網站建設這個口碑營銷的步驟
  • 在成都如何找到做網站的公司高級seo
  • 企業(yè)官方網站建設長沙專業(yè)競價優(yōu)化首選
  • 自建網站網址臺州關鍵詞優(yōu)化推薦
  • 怎么建立網站網址360優(yōu)化大師官方網站
  • 公司網站怎么突然多了好多友情鏈接如何刪除今日熱搜前十名
  • 做se要明白網站小紅書關鍵詞排名怎么做
  • 做網站用不用thinkphpb2b電商平臺有哪些
  • 做網站價格公司神馬推廣