|
大家好,我是不才陳某~ 接口冪等性是指無論調(diào)用接口的次數(shù)是一次還是多次,對于同一資源的操作都只會產(chǎn)生一次結(jié)果。換句話說,多次重復調(diào)用相同的接口請求應該具有與單次請求相同的效果,不會導致不一致或副作用的發(fā)生。 接口想要保證冪等性有很多種方案,這個在知識星球中《我要進大廠》這個專欄中有篇文章詳細介紹過:高并發(fā)下如何保證接口的冪等性的8種方案 但是這不是今天的重點,今天來介紹一下如何通過自定義注解的方式保證接口在一定時間內(nèi)冪等。 場景碼猿慢病云管理系統(tǒng)中其實高并發(fā)的場景不是很多,沒有必要每個接口都去考慮并發(fā)高的場景,比如添加住院患者的這個接口,具體的業(yè)務代碼就不貼了,業(yè)務偽代碼如下: 上述代碼有問題嗎?誰能說有問題?一般情況下是沒什么問題,但是在高并發(fā)的場景下肯定是存在問題,為什么? 因為有事務的隔離性,step1這個階段對住院號的校驗肯定是存在問題的,在高并發(fā)的場景下無法保證這里的校驗一定準確。 其實這個接口的并發(fā)并不高,在碼猿慢病云管理系統(tǒng)中一般不會出現(xiàn)這種問題,那么什么時候會出現(xiàn)呢? 醫(yī)院中大部分是內(nèi)網(wǎng)+外網(wǎng),如果由于網(wǎng)絡的抖動,系統(tǒng)請求響應的時間延遲,這樣會導致醫(yī)護操作時會出現(xiàn)重復點擊的情況,比如1秒中之內(nèi)由于第一次點添加患者這個按鈕沒反應,往往護士都會重復點擊,這種情況下是會出現(xiàn)問題。 這里我們就暫且不談對單個接口的冪等優(yōu)化了,要想一個方案全局解決這個問題,在碼猿慢病云管理系統(tǒng)中其實只要保證這種并發(fā)不高的接口在一定時間段內(nèi)保證冪等即可,比如5秒之內(nèi),這樣在5秒之內(nèi)護士重復點擊就沒事。 解決方案在碼猿慢病云管理系統(tǒng)中新增了一個注解: 只需要將該注解標注在新增、修改、刪除接口上就能保證在默認的5秒之內(nèi)接口冪等。 比如新增住院患者這個接口: 那么原理是什么?其實很簡單,先來說下原理,再介紹具體的實現(xiàn):
上述6個步驟中其實只有一點比較難實現(xiàn)的,其他的都是基本操作,就是獲取這個請求參數(shù),下面將詳細介紹一下如何獲取這個請求參數(shù)。 獲取請求參數(shù)對于form-data的入?yún)⒅恍枰{(diào)用 解決方案也很簡單,只需要保證IO流能夠多次讀取即可,下面就來介紹一下方案。 這里我們可以利用裝飾者模式對 HttpServletRequest 的功能進行增強,具體做法也很簡單,我們重新定義一個 HttpServletRequest:
這段代碼并不難,很好懂。 首先在構(gòu)造 RepeatedlyRequestWrapper 的時候,就通過 IO 流將數(shù)據(jù)讀取出來并存入到一個 byte 數(shù)組中,然后重寫 getReader 和 getInputStream 方法,在這兩個讀取 IO 流的方法中,都從 byte 數(shù)組中返回 IO 流數(shù)據(jù)出來,這樣就實現(xiàn)了反復讀取了。 接下來我們定義一個過濾器,讓這個裝飾后的 Request 生效: 判斷一下,如果請求數(shù)據(jù)類型是 JSON 的話,就把 這樣就可以配置后就可以在程序中反復讀取參數(shù)了! 防重注解實現(xiàn)解決了參數(shù)讀取的問題,下面就可以輕松實現(xiàn)這個防重注解了,首先定義注解 接下來直接用AOP實現(xiàn),
邏輯很簡單,上述已經(jīng)介紹過完整的流程,這里需要注意的是參數(shù)的讀取,代碼如下: 其實就是將request判斷下是否是經(jīng)過過濾器封裝后的 總結(jié)本節(jié)內(nèi)容介紹了防重注解 碼猿慢病云管理系統(tǒng)已經(jīng)在星球中陸續(xù)更新,目前更新內(nèi)容如下: 最后說一句(別白嫖,求關注)陳某每一篇文章都是精心輸出,如果這篇文章對你有所幫助,或者有所啟發(fā)的話,幫忙點贊、在看、轉(zhuǎn)發(fā)、收藏,你的支持就是我堅持下去的最大動力! 另外陳某的知識星球開通了,加入只需199元,星球回饋的價值巨大,目前更新了碼猿慢病云管理實戰(zhàn)項目、Spring全家桶實戰(zhàn)系列、億級數(shù)據(jù)分庫分表實戰(zhàn)、DDD微服務實戰(zhàn)專欄、我要進大廠、Spring,Mybatis等框架源碼、架構(gòu)實戰(zhàn)22講、精盡RocketMQ等.... |
|
|
來自: woh5r1ofyffxnh > 《待分類》