天天看點

11-02

java相關-分布式項目中事務,鎖,緩存的知識點

title+以及深入實踐

你好我是後腳跟的後腦勺,離進化為大腦袋還有很長的距離,不管怎樣,既然要編寫這篇文檔,就說明這條職業之路還要繼續進行下去,受"化内法師"的影響,除了上次了解到的關于基金類的知識之外(其實掌握的太淺,而且基金類的更專業的知識其實是由那些博士碩士類别的金融學專業,數學專業的大腦袋來操作的),是以基金類的項目就此打住.

而基金類,金融類的相關程式項目中,其實都使用到了金融類的計算及資料存儲,比如計算時使用bigdecimal做類中的字段類型,以及資料庫中decimal做存儲.

本來記錄這上面這些文字就夠我躺平一會兒了,但是勇敢牛牛不怕困難,迎難而上才能越戰越勇,對于分布式中相關的問題,也是近期被問到的高頻的問題,當然在後腦勺的了解中,這也是一塊要進階去實踐的地方,畢竟在mooc(icourse163)或者基礎類的基礎知識中,分布式事務,分布式鎖,分布式緩存是基本很少講到的,而很多講到這些點的教程則分散在馬士兵教育,尚矽谷.

mybatis中設定時間字段并隻在insert或update時設定某值

實作baomidou下的metaobjecthandler

注解fill=fieldfill.insert / insert_update

2.validation格式化的使用

validation包下的pattern指定了某個字段要符合某種格式

設定一個util,傳入某個含有多個validation判定字段的實體類,傳回不合規不符合要求字段異常集合

3.讓我惡心的一個需求

excelsortloanno

開始之前可以說記錄的是後腳跟之前的做的項目中不管是他人的還是自己的讓人有點疲乏的代碼,總之這樣拿出來就當自己清理了大腦吧.

讓人惡心的同時還有springbatch異步同時跑批,在我看來現在如果一個資料要讀一次并更改3種并寫入其它三個表落庫,最好的方法就是同時執行三個job.(關于spring官網中springbatch的分區的那種實作沒有應用到,不過那個的話應該可以解決之前的問題)

之前都是deleteflag而沒有加注解,直接進行了判定,而實際可以加@tablelogic注解用來說明是執行update設定deleteflag為1,而查詢時也不用指定,mybatisplus會自動查詢deleteflag=0的資料傳回

那天我騎着自行車在面試的問答中再次遇到分布式相關問題,在上海世紀公園轉了好幾圈後回到自己的小窩開始仔細整理學習了相關的知識點,而基于自己的了解,有些能懂有些不能懂,但大體總結出來先這樣,有句話是,"知其然,知其是以然",那麼這些整理類似的隻代表"知其然".

分布式鎖

分布式鎖:多服務同庫,使用樂觀鎖加版本号或悲觀鎖for update鎖定行資料元組

redis實作分布式鎖設定,設定業務key加逾時時間,多個程序隻有一個可以設定成功并執行業務邏輯操作,随後清除,等待下一個程序搶占并設定。redlock

zookeeper設定臨時節點,類似往隊列中放置鎖辨別,并且每次都先擷取節點辨別值最小的用來消費,即擷取到鎖并執行随後清除鎖,則下一個辨別值最小的再擷取鎖并執行操作。跟redis存放鎖辨別不同的是,zookeeper可以有種消息隊列消費鎖的感覺。

分布式事務

分布式事物:分布式事物同樣也是面臨多伺服器多資料庫的事物處理。

首先基于cap理論,事物處理要滿足一緻性,可用性,分區容忍性。

而在分布式事物中,隻能滿足其二,ca.ap.cp

解決方案,

1 兩階段送出協定 2pc

階段一,通過協調者通知參與者準備送出,各參與者回報事物執行結果,但參與者不送出事物。

階段二,協調者通知參與者開始送出事物,各參與者回報事物處理結果,隻要在這兩個階段中執行結果和送出結果有失敗回複,則整個事物復原。

2 事物補償 tcc

tcc是基于2pc實作的業務層事物控制方案,try階段檢查及預留業務資源完成送出事物前的檢查,并預留好資源。

confirm确定執行業務操作對try階段預留的資源正式執行。

cancel取消執行業務操作對try階段預留的資源釋放。

以下單扣庫存為例子,try去占庫存,confirm階段實際扣庫存,如果庫存扣減失敗進行cancel事物復原,釋放庫存。

3 消息隊列實作最終一緻性

本方案基于消息中間件也是建立在2pc之上。

将庫存減少的消息進行消息隊列處理,在之前先生成了訂單表,為避免重複執行消息,執行減少庫存時檢查是否執行過此消息,(這裡應該可以用生成出來的訂單号做為一個辨別?)

執行減少庫存成功後将狀态發回消息隊列,訂單服務接收到完成庫存減少消息後删除原來的減少庫存任務消息(可能帶着訂單号的辨別的那條消息)

開發成本比tcc低,但基于本地事物實作,會頻繁讀寫資料庫記錄,對高并發并不是最佳方案。

4 阿裡的分布式架構seata

分布式緩存

分布式緩存:大型項目中緩存需要進行同步處理,比如沒連同一個緩存伺服器的不同位置的伺服器裡的服務。

如果不處理分布式緩存,則會遇到資料庫的讀寫瓶頸。

1 ehcache

java實作的開源分布式緩存架構,可以減輕資料庫負載,讓資料儲存在不同伺服器記憶體中,擴充簡單。

2 cacheonix

同java實作的分布式緩存系統

3 jboss cache

基于事物的java緩存架構

4 voldemort

基于鍵值的緩存架構,支援多台伺服器之間的緩存同步。

什麼是樂觀鎖 主要适用場景: 當要更新一條記錄的時候,希望這條記錄沒有被别人更新,就是說實作線程安全的資料更新.

針對并發中,兩個用戶端執行操作同一條資料更新,這時牽扯到兩個用戶端要都開啟事務,并可能産生資料不一緻問題.

mybatisplus中提供了樂觀鎖插件

原了解析

通過對表中加version字段并注解mybatisplus的相關注解@version,可以在更新資料的時候判定資料是否在其中一個事務中已經執行了送出,并且設定version版本号自動+1,而另一個事務即使也預先在事務開始時得到了原始的版本号,但是當執行的version+1的事務已經送出後,另一個則無法判定version=#{oldversion},是以即無法執行送出事務.