99精品久久精品一区二区-亚洲熟妇无码?v在线播放-日本国产精品无码字幕在线观看-久久久亚洲永夜AV-亚洲一级无码一区二区一-免费国产成高清人在线视频-中文字幕乱码免费观看-国产毛片精品妇女久久久

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

REA模型實(shí)戰(zhàn):用資源事件代理建模積分結(jié)算系統(tǒng)

REA模型實(shí)戰(zhàn):用資源事件代理建模積分結(jié)算系統(tǒng) 做后端和架構(gòu)的同學(xué)應(yīng)該都對(duì)這種場(chǎng)景不陌生。業(yè)務(wù)方丟過(guò)來(lái)一句話“我們要上一個(gè)積分系統(tǒng)買東西得積分積分能抵現(xiàn)。”你第一反應(yīng)是建表用戶表、訂單表、積分表、流水表。等上線三個(gè)月財(cái)務(wù)說(shuō)要對(duì)賬你發(fā)現(xiàn)積分流水里只有加減沒有“這筆積分來(lái)自哪筆訂單、對(duì)應(yīng)哪次消費(fèi)、被誰(shuí)消耗”問題一下子全出來(lái)了。今天聊的REA模型就是專門用來(lái)解決這類建模問題的。REA全稱是Resource-Event-Agent資源-事件-代理是一套面向經(jīng)營(yíng)活動(dòng)的領(lǐng)域建??蚣懿唤壎ㄈ魏慰蚣芎驼Z(yǔ)言。這篇文章我會(huì)用一個(gè)積分結(jié)算系統(tǒng)的完整建模過(guò)程講清楚REA是什么、怎么建模、怎么落到存儲(chǔ)和查詢最后把實(shí)際踩過(guò)的坑一次說(shuō)清。適合正在做DDD落地、事件溯源以及賬戶、庫(kù)存、積分類系統(tǒng)的開發(fā)者參考。1. REA模型認(rèn)知為什么業(yè)務(wù)建模繞不開它1.1 三個(gè)要素和一個(gè)中心關(guān)系REA模型的三個(gè)核心詞匯展開來(lái)說(shuō)并不復(fù)雜。Resource資源凡是“有價(jià)值、可以衡量、能在業(yè)務(wù)中流動(dòng)”的東西都可以歸入這個(gè)范疇?,F(xiàn)金、庫(kù)存商品、積分、優(yōu)惠券、產(chǎn)能、維修工單中的工時(shí)都是資源。判斷標(biāo)準(zhǔn)很直接這個(gè)東西在業(yè)務(wù)里會(huì)不會(huì)被增加、減少、轉(zhuǎn)移如果會(huì)它就是Resource而不是什么普通實(shí)體或字典表。很多同學(xué)建模時(shí)把積分當(dāng)成“用戶的屬性”直接給用戶表加一個(gè)point字段這恰恰是問題的起點(diǎn)。積分本質(zhì)上是一種可流轉(zhuǎn)、可消耗、有歸屬的資產(chǎn)應(yīng)該被當(dāng)成Resource來(lái)建模。Event事件是發(fā)生在資源上的經(jīng)濟(jì)活動(dòng)。用戶支付、商品出庫(kù)、積分發(fā)放、優(yōu)惠券核銷都屬于Event。它記錄的是“發(fā)生了什么”而不是“現(xiàn)在是什么狀態(tài)”。平時(shí)做CRUD的時(shí)候我們習(xí)慣把賬號(hào)狀態(tài)從待支付改成已支付這是狀態(tài)的覆蓋而在REA里我們記錄的是“誰(shuí)在什么時(shí)間做了什么動(dòng)作”這個(gè)動(dòng)作不會(huì)因?yàn)闃I(yè)務(wù)狀態(tài)變化而被抹掉。Agent代理是參與經(jīng)濟(jì)活動(dòng)的人、系統(tǒng)角色或組織。用戶、供應(yīng)商、平臺(tái)、渠道商甚至一個(gè)負(fù)責(zé)積分過(guò)期任務(wù)的定時(shí)程序都可以是Agent。在REA模型里Agent不是簡(jiǎn)單的標(biāo)簽而是資源流向的歸屬方。每一筆資源變動(dòng)都必須能回答“這個(gè)資源從哪個(gè)Agent流出流入哪個(gè)Agent”。三者的關(guān)系是一個(gè)Event至少連接兩個(gè)Agent同時(shí)連接流入和流出兩類Resource。為什么必須有雙方因?yàn)槿魏我还P經(jīng)濟(jì)活動(dòng)要成立必然存在一方資源減少、另一方資源增加。如果模型中只看到一個(gè)Agent那說(shuō)明你記錄的很可能不是事實(shí)而是某個(gè)操作的結(jié)果快照。1.2 用一杯咖啡看懂REA用一個(gè)最生活化的例子來(lái)拆解比如“你花20元在咖啡店買一杯咖啡”。傳統(tǒng)建模會(huì)怎么寫訂單表記錄商品、金額、訂單狀態(tài)支付表記錄支付結(jié)果庫(kù)存表扣減庫(kù)存??雌饋?lái)邏輯完整但對(duì)賬時(shí)就會(huì)遇到一個(gè)經(jīng)典麻煩訂單顯示已支付財(cái)務(wù)的銀行流水里卻沒有這筆錢或者支付成功但訂單狀態(tài)沒被更新你說(shuō)不清是哪一步發(fā)生的、責(zé)任在哪一方。用REA模型這次交易要被拆成兩個(gè)獨(dú)立的經(jīng)濟(jì)Event。第一個(gè)Event是顧客付款。此時(shí)支付錢包這類Resource從顧客名下流出20元流入咖啡店的收款賬戶涉及到的Agent是顧客和咖啡店。第二個(gè)Event是咖啡交付。咖啡豆或已制作好的咖啡成品從咖啡店的庫(kù)存Resource中流出1杯轉(zhuǎn)入顧客名下涉及到的Agent同樣是顧客和咖啡店。這里一定會(huì)有人問一筆交易為什么要拆成兩個(gè)Event因?yàn)楦犊詈徒桓侗緛?lái)就是兩個(gè)獨(dú)立事實(shí)它們可能不是同一時(shí)刻發(fā)生。顧客觀看菜單后可能先付款再取貨也可能先取走咖啡后補(bǔ)付錢更可能付款后商家倒閉跑路根本拿不到咖啡。如果把兩者揉在一個(gè)訂單Event里后續(xù)處理退款、掉單對(duì)賬、庫(kù)存損耗時(shí)就會(huì)非常痛苦。拆開之后“顧客付了錢但沒拿到咖啡”可以定位到第一個(gè)Event已完成、第二個(gè)Event未發(fā)生“拿到咖啡但沒扣庫(kù)存”也可以從Event里直接查出來(lái)。這背后正是復(fù)式記賬的思路每一筆資源的流入必然對(duì)應(yīng)另一筆資源的流出兩邊都要有據(jù)可查。REA把這種會(huì)計(jì)思想搬到了軟件建模層面很多看似復(fù)雜的業(yè)務(wù)按這個(gè)邏輯梳理后核心關(guān)系會(huì)非常干凈。等等有人會(huì)問“我開發(fā)的是一個(gè)管理后臺(tái)不是財(cái)務(wù)軟件有必要這么較真嗎”確實(shí)不是所有系統(tǒng)都必要但凡是涉及資金、庫(kù)存、積分、兌換碼這類“資產(chǎn)型”數(shù)據(jù)的模塊如果沒有這一層事實(shí)記錄將來(lái)對(duì)賬、審計(jì)、排查數(shù)據(jù)異常時(shí)代價(jià)會(huì)成倍增加。我見過(guò)太多系統(tǒng)因?yàn)樵缙谑×诉@一步后期專門開發(fā)“審計(jì)模塊”“對(duì)賬系統(tǒng)”結(jié)果還是對(duì)不齊最后只能硬編碼各種補(bǔ)丁。1.3 傳統(tǒng)建模與REA建模的對(duì)照把傳統(tǒng)CRUD式的建模和REA建模放在一起對(duì)比區(qū)別會(huì)更直觀。對(duì)比維度傳統(tǒng)建模REA建模核心數(shù)據(jù)狀態(tài)字段比如訂單狀態(tài)不可變的經(jīng)濟(jì)事實(shí)流審計(jì)能力依賴操作日志經(jīng)常缺失環(huán)節(jié)事件天然全鏈路可回溯當(dāng)前余額/庫(kù)存直接查字段值通過(guò)投影計(jì)算可從事件推導(dǎo)業(yè)務(wù)擴(kuò)展需要改表結(jié)構(gòu)、加字段新增事件類型舊事件不動(dòng)冪等保障依賴狀態(tài)校驗(yàn)和鎖依賴事件的業(yè)務(wù)唯一性財(cái)務(wù)對(duì)賬另行開發(fā)對(duì)賬邏輯事件本身就是賬本傳統(tǒng)表結(jié)構(gòu)像給系統(tǒng)拍了一張又一張快照我們能看到的永遠(yuǎn)是當(dāng)前狀態(tài)REA更像一段完整錄像任何時(shí)間點(diǎn)的業(yè)務(wù)都可以被還原。數(shù)據(jù)庫(kù)字段里那個(gè)“訂單狀態(tài)已完成”更像一張抓拍照片而REA事件流里的“下單、支付、出倉(cāng)、簽收”是連續(xù)的事實(shí)序列。對(duì)需要追溯責(zé)任的業(yè)務(wù)來(lái)說(shuō)錄像比照片可靠得多。還不止如此。傳統(tǒng)建模中當(dāng)業(yè)務(wù)需求增加“積分可以跨訂單合并使用”的時(shí)候你要么給積分表加一大堆關(guān)聯(lián)字段要么再寫一套合并邏輯。但在REA里積分合并本質(zhì)上是一筆資源重組Event把兩個(gè)積分賬戶的資源結(jié)余轉(zhuǎn)移到一個(gè)新賬戶事件不改變舊積分賬戶的事實(shí)只是做一個(gè)新事件。這種擴(kuò)展方式對(duì)新老邏輯都比較溫和。1.4 REA與DDD、事件溯源的真實(shí)關(guān)系DDD領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)這么多年都很火但很多團(tuán)隊(duì)落地時(shí)卡在同一個(gè)問題上通用語(yǔ)言怎么定義聚合根怎么劃分領(lǐng)域事件到底應(yīng)該記錄哪些內(nèi)容REA恰好給了一套可落地的詞法規(guī)范。DDD的“領(lǐng)域事件”在REA里對(duì)應(yīng)的是真正的經(jīng)濟(jì)Event而不是系統(tǒng)的每一步操作。比如“用戶點(diǎn)擊了積分明細(xì)頁(yè)”這種操作不算Event因?yàn)樗簧婕叭魏蜶esource的流入流出“用戶用100積分兌換了一張5元優(yōu)惠券”才是Event因?yàn)樗婕皟蓚€(gè)Agent用戶和平臺(tái)、兩類Resource積分和優(yōu)惠券。如果你的團(tuán)隊(duì)在做事件風(fēng)暴時(shí)總是吵不清楚哪些是領(lǐng)域事件引入REA的“雙Agent、雙Resource”校驗(yàn)一下子就能過(guò)濾掉大量噪音。事件溯源Event Sourcing落地時(shí)最常見的問題也是事件庫(kù)亂。有些團(tuán)隊(duì)把“狀態(tài)變更”都當(dāng)成事件存進(jìn)去結(jié)果事件流里魚龍混雜重放時(shí)根本還原不出業(yè)務(wù)。REA的約束正好解決了這個(gè)問題事件必須關(guān)聯(lián)資源、必須關(guān)聯(lián)雙向代理、必須描述經(jīng)濟(jì)活動(dòng)。不符合這三條的就不應(yīng)該進(jìn)事件庫(kù)。所以REA不是DDD的替代品也不是事件溯源框架的前置依賴而是它們之間的粘合劑。我個(gè)人的習(xí)慣是先用REA梳理領(lǐng)域詞表再做DDD的聚合設(shè)計(jì)最后用事件溯源來(lái)落地。順序?qū)α撕竺鏁?huì)順很多。2. 實(shí)操建模用REA給積分結(jié)算系統(tǒng)搭骨架2.1 從一個(gè)不過(guò)分的模擬項(xiàng)目開始為了把REA落地過(guò)程講得具體我假設(shè)自己正在為某社區(qū)團(tuán)購(gòu)平臺(tái)設(shè)計(jì)一套結(jié)算模塊業(yè)務(wù)規(guī)則一共有四條用戶可以用微信充值獲得平臺(tái)余額用戶在商城下單時(shí)用余額支付同時(shí)按支付金額的一定比例獲得積分用戶可以用積分兌換優(yōu)惠券優(yōu)惠券在下一次購(gòu)買時(shí)核銷。需要注意的是充值渠道和商品提供方是外部角色平臺(tái)本身也需要作為Agent進(jìn)入模型。拿到這個(gè)需求第一步不是寫代碼也不是畫架構(gòu)圖而是列事件清單。我把所有可能發(fā)生的經(jīng)濟(jì)活動(dòng)寫下來(lái)用戶發(fā)起充值、充值成功到賬、用戶下單、支付成功、訂單完成出庫(kù)、積分發(fā)放、積分兌換優(yōu)惠券、優(yōu)惠券核銷。事件清單不需要一次就完美后續(xù)隨業(yè)務(wù)梳理不斷補(bǔ)充但第一版必須包含業(yè)務(wù)方最關(guān)心的幾件事尤其是錢和商品的流轉(zhuǎn)。第二步對(duì)每個(gè)事件確認(rèn)它涉及的Resource和Agent。這里直接給出我梳理后的關(guān)系表這個(gè)表本質(zhì)上會(huì)成為后面領(lǐng)域模型和數(shù)據(jù)庫(kù)設(shè)計(jì)的基礎(chǔ)事件流入Resource流出Resource涉及Agent充值成功余額用戶外部資金平臺(tái)用戶、平臺(tái)支付成功下單商品貨權(quán)用戶余額用戶用戶、平臺(tái)訂單完成出庫(kù)商品庫(kù)存平臺(tái)商品在庫(kù)平臺(tái)平臺(tái)、供應(yīng)商積分發(fā)放積分用戶積分池平臺(tái)用戶、平臺(tái)積分兌換優(yōu)惠券優(yōu)惠券用戶積分用戶用戶、平臺(tái)優(yōu)惠券核銷優(yōu)惠券核銷記錄平臺(tái)優(yōu)惠券用戶用戶、平臺(tái)注意這里“商品貨權(quán)用戶”與“商品在庫(kù)平臺(tái)”是兩個(gè)不同的Resource。REA模型鼓勵(lì)把貨權(quán)和庫(kù)存分開看待因?yàn)橛脩粝聠魏筘洐?quán)雖然已經(jīng)轉(zhuǎn)移給用戶但商品仍然在平臺(tái)倉(cāng)管里直到出庫(kù)才減少庫(kù)存。很多庫(kù)存對(duì)不上的問題正是因?yàn)榘沿洐?quán)轉(zhuǎn)移和庫(kù)存減少混為一談。這個(gè)點(diǎn)在實(shí)際做電商系統(tǒng)時(shí)非常重要。第三步確定聚合邊界。我的方案是把“經(jīng)濟(jì)事件”作為獨(dú)立的不可變聚合根每個(gè)Agent的每個(gè)Resource類型對(duì)應(yīng)一個(gè)資源賬戶聚合比如UserAccount聚合里包含用戶的余額賬戶和積分賬戶平臺(tái)的資產(chǎn)品類賬戶單獨(dú)再建一個(gè)聚合。事件聚合負(fù)責(zé)產(chǎn)生事實(shí)賬戶聚合負(fù)責(zé)校驗(yàn)和投影兩者職責(zé)分離不混在一起。2.2 領(lǐng)域模型代碼骨架事件與賬戶分離按照上面的設(shè)計(jì)核心代碼可以拆成三層。Resource層比較簡(jiǎn)單它包含一個(gè)ResourceType和一個(gè)數(shù)量字段。Event層承擔(dān)事實(shí)記錄必須不可變。Agent層負(fù)責(zé)資源賬戶的承載。我用接近Java的偽代碼把它寫出來(lái)public class ResourceAccount { private AgentId agentId; private ResourceType resourceType; private long amount; // 以最小單位存儲(chǔ)比如“分” private int version; public void apply(EconomicEvent event) { // 先校驗(yàn)后變更 } } public class EconomicEvent { private EventId eventId; private EventType eventType; private Instant occurredAt; private ListEntry entries; public static class Entry { private AgentId agentId; private ResourceType resourceType; private long amount; // 流入記正數(shù)流出記負(fù)數(shù) private EntryDirection direction; } } public class Agent { private AgentId agentId; private AgentType agentType; private String name; }這里最核心的是EconomicEvent中的Entry列表。一個(gè)事件至少要有兩條Entry一條表示某Agent的某個(gè)Resource增加另一條表示另一個(gè)Agent的某個(gè)Resource減少。兩條Entry之間滿足金額守恒。比如充值成功事件一條Entry是用戶余額10000分另一條Entry是平臺(tái)外部資金-10000分。兩條金額加起來(lái)為0這個(gè)事件的完整性就初步得到保證。金額守恒看起來(lái)像會(huì)計(jì)學(xué)概念但它對(duì)系統(tǒng)質(zhì)量的作用非常直接。在傳統(tǒng)模型里一個(gè)不經(jīng)意的小Bug可能導(dǎo)致用戶余額憑空多出1分錢而在REA模型里事件本身自檢就能發(fā)現(xiàn)不平衡測(cè)試用例也更容易寫。我經(jīng)常說(shuō)REA等于把會(huì)計(jì)的“借貸平衡”內(nèi)置到了業(yè)務(wù)系統(tǒng)的核心數(shù)據(jù)結(jié)構(gòu)里。當(dāng)然代碼只是骨架真正能不能落地還取決于底層存儲(chǔ)和并發(fā)控制這部分放到第3章細(xì)說(shuō)。2.3 為什么資源單位必須是最小單位這個(gè)坑我踩過(guò)必須單獨(dú)拿出來(lái)講。早期做一個(gè)優(yōu)惠券計(jì)算功能時(shí)我用浮點(diǎn)數(shù)表示折扣比如0.88折結(jié)果計(jì)算過(guò)程中出現(xiàn)了0.30000000000004這類連自己都看不懂的數(shù)字后面所有對(duì)賬全部錯(cuò)位。這不是REA特有的問題而是所有涉及金額、積分、數(shù)量類業(yè)務(wù)都容易犯的錯(cuò)。在REA建模中所有Resource的數(shù)量都必須選擇整數(shù)類型以最小不可分割單位存儲(chǔ)。金額以“分”存儲(chǔ)積分以1個(gè)為單位庫(kù)存以“件”為單位。打折、匯率換算這些計(jì)算放到入賬之前處理一旦進(jìn)入Resource賬戶全部是整數(shù)。這個(gè)設(shè)計(jì)同時(shí)解決了兩個(gè)問題第一浮點(diǎn)數(shù)誤差從源頭消失第二審計(jì)時(shí)看到的每一筆事件都是完整的業(yè)務(wù)事實(shí)不會(huì)出現(xiàn)三條小數(shù)記賬記錄加起來(lái)不等于一條原始記錄的情況。另外Resource的流出方向我建議用direction字段而不是簡(jiǎn)單的正負(fù)號(hào)。正負(fù)號(hào)只有兩個(gè)方向但業(yè)務(wù)里還有“凍結(jié)”“解凍”“沖正”等狀態(tài)只用正負(fù)號(hào)表達(dá)很容易把數(shù)量與狀態(tài)混淆。庫(kù)存不足時(shí)如果系統(tǒng)錯(cuò)誤地產(chǎn)生一個(gè)負(fù)庫(kù)存光看數(shù)據(jù)根本判斷不出異常但如果direction明確標(biāo)記為“凍結(jié)失敗”異常就能被精準(zhǔn)定位。2.4 事件不可變與沖正機(jī)制很多同學(xué)第一次接觸REA時(shí)會(huì)問如果事件寫錯(cuò)了怎么辦用戶的余額被我用一個(gè)錯(cuò)誤事件扣掉了難道不能改掉那條事件嗎答案是原始事件永遠(yuǎn)不能改只能新增一個(gè)“沖正事件”來(lái)糾正。比如充值事件本來(lái)是100元結(jié)果系統(tǒng)錄入成了1000元你不能去修改那條充值事件而是要生成一條“充值沖正”事件把多出的900元從用戶余額里扣回來(lái)并關(guān)聯(lián)到被沖正的原事件ID。這個(gè)規(guī)則看上去死板卻保住了整個(gè)系統(tǒng)的底線。一旦事件可修改之前所有基于事件的審計(jì)、重放、對(duì)賬邏輯都會(huì)失去信任基礎(chǔ)。金融系統(tǒng)里為什么要求“記賬憑證不可涂改”因?yàn)閼{證一旦可改賬本就沒有意義了。REA在這個(gè)層面就是數(shù)字化時(shí)代的記賬憑證。事件不可變的另一個(gè)好處是可以在多系統(tǒng)之間可靠地同步數(shù)據(jù)。下游系統(tǒng)只需要按事件ID增量拉取不需要關(guān)心上游是否修改過(guò)數(shù)據(jù)即使下游處理失敗重新消費(fèi)冪等性也可以通過(guò)事件唯一ID保證。這是事件驅(qū)動(dòng)架構(gòu)中一個(gè)很實(shí)用的基礎(chǔ)設(shè)計(jì)。3. 從模型到落地事件存儲(chǔ)、快照與查詢投影3.1 事件存儲(chǔ)表結(jié)構(gòu)怎么設(shè)計(jì)模型最終要落到存儲(chǔ)。在數(shù)據(jù)量不大時(shí)完全可以用普通關(guān)系型數(shù)據(jù)庫(kù)來(lái)實(shí)現(xiàn)事件存儲(chǔ)而不必一上來(lái)就引入專門的事件溯源中間件。我用PostgreSQL風(fēng)格的表結(jié)構(gòu)來(lái)說(shuō)明但換成MySQL也成立。核心就兩張表一張保存事件流元數(shù)據(jù)一張保存每個(gè)具體事件的數(shù)據(jù)。CREATE TABLE event_streams ( id BIGSERIAL PRIMARY KEY, aggregate_type VARCHAR(64) NOT NULL, aggregate_id VARCHAR(64) NOT NULL, version INT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), UNIQUE (aggregate_type, aggregate_id, version) ); CREATE TABLE events ( id BIGSERIAL PRIMARY KEY, stream_id BIGINT NOT NULL REFERENCES event_streams(id), version INT NOT NULL, event_type VARCHAR(128) NOT NULL, event_id VARCHAR(64) NOT NULL UNIQUE, payload JSONB NOT NULL, recorded_at TIMESTAMPTZ NOT NULL DEFAULT now() );這里的event_streams表代表一個(gè)聚合的版本序列。version字段是遞增的整數(shù)每次追加新事件時(shí)必須指定基于哪個(gè)version寫入。如果兩個(gè)并發(fā)請(qǐng)求都用version3去追加下一個(gè)事件數(shù)據(jù)庫(kù)的唯一約束就會(huì)讓其中一個(gè)失敗沖突在源頭被攔下來(lái)。events表的event_id是這個(gè)事件的業(yè)務(wù)唯一ID不是自增主鍵。比如支付成功事件的事件ID就是支付流水號(hào)充值沖正事件的事件ID就是沖正單號(hào)。加上唯一約束后即使消費(fèi)者重復(fù)投遞消息數(shù)據(jù)庫(kù)也會(huì)把重復(fù)事件擋在外面這是冪等性的最后一道保險(xiǎn)。我見過(guò)不少團(tuán)隊(duì)把事件和業(yè)務(wù)數(shù)據(jù)混在一起事件表里既存原始事實(shí)又存當(dāng)時(shí)算出來(lái)的余額結(jié)果重放時(shí)數(shù)據(jù)結(jié)構(gòu)混亂。記得原則Event只存事實(shí)數(shù)據(jù)比如數(shù)量、單價(jià)、關(guān)聯(lián)訂單號(hào)所有可推導(dǎo)的余額、庫(kù)存、狀態(tài)全部放投影不要放事件。3.2 快照策略與應(yīng)用恢復(fù)事件存儲(chǔ)解決了事實(shí)保存但性能上不能無(wú)限依賴“從頭重放所有事件”。假設(shè)一個(gè)用戶賬戶有10萬(wàn)條積分流水每次加載賬戶狀態(tài)都要重放10萬(wàn)次系統(tǒng)必然扛不住。這時(shí)候需要快照??煺站褪蔷酆显谀硞€(gè)版本時(shí)刻的完整存檔?;謴?fù)時(shí)只從最近的快照開始重放后續(xù)事件而不是從零開始。比如用戶賬戶已經(jīng)發(fā)生10萬(wàn)條事件系統(tǒng)每100條生成一個(gè)快照那么恢復(fù)時(shí)最多重放100條性能得到了數(shù)量級(jí)提升。快照的生成策略要兼顧實(shí)時(shí)性和成本。我常用的方案是在追加事件的事務(wù)里判斷當(dāng)前版本號(hào)是否達(dá)到“上次快照版本100”如果達(dá)到了就在同一事務(wù)里把聚合狀態(tài)序列化后寫入快照表??煺找部梢耘浜隙〞r(shí)任務(wù)做但要注意版本對(duì)齊避免快照版本與事件版本不一致導(dǎo)致重放重復(fù)或缺失。CREATE TABLE snapshots ( stream_id BIGINT NOT NULL REFERENCES event_streams(id), version INT NOT NULL, state JSONB NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), PRIMARY KEY (stream_id, version) );讀取聚合狀態(tài)時(shí)先取版本號(hào)最大的快照再加載該版本之后的所有事件順序重放得到最新狀態(tài)??煺兆鳛閮?yōu)化手段不能取代事件本身如果快照損壞最多重建一個(gè)空聚合重放全量事件不影響數(shù)據(jù)正確性。3.3 查詢投影別拿事件庫(kù)當(dāng)查詢庫(kù)事件庫(kù)和普通業(yè)務(wù)庫(kù)的查詢特性完全不一樣。事件表的寫入是追加式?jīng)]有任何update拿它來(lái)做“查詢用戶當(dāng)前余額”這類高頻業(yè)務(wù)請(qǐng)求非常不適合。正確做法是建立查詢投影用一份獨(dú)立的讀模型來(lái)服務(wù)查詢。還是說(shuō)積分系統(tǒng)的例子。我可以建一張賬戶余額讀模型表專門用來(lái)支撐業(yè)務(wù)查詢CREATE TABLE account_balance_read_model ( user_id VARCHAR(64) PRIMARY KEY, balance_amount BIGINT NOT NULL, total_points BIGINT NOT NULL, coupon_count INT NOT NULL, updated_at TIMESTAMPTZ NOT NULL );這張表的數(shù)據(jù)不直接寫入業(yè)務(wù)邏輯而是由事件訂閱者異步更新。充值成功、支付成功、積分兌換等事件發(fā)布后訂閱者收到消息重新計(jì)算該用戶的最新余額和積分然后更新表中的記錄。查詢接口只讀這張表響應(yīng)速度很快。這個(gè)寫模型與讀模型分離的思路本質(zhì)上就是CQRS。REA和CQRS天然合拍REA負(fù)責(zé)把寫側(cè)變成一串不可變的事實(shí)CQRS負(fù)責(zé)把讀側(cè)變成面向業(yè)務(wù)場(chǎng)景的投影。在寫側(cè)我們強(qiáng)調(diào)一致性、完整性和審計(jì)能力在讀側(cè)我們強(qiáng)調(diào)查詢性能和響應(yīng)速度。兩者互不拖累。需要注意的是投影更新存在“最終一致”窗口事件寫入后到讀模型更新完成前用戶可能看到舊數(shù)據(jù)。對(duì)大多數(shù)積分、余額業(yè)務(wù)來(lái)說(shuō)這個(gè)時(shí)間差可以接受如果業(yè)務(wù)要求強(qiáng)一致可以在同一個(gè)事務(wù)里同時(shí)更新事件表和投影表代價(jià)是寫入延遲升高。我剛落地REA時(shí)只顧著保證事件一致性忘了設(shè)計(jì)讀模型結(jié)果上線后接口響應(yīng)慢得沒法看后來(lái)補(bǔ)了投影表才解決問題。3.4 冪等、并發(fā)控制與重試事件驅(qū)動(dòng)系統(tǒng)里的冪等性遠(yuǎn)比單體CRUD里需要考慮得多。同一個(gè)支付成功事件可能因?yàn)橄⒅虚g件重投、下游服務(wù)重啟等原因被處理兩次。如果沒有冪等保護(hù)用戶的300元可能被入賬兩次積分翻倍優(yōu)惠券重復(fù)發(fā)放。冪等的第一道防線在事件唯一鍵上。我用支付回調(diào)里的平臺(tái)流水號(hào)作為eventId數(shù)據(jù)庫(kù)對(duì)eventId加唯一索引重復(fù)插入必然失敗。第二道防線在賬戶聚合的版本號(hào)上。每個(gè)賬戶記錄當(dāng)前version更新時(shí)必須攜帶期望version如果version對(duì)不上說(shuō)明有其他事件已經(jīng)先入賬當(dāng)前請(qǐng)求需要重新加載最新狀態(tài)再合并計(jì)算。這里給出一個(gè)典型的寫入流程偽代碼public void processPayment(PaymentReceivedEvent event) { for (int retry 0; retry 3; retry) { AgentAccount account accountRepository.load(userId); if (eventStore.exists(event.getEventId())) { return; // 已經(jīng)處理過(guò)直接忽略 } try { account.apply(event); accountRepository.save(account, account.getVersion()); eventStore.append(event); return; } catch (VersionConflictException ex) { // 說(shuō)明有并發(fā)事件先寫入重新加載重試 } } throw new RecoverableException(concurrent payment processing); }這個(gè)寫法里事件唯一鍵保證了重復(fù)消息不會(huì)入賬版本沖突保證了并發(fā)更新不會(huì)互相覆蓋。我實(shí)際測(cè)試過(guò)即使兩個(gè)線程同時(shí)收到同一事件最終也只有一個(gè)線程能成功寫入另一個(gè)會(huì)在下一輪重試時(shí)發(fā)現(xiàn)事件已存在并退出。這套機(jī)制簡(jiǎn)單可靠比分布式鎖輕量很多。4. 復(fù)盤避坑REA落地時(shí)最常踩的6個(gè)坑4.1 坑一把派生數(shù)據(jù)混進(jìn)事件里這是REA建模中最典型的錯(cuò)誤幾乎每個(gè)初學(xué)的人都會(huì)犯。有人設(shè)計(jì)“用戶支付”事件時(shí)除了記錄支付金額、訂單號(hào)還會(huì)加一個(gè)字段叫“支付后余額”目的是查詢方便。結(jié)果事件溯源重放到最后一筆時(shí)發(fā)現(xiàn)余額和真實(shí)余額差了10元。為什么因?yàn)樵缙诘哪硹l事件里的“支付后余額”算錯(cuò)了而這個(gè)錯(cuò)誤在之后的N條事件里被當(dāng)成基礎(chǔ)數(shù)據(jù)繼續(xù)疊加。正確做法是事件只記錄業(yè)務(wù)事實(shí)支付了多少錢、來(lái)自哪個(gè)訂單、發(fā)生于何時(shí)。用戶支付后的余額是多少由投影計(jì)算得出不能寫進(jìn)事件。把這個(gè)原則記住你的事件流就能永遠(yuǎn)保持純凈和可重放。4.2 坑二漏掉系統(tǒng)自動(dòng)任務(wù)的Agent身份有一類特殊Agent特別容易被遺漏——系統(tǒng)本身。比如平臺(tái)規(guī)定“90天未使用的積分自動(dòng)過(guò)期”這個(gè)定時(shí)任務(wù)每天掃描積分賬戶并執(zhí)行過(guò)期操作。很多建模者覺得它不是人就不給它Agent身份。結(jié)果積分過(guò)期后業(yè)務(wù)審計(jì)想查“誰(shuí)的積分被清了、為什么被清”時(shí)事件流里只有一個(gè)資源減少記錄沒有任何Agent承擔(dān)責(zé)任。正確做法是把“積分過(guò)期服務(wù)”或者“系統(tǒng)管理Agent”納入模型給它分配一個(gè)AgentId。事件里的雙向Agent就變成了“用戶”和“系統(tǒng)管理Agent”。這樣審計(jì)時(shí)才能回答這筆積分是用戶主動(dòng)兌換掉還是被規(guī)則自動(dòng)清理的規(guī)則歸屬哪個(gè)系統(tǒng)服務(wù)。4.3 坑三濫用浮點(diǎn)數(shù)處理金額和積分這個(gè)坑前面已經(jīng)提過(guò)但值得放進(jìn)避坑清單里再次強(qiáng)調(diào)。任何Resource的入賬和出賬都使用以最小單位為基準(zhǔn)的整數(shù)。打折、匯率、稅率等計(jì)算全部放在事件入賬之前計(jì)算結(jié)果必須四舍五入到最小單位后再進(jìn)入事件。如果某天計(jì)算結(jié)果出現(xiàn)0.1個(gè)積分業(yè)務(wù)上要么向下取整要么單獨(dú)生成一個(gè)“零頭積分”的Resource絕不能讓一個(gè)小數(shù)出現(xiàn)在賬戶流水里。4.4 坑四事件表膨脹查詢性能失控事件存儲(chǔ)的量級(jí)和普通業(yè)務(wù)表完全不一樣。一個(gè)用戶一年可能產(chǎn)生上千條積分流水一個(gè)平臺(tái)一年就是上億條。如果不做任何優(yōu)化任何一次加載聚合狀態(tài)都要掃描幾十萬(wàn)條數(shù)據(jù)系統(tǒng)會(huì)卡到?jīng)]法用。解決方案有分層第一層是快照把上千條事件壓縮到最多回放100條第二層是歸檔把超過(guò)3個(gè)月的舊事件歸檔到冷存儲(chǔ)業(yè)務(wù)查詢走投影表只在審計(jì)、對(duì)賬、糾紛處理時(shí)查冷數(shù)據(jù)第三層投影表本身也要定期清理和壓縮避免重復(fù)投影數(shù)據(jù)越來(lái)越多。記住一條事件庫(kù)是“真相”投影模型才是“讀接口”不要讓用戶請(qǐng)求直接親吻事件庫(kù)。4.5 坑五團(tuán)隊(duì)不認(rèn)可新模型方案被噴成過(guò)度設(shè)計(jì)REA落地最大的阻力往往不是技術(shù)而是團(tuán)隊(duì)協(xié)作。業(yè)務(wù)方會(huì)覺得你繞了一大圈明明一張訂單表就能解決的問題你非要拆成幾個(gè)事件和賬戶開發(fā)同事會(huì)覺得這套模型復(fù)雜要學(xué)新的概念還要寫一套以前沒寫過(guò)的代碼。我的建議是不要試圖一次性全面鋪開。先挑一個(gè)最痛的點(diǎn)比如財(cái)務(wù)月結(jié)算對(duì)不上賬、積分明細(xì)查不清用REA做一個(gè)影子模塊和舊系統(tǒng)并行跑一段時(shí)間用報(bào)表比對(duì)新舊模型的結(jié)果。當(dāng)數(shù)據(jù)證明舊模型有缺失、新模型能精準(zhǔn)還原后團(tuán)隊(duì)自然會(huì)接受。技術(shù)方案存在的最終目的是解決問題不是證明誰(shuí)更高級(jí)。如果想靠“這個(gè)模型很經(jīng)典很權(quán)威”來(lái)說(shuō)服團(tuán)隊(duì)阻力只會(huì)更大。4.6 坑六把REA當(dāng)成萬(wàn)能銀彈最后一條坑是反過(guò)來(lái)走向極端什么系統(tǒng)都往REA上套。一個(gè)簡(jiǎn)單的用戶配置管理系統(tǒng)只有查詢和修改既不涉及資源流轉(zhuǎn)也不需要審計(jì)對(duì)賬硬套R(shí)EA只會(huì)增加無(wú)意義的復(fù)雜度。判斷是否該用REA的標(biāo)準(zhǔn)很簡(jiǎn)單業(yè)務(wù)里是否存在多方資源流轉(zhuǎn)、是否存在審計(jì)追溯訴求、當(dāng)前狀態(tài)是否依賴歷史事實(shí)推導(dǎo)如果三個(gè)都否普通CRUD可能就夠用了。我自己的經(jīng)驗(yàn)是REA最適合的場(chǎng)景是“用戶持有資產(chǎn)型數(shù)據(jù)”的業(yè)務(wù)錢包、積分、優(yōu)惠券、庫(kù)存、配額。這類業(yè)務(wù)中的數(shù)據(jù)不僅是一個(gè)字段更是一種有生命周期、有歸屬方、可流轉(zhuǎn)的資產(chǎn)。判斷清楚再上模型會(huì)給你帶來(lái)巨大回報(bào)判斷不清楚硬上就會(huì)變成過(guò)度設(shè)計(jì)。最后把六個(gè)坑整理成速查表方便排查時(shí)對(duì)照坑位問題表現(xiàn)解決思路派生入事件重放結(jié)果與真實(shí)余額不一致事件只記錄原始事實(shí)漏掉系統(tǒng)Agent自動(dòng)過(guò)期等操作無(wú)責(zé)任方補(bǔ)建系統(tǒng)Agent浮點(diǎn)數(shù)量計(jì)算誤差導(dǎo)致對(duì)賬失敗全部使用整數(shù)最小單位查詢撞事件庫(kù)響應(yīng)越來(lái)越慢用快照投影歸檔團(tuán)隊(duì)阻力方案被質(zhì)疑影子運(yùn)行用數(shù)據(jù)說(shuō)話過(guò)度設(shè)計(jì)簡(jiǎn)單CRUD也套R(shí)EA先評(píng)估業(yè)務(wù)是否匹配寫在最后一個(gè)實(shí)用體會(huì)。我最早接觸REA時(shí)也覺得一個(gè)訂單要拆成好幾個(gè)事件實(shí)在太繞。直到后來(lái)一次對(duì)賬財(cái)務(wù)要我說(shuō)清楚“某用戶1月5日20點(diǎn)03分用余額買了一箱牛奶之后余額去哪了、積分發(fā)了多少、是否存在資金漏洞”傳統(tǒng)模型里的訂單狀態(tài)和流水表根本理不清是REA幫助我從事件流里逐條還原把資金鏈路完整講了出來(lái)。從那以后凡是涉及錢、庫(kù)存、積分這類模塊我都會(huì)先問自己一句我建的是狀態(tài)還是事實(shí)如果只能給一條建議那就是在建模第一周先用Excel把所有事件、資源流入流出、Agent列成一張大表把關(guān)系徹底捋順了再寫代碼。這個(gè)笨辦法比畫100張架構(gòu)圖都有效。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
天天爽天天操| 久久婷婷影院| 91婷婷视频| 99精品在线下载| 亚洲五月花| 91a片爽| 激情丁香五月婷婷啪啪| 午夜婷婷久久 | 色色色婷婷五月天| 大地9中文在线观看免费高清 | 91丨九色丨熟女|老版| 五月天婷婷爱| 99视频| 婷婷五亚洲| 久久一级片| 五月伊人网| 日韩欧美五月丁综合| 香蕉AV福利精品导航| 可以免费看的av网站| 激情 婷婷| 五月丁香啪啪啪| 日韩av干| 激情五月婷| 九月婷婷久久| 五月婷婷色播| 激情WWW| 秋霞免费三级片| 精品成人无码A片观看香草视频| 99热99美国在线观看| 五月色婷婷亚洲| www天堂99| 久草热8精品视频在线观看| www.天天干| 九九综合精品| 影音先锋毛片网站| 婷婷丁香97| 夫妻超碰在线| 成人精品视频99在线观看免费| 伊人啪啪网| 人人摸人人操人人爽| 国产免费av网站| 激情婷婷六月天| 五月天玖玖狠狠色色| 五月天婷婷午夜丁香| 少妇人妻人伦A片| 狠狠综合| 在线观看的av| 日本色婷婷| 深爱激清网| 狠狠色噜噜狠狠狠888了| 99精品久久| 四季日韩AV无码综合| 天天肏在线| 午夜天堂啪啪| 熟女激情网| 狠狠色成人影片| 天天干狠狠艹| 欧美激情综合色丁香婷婷五月天| 最新丁香六月婷婷| 99免费视频网| 五月天婷网| 婷婷爱婷婷| 99精品7| www99热| 他改变了拜占庭| 五月婷婷成人| www.99日本| 天天久久婷婷| 日本三级色| 综合九色| 人妻激情视频| 亚洲丁香五月综合| 欧美VA在线观看| 丁香五月亚综合图片| 黄色激情五月天| 久热这里只有| 天天爽天天| 六月丁香色色| 99精品偷自拍| 色婷婷yy久| 色青青电影色五月| 亚洲天堂婷婷| 99精品在线观看| 丁香五月天激情网址| 欧美精品99| 婷婷丁香射射| 日本久久爱| 丁香五月中文字幕久色| 日韩无码专区| 狠狠色婷婷丁香五月| 一起草av在线观看| 综合激情网| 秋霞午夜理论| 99热网址| 亚洲三级无码| 青青色com久久| 9视频在线成人网站| 亚洲免费综合一区| 91久久免费| 色婷婷文字幕| www.伊人天堂偷偷婷婷| 99自拍视频网站| 色综合色色| 国产99久久久国产精品免费看| 久久ri精品| www.sebowuyue| 热久久成人| 五月激情婷婷女| 久re热视频| 51成人| 狠狠婷婷爱| 天天日,夜夜爽| 热99热9| 99综合| 人妻内射视频| 婷婷综合天堂| 丁香婷婷五月综合影院| 五月丁香激情综合| 色婷婷久久综合久色综| 日本色色色| 99热这里只有精品1| 五月美女婷婷风骚| 2025最新亚洲激情在线| 玖玖综合色| 色偷偷五月天| 99无码超碰| 99热www.| 丁香五月天堂网| .精品久久久麻豆国产精品| 四虎99热在线观看网站| www.久久99| 亚洲 激情 中文| 五月天色视频| www.第四色99| 99青青草| 天天色中文字幕女优AV| 五月丁香av在线| 五月丁香亚洲综合| 狠狠色婷婷综合开心影视| 色综合久久88色综合天天99| 直接看的av| 激情久久久久久| 99久热视频在线| 婷婷色五月综合丁香| 色婷久久| 久久免费丁香| 九色无码| 97操碰碰无码视频| 色色色婷婷五月| 202丰满熟女妇大| 久久婷婷色| 久热中文字幕在线线观看| 91中文在线| 色婷亚洲五月丁香| 婷婷欧美| 超碰在线观看9| 五月婷婷伊人在线| 婷婷五月天丁香久久| 天天综合天天做天天综合| 激情五月天小说| 香蕉人妻AV久久久久天天| 婷婷丁香六月五月天| 超碰成人在线观看| 午夜丁香婷婷| 五月婷婷啪啪| 5月婷婷六月丁香| 96精品久久久久久久久| 丁香蜜臀黄色婷婷五月天| 天天久久综合| 成人无码精品1区2区3区免费看| 五月激情四射婷婷丁香| 色综合色色| 婷婷综合国产| 久9视频免费播放| 色天使色婷婷| 97色啪| 日本免费91| 十一月婷婷激情四射| 壅壅儕家a| 婷婷五月天Av| 99热伊人综合| 国产色网站| 人人操大| 色99网| 色啪影院| 开心五月色婷婷综合开心网| 亚洲综合婷婷六月丁香五月| 久久图色4| 日日爽夜夜爽| 五月丁香六月婷婷啪啪综合| 91蝌蚪窝视频在线| 丁香五月23111| 丁香五月激情久久麻豆| 99视频在线精品| 99ri精品在线| 免费做A爰片77777| 婷婷五月天综合久久| 激情五月天婷婷播播久久综合91| 激情六月色| 五月天激情网址| 狠狠色综合网站久久久久| 婷婷五月天精品| 婷婷久久大香蕉| 欧美va精品va老师va| 欧美性做爰大片免费看办公室| 婷婷五月俺要去| 天天色凹凸| 五月天淫乱视频| 色九九一二| 98色花堂98t.R| 激情综合色| 伊人激情AV一区二区三区| 色综合日日| 久久sp免费视频| 亚洲热视频在线| 久久久ww| 99久久欧美| 色婷婷精品视频| 久久伊人大香蕉| 成人国产欧美大片一区| 99riAV国产精品视频| 丁香婷婷综合精品六月初| 九九成人电影婷婷| 狠狠干夜夜干| 天天爽天天干| 五月婷色啪| 国产婷婷综合| 一级AV片| 丁香五月天色婷婷| 婷婷五月激情中文字幕| xxx综合在线| 天堂网色色| 第九色区av天堂| 五月在线| 一区二区三区四区无码| 五月婷五月婷伊人伊人五月婷| 狼人伊人天堂| 日本久久精品| 五月久久婷婷丁香| 狠狠擼综合| 狠狠久久婷婷| 日本综合99| 99久久婷婷国产综合| 五月天久久丁香| 色五月丁香五月| 真实的国产乱XXXX在线91| 五月丁香六月香香蕉| 密桃激情五月天综合网| 色久在| 人妻aV在线| 教师性爱毛片| 天天射影院| 五月丁香色婷婷久久| 丁香5月综合啪啪| 色婷婷伊人| 日本片日本片祼观看网站在线看中文版网页在线看 | 9999热这里只有精品| 在线观看免费狠狠色丁香香综合| 丁香五月激情啪啪啪啪| 无码人妻精品一区二区蜜桃色欲| 婷婷丁香色五月| 26uuu精品一区二区| 五月天激情在线视频| 激情五月天啪啪| 亚洲欧洲美女在线观| 色情五月丁香| 亚洲中文乱字字幕在线永久| 婷婷天堂综合| 婷婷五月电影| 91无码视频| 久久机热/这里只有精品| 激情五月激情综合网一级丸片| 99色中文| 91天天操天天干天天射| 天天操天天插天天射| 久久婷婷亚洲| 色情丁香五月婷婷精品| 色婷婷9| 天天精品视频免费观看| 99热这里只有精品在线观看| 久久久区区一久久久久久| 99热最新地址在线| 琪琪秋霞| 夜夜夜叫天天天做| 夜夜爽天操| 四色女婷婷| 丁香五月视频在线观看| 丁香五月天婷婷久久综合| 婷婷丁香六月综合激情站| 亚洲天99| www.97干视频| 婷婷射图五月天| 五月丁香婷婷婷激情爱爱| 另类图片五月天激情| 狠狠色噜噜狠狠狠777奇米| 99久久人妻精品无码二区| 综合激情婷婷| 日本一级黄色片。| 亚洲电影中文字幕| 99.N在线视频| 色婷婷基地| 九九AV| 蜜臀丁香黄色婷婷五月天| 久操热| 亚洲小视频免费播放| 99久久综合网| 色播播之激情五月婷婷| 婷婷五月色亚洲| 亚洲 五月 婷婷 成人| 丁香五月在线观看完整版| 亚洲最大五月天成人网| 日韩99视频| 久久九九网| 饮料下药迷倒漂亮女同事强干| 激情婷婷六月天| 色婷婷五月天| 爱射综合| 毛片九九九九九九| 欧美情月伍月天| 99热思思在线观看| 天天插天天操| 另类激情中文| 九久9精品| 图片区 小说区 区 亚洲五月| 色五月天激情| 丁香五月婷婷激情97| 色综合色综合色综合| 99九九热视频| 午夜丁香六月婷| 色五月丁香五月婷婷五月成人网| 色五月婷婷操逼| 这里只有精彩视频| 97干资源在线观看| 婷婷综合网| 天天日夜夜草进麻麻的子宫| 丁香五月六月| 四川BBB搡BBB搡多人乱亂| 九九久久偷拍| 安息电影在线观看完整版| 久久九九大香蕉电院| 99视频在线| 九热久| 色婷婷成人丁香| 丁香五月色情| 无码啪啪| 在线五月婷| 综合久久综合久久| 岛国av电影网站| 97色婷婷成人综合在线观看| 日日夜夜九九| 天天插天天狠| 狠狠狠狠狠干| 爱iii做iiii日| 亚洲综合五月天婷婷丁香| 天天综合天天做天天综合| 日日夜夜天天| 4399无码视频二区| 五月婷婷新网站| 免费观看欧美成人AA片爱我多深| 五月丁香激情综合网| 久久99精品久久久久久青青AR| 五月婷婷xxx| 色婷婷色婷婷五月| 国产亚洲精品AAAAAAA片| 99在线视频免费| 丁香五月婷婷色五月| 91狠狠色丁香| 在线成人国产| www.五月激情红色| 婷婷五月天伊人| 日韩欧美老妇性视频91久久久| 亚洲婷婷婷| 99re热视频这里只精品| 97色色综合| 六月五月婷婷| 中国女人做爰A片| 婷婷五月丁香久久| 午夜婷婷久久| 婷婷五月六月丁香| 色五月婷婷久久| 婷婷激情图片| 色婷大香蕉| 亚洲 在线 性爱 | 人人综合五月人人婷婷| 国产激情久久| 一区中文字幕电影| 激情六月一二| 2050人人操免费工开爱 | 九九99香蕉在线视频播放| 激情五月天色| 六月丁香啪啪| 六月婷婷综合| 日良久久| www色色com| 99视频激情四射| 在线成人国产| 丁香六月综合| 五月天婷综合| 精品99视频| 五月花激情网| 婷婷激情小说| 综合玖玖偷拍| 操操自拍| 婷婷黄色| 五月婷婷在线视频| WWW,五月天| 色婷婷综合网| 華人性愛AV在線| 超碰av在线| 日韩欧洲亚洲| 亚洲激情免费视频| 九月色婷婷综合亚洲| 亚洲麻豆乱码国产2028| 五月婷婷 婷婷五月 一区二区 久久久 | BT综合在线视频观看| 日韩在线观看亚洲| 国产精品操| 亚洲性爱电影| 91九色精品熟女内射| 91丨九色丨43老版熟女| 人人爽在线视频综合网| 青青草免费公开视频| 日韩狠狠色婷婷| 天天综合网站| 99热在线这里只有精品| 波多野结衣成人作品在线| 五月激情偷拍| www.婷婷,com| 无码99| 综合激情五月丁香| 超碰在线免费观看3 9| 思思 热 99| 五月丁香六月婷婷激情四射| 91人操| 色色五月天网站| 99激情在线| 影音先锋按摩| 久热99视频在线观看| 激情综合色婷婷啪啪六月天| 欧美、日韩、中文、制服、人妻| 第四色激情网| 色婷丨日丨天丨综合久久| 久久丁香综合香蕉| 亚洲AV网址| 99在线观看| 四季8848精品成人免费网站| 成人va在线播放| 九九色图| 九九XX视频| 日本va欧美va国产激情| 五月天开心激情网色欲无码| 九月停停| 国产亚洲在线| 五月婷婷激清网| 激情综合在线播放| 99在线精品观看99| 亚洲色99| 色婷婷91激情小说| 婷婷基地成人五月天| 九月激情综合| 亚洲日韩26uuu| 亚洲在线视频321| 色播五月网| 婷婷激情丁五月| 婷婷玖玖丁香| CHINESE熟女老女人HD视频| 天天射综合网夜夜操| 99人人操人人操人人精| 秋霞AV吧| 色噜噜婷婷| 六月亭亭久久综合激情| 99九九精品| 97色射| 在线看片av| xxx综合在线| 日本久久婷婷| 另类国产欧美视频| 啪啪啪大香蕉| 激情四射网| 天天插天天干天天舔| 久久久婷婷五月亚洲97号色| 婷婷丁香色五月天| 五月婷婷色| 色久五月天| 4399在线观看免费高清电视剧| 亚洲无码免费看| 婷婷免费视频| 色婷婷a| 国产熟女日日骚五月丁香爱| 九九久久精品| 亚洲欧洲午夜成人精品av| 欧美成人一区二区三区在线视频| 久久久久婷婷| 五月丁香亭亭| 夜夜骑天天玩天天日| 久这里只有精品99| 91视频一起草| 久久精品噜噜噜成人A∨色欲| 丁香网站| AV电影在线播放| 超碰不卡在线| 五月激情小说网| 婷婷瑟五月天久久综合| 99视频超级精品| 99久操| 禁片二区| 婷婷不卡基地| 99免费超碰在线| 亭亭玉月丁香| 丁香六月婷婷综合| av九九| 色噜噜狠狠色综无码久久合欧美| 五月天伊人综合| 五月天婷婷久色| 久热这里只有精品6官网亚洲| 1024成人在线观看| 99热丁香五月| 九九青草热| 91jiuseshunv| 五月天婷婷激情四射综合| 婷婷五月天久草在线| 亚洲A片成人无码久久精品青桔| 99在线精品免费视频| 超碰9| 99性爱视频| ji'qi'luan'ren'lun| 激情综合网 激情五月天| 五月天婷婷六月| 亚洲另类婷婷五月丁香在线播放| 婷婷激情中文综合| 亚洲艹网| 五月天激情在线视频| 五月婷婷丁香深深爱| 玖热精品综合视频| 婷婷五月天成人五月天| Av狠狠色丁香婷| 激情五月图| 深爱激情网五月| 99在线观看视频精品| 无码一区二区三区四区五区| 五月激情精品视频| 99热精这里只有精品| 丁香五月大片| 性日本精品| 婷婷五月天激情网站| 丁香五月天天高清在线| 色欲一二三| 开心五月深爱五月| 五月婷婷AV| 六月婷婷中文字幕| 亚洲亚洲人成综合网络| 色色婷婷综合| 国产精品成人网站| 婷婷五月天综合久久| 久久久999精品| 激情深爱婷婷网| 九九热这里精品| 久久婷婷五月综合色播| 久久99热这里只有精品| 超碰在线视屏| 成人无码髙潮喷水A片| 亚洲色图欧美色图日本视频| 超碰在线94| 永久免费视频| 操人妻90p| 激情九九这里只有精品| 九九亚洲| 丁香六月啪| 99视频这里有精品| 狠狠综合色网| 日本女天天爽| 日韩在线aaa| 91九色视频在线观看| AV大香蕉| 亚洲永远av在线播放| 亚洲操B视频| 桃色五月婷婷| 久久免费视频62| 91成人看片| 久久九九综合| 亚洲成Av人片乱码色第1集| 激情综合啪啪| 欧美狠狠地| 久久性操| 久久婷婷免费| 噜噜噜狠狠色综合| 亚洲激情网站| 五月丁香六月婷综合成人综合| 丁香五月婷婷操逼| 亚洲精品视频在线| www.五月天激情| 爱射综合| WWW.五月com| 99久久9| 巴基斯坦粉嫩无码视频| 色五月天激情| 99热99思午夜精品| 欧美天天五月丁香免费观看 | www久久久久久久久久久| 金品在线视频99| 99热热九九| 激情婷婷五月| 亚洲网站观看视频| 狠狠色综合网| 日日天天干| 欧美日韩中文国产一区发布| 丁香六月狠狠干| 亚洲精品小视频| 91操熟女| 午夜丁香六月婷| 丁香五月骚喷水视频| 手机旧版看人妻1025| 《亚洲操B久久免费在线观看,亚洲操B久久在线播放》在线播放 - 高清资源 - 97 | 成人av播放| 五月丁香六月婷婷综合网缴情| 99视频内射三四| AV六月丁香| 激情五月天开心网丁香无码| 色丁香五月婷婷| 丁香五月97视频| 五月丁香综合精品| 久久这里只有精品热在99| 五月丁香最新| 99热这里只有精品最新| 狠狠精品干练久久久无码中文字幕| 99热欧美偷拍| 很很干夜夜干| 麻豆忘忧草午夜| 综合狠狠干| 天天日天天爽夜夜爽| 99在线免费视频| 91玖玖| 天天做天天爱天天爽综合网| 丁香五月激情图片婷婷| 五月婷婷视频啪啪美女| 国产精品色色| 五月丁香亚洲校园欧美| 色婷婷婷婷| 人橾人| 99精品热| 五月丁香婷婷综合网色欲| 99精品22| ai97re99一本| 综合色综合| 少妇性按摩无码中文A片| 久久婷婷五月综合97色一本| 婷婷激情五月| 亚洲色综合| 日韩成人网址| 久久久网站| 日韩九区| 六月婷婷天天操夜夜爽视频| 色欲色香综合网| 超碰97干| 99无码视频| 五月丁香六月婷综合成人综合| 91久久电影| 97热久久五月婷婷| 日本在线视频播放91| enecarbon-materials.comWu染请涟系Bao护@wip1688| 欧美六月| 婷婷五月丁香久久| www.超碰| AA丁香综合激情| 丁香久久AV| 免费观看欧美成人AA片爱我多深| 人人添人人| 五月婷婷视频| 五月天狠狠网| 天堂中文国产| 天天操天天干天天日| 久青青久| 一级片操逼视频| 婷婷五月深深爱| 成人片在线免费看| 五月丁香激情四射| 五月天婷婷一起草| 欧美三级视频| 99色视频| 婷婷五月综合激情| 亚洲欧洲中文日韩久久AV乱码| 2020夜夜操天天爽| 嘿嘿视频免费看9| 国产精品国产| 久久视屏这里只有久久| 激情人妻蜜夜系列区| 四色AVwww| 五月丁香激情综合啪啪| 99这里只有精| 99精品无码网站| 欧美人人超级碰| 97操操操| 怡红院院久久| 99久久五月天| 久久精品人妻| 3www激情| 久操大| 九月婷婷综合八月丁香在线观看| 九九9久九9国产视频| 色播五月婷婷五月| 婷婷色婷婷亚洲成人| 四川女人毛多水多A片| xxx.色婷婷| 9色在线| 天天揷综合网| 99在线视频精品| 五月婷婷伊人网| www.com.色色| 久久久久久人妻| 国产日韩欧美| 九九人妻福利| 亚洲av网址| 99无码| 婷婷深爱五月| 婷婷深爱五月天在线| 五月丁香六月婷婷综合| 99熟女| 99热这里只有精品在线观看| 婷婷五月天.com| 97超级碰碰碰| 性按摩玩人妻HD中文字幕| 婷婷久久精品| 丁香五月网在线观看| 丁香伊人网| 五月丁香综合色婷婷| 九九人人操| 狠狠xx| 激情综合网,婷婷| 3p久久| 五月综合人妻| 五月天另类激情在线| 五月丁香天堂网| 五月婷婷六月丁香综合视频在线| 六月大香蕉| 久久曰9| 色婷婷综合网站| 先锋资源婷婷| 六月丁香婷婷五月| 欧美激情xxxXX| 伊人激情综合网| 五月婷婷精品视频| 666555。COm毛片| 五月丁香五月综合欧美| 国产精品电影网| 激情五月,激情综合网| 狠狠久久婷五月综合色| 九九综合九九| 美欧成人视频| 五月色丁香婷婷综合| 欧美性生交A片免费看| 人人澡玖玖一| 2016日日夜夜操| 午夜成人av在线| 国产毛片精品一区二区色欲黄A片| 99九无网码| 激情五月综合| 玖玖精品视频| 一本久道综合色婷婷五月| 五月婷高清视频| 色色日韩网| 婷婷99中文字幕| 9热在线观看| 超碰成人AV| 国产黄色大片| 久久99激情五月天| 人人摸人人干| www.玖玖九| 国产视频色色色色色色色| 激情六月天| 色99在线| 大香蕉久| 俺去也婷婷| 综合激情五月天| 日本欧美成人片AAAA| 久久三级视频| 99热综合| 亚洲五月婷| 成功精品影院| 中文字幕在线日亚州9| 久久精彩视频| 五月丁香色综合| 亚洲综合在线视频| 国产JK精品白丝AV在线观看| 色婷婷丁香五月| 国产这里只有精品| 超pen个人视频97| 久久精品A片777777| 99国产在线精品视频| 久久人妻熟女一区二区| 操B视频在线播放| 色婷婷av综合网| 综合激情四射一theav| 91日综合欧美| 啪啪黄页网| 97碰| 婷婷五月成人色综合| 狠色狠色狠狠色综合网| 色婷婷丁香五月丁香| 操操操操操电影网| 舔色婷婷| 九月激情网| 可以看的av| 五月美女婷婷风骚| 1024亚洲| 伊人激情| 综合激情综合啪啪| 五月天六月婷| 久久婷丁香五月| 狠狠综合| 丁香香蕉射射射| 色碰97| 丁香五月婷婷啪啪啪| 激情图片五月天| 中文字幕网伦射乱中文| 91精品国产色猫| 91视频一起草| 色婷婷精品小视频| 欧州色色| 五月丁香黄色视频| 成人αV视频免费观看| 婷婷性爱视频在线| 九九热AV| 欧美激情综合色综合色| 五月婷婷亚洲| 精品夜夜澡人妻无码AV| 久久日婷婷| 99热综合在线| 婷婷5月天av| 色色AV色色色东莞| 五月丁香五月综合欧美| 黃色三级三级三级三级 qixing300.shrkbk.com www.jinbozs.com tianmiaosw.com | 五月丁香六月| 91日精品| 激情综合4月| 亚洲欧美另类在线23p| 亚洲天堂大香蕉| WWW.国产| 吊色AV男人的天堂| 色综合五月婷婷狠狠干| 天天爱天天秀天天做| 涩综合婷婷| 91人人人人人人人| 激情五月天在线观看婷婷| 色5月婷婷| 99自拍视频在线| 91精品91久久久久77777| 99男人的天堂| 日韩综合大黄| 97人人超| 婷婷丁香五月天色色| www.激情五月天.com| 在线综合网| 亚洲精品字幕在线观看| 色综合视频| 亚洲五月天狠狠| 久久九九爽| 99精品久久久久久久久| 婷婷五月在线免费| 五月丁香啪啪| 亚洲精品一二三| 五月丁香影院| AV人人操| 一区二区成人电影免费播放| 日日噜噜夜夜狠狠久久丁香六月| 天天操天天日天天操| 色情五月综合婷婷| 天堂五月婷婷| 综合图区激情| 色九月| 色碰干| 97色色综合| www.91av.com| 五月开心婷婷中文字幕| 曰曰久久| 五月天之色情综合网| 天天干天天色天天干| 久久天天| 91精品婷婷国产综合| 色色五月婷婷丁香| 99热久久这里只有精品| 久久婷婷五月综合97色一本| 色玖玖导航| 日韩美一级毛卡片| 青青草婷婷综合五月| 日本色色色| 色吧综合网| 91久久精品无码一区二区三区| 久久五月天丁香| 激情九九这里只有精品| 无码免费人妻A片AAA毛片西瓜| 久操操| 日韩综合久久| 色欧美影院| 色丁香五月| 久久3级片| 韩国久久少妇视屏| 国产精品久久久久久喷浆| 五月天开心激情网色欲无码| 岛国av网站| 青青.com| 激情第四色| 人妻爽爽爽久久久久久久久| 99这里只有精品|v| 99热人人| 日本99久久| 丁香婷婷五月激情| 操逼六区| 国产综合视频婷婷| 91黄操| 日本久久爽| 九热免费视频| 另类伊人婷婷| 伊人干综合| 日韩欧美一级大黄网站| 日韩人妻无码专区| 日本91在线| 99精品在线观看| 99视频这里只有免费精品| 五月婷综合| 开心激情色婷婷五月天| 99成人| 99热精品一区| 草草色情综合网| 五月中旬婷婷丁香六| 大香蕉在线99热| 丁香六月婷婷综合在线| 99re免费视频| 亚卅毛片| 五月婷婷久久综合| 婷婷六月丁香开心深深爱| 狠狠色婷婷777| 婷婷的五月天另类视频| 思思久久99热只有频精品66| 开心五月婷婷激情网| 七月丁香婷婷 色色| 97婷婷五月天| 99久久精品国产色欲| 一级精品999WWW| 久久久8| 婷婷五月成人| 爱婷婷五月| 月色色综合婷婷网| 91婷婷色五月| 五月噜噜噜色综合| 四季8848精品成人免费网站| 激情五月婷婷六月丁香| 激情久久肏屄视频| 99色色网| 狠狠干五码| 亭亭玉月丁香| 五月天社区| 另类图片 五月激情| 亚洲AV日韩AV永久无码网站| 91激情五月开心| 26UUU一区二区| 伊人婷婷99热精品| 日韩人妻无码精品| 99re这里只有精品视频6| 91色综合久久| 中文字幕人妻在线| 五月丁六月香av| 婷婷亚洲久久| 97香蕉碰碰人妻国产欧美| 这里只有九九精品| 欧洲一区二区| 中字幕视频在线永久在线观看免费| 久久性爰视频这里只有精品| 久久伊人9| 国产精品色色| 欧美五月婷婷| 开心深爱五月天| 综合九九久久| 99色在线| 久久五月天综合| 欧洲永久精品| 在线综合91| 五月天另类激情在线| 五月婷婷在线综合| a色色片| 超碰在线资源| 五月天婷婷影院| 日本操B视频| 色视频2025| 99er热精品视频| 少妇被下春药玩弄A片| 亚洲美女网Va| 人人舔人人色人人高潮| 色婷婷国产精品综合在线观看| 国产精品人成A片一区二区| 另类激情中文| 五月丁香婷中文| 久久综合中文| 九九精品re免费视频| 免费黄色片子| 91碰碰视频| 亚洲色亚洲精品| 丁香五月情色| 国产超碰人人| 国产精品成av人在线视午夜片| 天天插天天插天天插天天插| 这里只有精品免费| 五月激激网w'w'w| 日本超碰在线| 亚洲婷婷综合视频| 亚洲乱码日产精品BD| www.婷婷亚洲基地| 洗浴中心操B视频| 天天色综合色| 99久热这里只有精品视频删减版| 婷婷欧美激情| 午夜微拍福利| 成人国产欧美大片一区| 99精品热| 成人电影在线免费试看| 五月天激情AV| 激情网第四色| 婷婷色五月婷婷姐妹| 激情六月婷婷| 婷婷色在线视频| #NAME?| 91 影音先锋| 99热只有| 色五月婷婷网| av在线资源| 99热亚洲精品| 婷婷丁香18| www,av好吊操| 色婷婷九月综合| 婷婷黄色五月天在线视频| 依人大香蕉| 超碰成人在线观看| 日韩在线观看亚洲| 六月丁香激情| 大香蕉啪啪啪啪啪啪| 婷婷情色五月| 欧美97超碰| 深夜婷婷 丁香| 亚洲国产精品VA在线看黑人| 五月婷婷丁香六月| 久久婷婷亚洲| 中文字幕 码精品视频网站| 久久久中文| 国产9色在线/日韩| 九九AV在线| 九月婷婷久久久| 乱码操操| 亚洲欧美婷婷五月色综合| 久久女人天堂| AV网站免费在线| 久久婷婷91| 99热最新精品| 日日干天天射| 久久色情| 五月婷六月| 少妇综合网| 伊人婷婷五月天| 亚洲国产精品SUV| 国产69久久久欧美黑人A片| CHINESE熟女老女人HD视频| 无码日本精品XXXXXXXXX | 69精品人人人人| 日韩黄在免| 久久婷综| 99综合成人视频在线观看| 9在线9在线婷婷在线国产| 激情五月天色婷婷综合| 色哟哟www| 超碰99热| 丁香五月天天| 97干婷婷五月天| 五月天婷网| 国产精品久久久海的味道| 97碰碰视频| 九九九热精品| 久久婷婷色| 成人国产欧美大片一区| 日韩成人精品中文字幕电影| 大香蕉综合| 五月停停丁香| 99热国产婷婷| 亚洲色久| 五月天天天天天天天天天天天天天天天婷婷婷 | 无码少妇高潮喷水A片免费| 99久久精品国产色欲| 五月婷婷啪啪网| 久久99网站| 4399在线日本A片| 色婷婷成人| 99riav 亚洲| 9.1综合网| 中文字幕AV网址| 国产超碰av| 六月婷婷色宗合| 香蕉久久国产AV一区二区| w婷婷五月婷婷w| 国产精品人人妻人人爽| 教师性爱毛片| 精品无码色欲AV| www.99视频| 久操干| 国产无套精品一区二区| 丁香狠狠干| 久久亚洲色导航| 亚洲六月色| 国产avapp 网| 激情婷婷六月天| 4438全国最大视频成人网站在线观看| 久久久月丁香| 五月丁香影院| 888精品福利地址| 亚洲AV免费在线| 久9热视频在线观看| 五月激情小说| bukadeavzaixian| 五月天久久丁香| 射婷婷中文字幕| 69五月天视频| 午夜天堂一区人妻| 开心 五月 综合| 可以免费观看的av| 久久丁香| 五月天激情久久| 婷婷丁香五月亚洲欧美| 99久久婷婷国产综合| 婷婷99中文字幕| 久久五月网| 成人五月天丁香婷| 亚洲AV网址| 玖玖爱综合网| 蜜臀av粉嫩av懂色av| 四色五月视频| 六月婷婷五月天| www综合久久| 可以看的av网站| 综合九九中文字幕| 激情网五月天| 九九自拍网| 国产精品久久..4399| 超碰91av| 婷婷伊人| 色情五月丁香婷婷网| 极品少妇XXXX精品少妇偷拍| 五月婷婷六月激情| 99热免费| 丁香六月视频| 激情九月婷婷九月| 婷婷在线免费| 丁香六月亚洲| 5月婷婷6月六月丁香| 最新日韩久热免费视频看看| www.婷婷,com| 五月丁香另类图片| 狠狠插狠狠插| 色另类五月天| 欧美特大片黄| 激情开心五月天婷婷基地丁香社区| 婷婷五月激情小说| 噜噜视频| 99热在线观看精品| 超碰久热| 九九热视频首页/这里只有精品| 538在线精品| 亚洲婷婷乱乱丁香| 92久操视频| 婷婷操超碰| 精品视频这里只有精品| 国产毛片欧美毛片久久久| 亚洲中文乱字字幕线在永久| 丁香婷婷五月天成人| 婷婷六月综合基地| 日本三级韩三级99久久| 成片免费播放| 五月婷婷啪啪网| 日韩免费99| 婷婷丁香五月激情| 丁香花五月天| 一级性爱大片| 91seav| 思思久久精品视频| 九九热狼人| 天天爽天天爽| 色久婷婷五月| 久99久视频精品| 天天天天干| 婷婷五月丁香综合亚洲| 屁股翘好撅高迎合跪趴| 99热精品在线播放| 婷婷中文无码| AA片在线观看视频在线播放 | 性爱激情小说AV五月丁香花| 五月婷婷欧美| 激情五月六月婷婷综合啪啪| 日韩操啪| 日韩视频99| 婷婷丁香五月欧美人| 婷婷丁香五月天影院| 九月婷婷| 色婷婷五月天激情在线观看| 色色色色欧洲| 99色综合久久| 色色色婷婷五月天| 丁香五月婷婷成人色区| 五月婷婷丁香大香蕉| 国产色色视频| 五月花综合视频| 日韩一级片| 夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂夂亚洲亚洲亚洲亚洲亚洲亚洲亚洲亚洲色 | 九九伊人网| 五月婷亚洲精品| 天天干,天天舔| 青青久久五月| 婷婷精品免费久久| 色五月亚洲开心网| 五月婷婷av| jiujiuxiangjiaowang| 26uuu| 久久人妻伦理| 婷婷国产综合| se.久久视频在线观看| 99精品久久| 色色色99| hd五月婷婷在线| 激情久久肏屄视频| 玖玖91| 综合网五月| 六月天婷婷| 亚洲丁香五月美女| 99ri国产在线| 日本丰满久久| 久热免费视频| 91婷婷丁香五月| 开心五月激情五月丁香五月婷婷| 亭亭色色五月天| 国产色香蕉精品五夜婷| www.五月天| 色热久| 五月丁香六月婷婷视频| 伊人五月天男人的天堂在线| 久久图色4| 五月婷婷 激情按摩| 国产这里只有精品| 日韩淑女人妻luan伦激情精品一区二| 久久最新色| 91久女| 婷婷五月天av| 97人人操人人| 深爱开心激情| 婷婷之六月丁香| 激情五月激情综合俺也去婷婷小说| 综合玖玖偷拍| 97操在线| 免费观看18视频网站| 色欲婷婷五月天| 激情五月天小说网| 思思热久久婷婷五月天| 丁香六月天婷婷在线| 一月婷婷色色| 色444综合网| 婷婷操无码| 99热这里有精品| 这里只有精品视频99| 日日干日日| 五月婷婷在线综合| 日日操人人操| 无码人妻一区二区三区四区| 婷婷丁香五月天婷婷|