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
返回資訊列表
WWW.夜夜操.com| 丁香六月色| 婷婷丁香五月激情图片| 第四色五月婷婷| 丁香午夜天| 婷婷丁香六月激情综合| 8区视频在线| 欧美日综合| 中文字幕 久久9999| 国产99久9在线| 99精品热| 开心婷婷五月| 狠狠色无码| 91色涩| 激情五月婷婷| 亚洲激情综| 99热99日…..| 久久女婷| 97碰| 婷婷欧美激情| 91综合网| 久久五月婷天天干| 色色无码| 色色五月丁香| 久久丁香五月天| 五月天成人在线播放丁香| 在线看片av| 狠狠操之狠狠操| 久综合4| 26uuu丁香婷婷五月| 天堂婷婷五月在线| 亚洲综合在线视频| 五月天大香蕉| 天天综合区| 亚洲精品视频在线播放| 97五月天| 天天干天天操天天爽| 538午夜激情| www.99精品视频| AA片在线观看视频在线播放 | 二人电影免费版在线观看| 无语停婷丁香网| 婷婷五月天小说网| 天天干天天日天天操| 超碰资源在线| 99人妻碰碰碰久久久久视| 五月天婷婷在看| 久婷| 欧美日韩成人在线| 偷偷狠狠久久婷婷五月天| 99热丁香| www.日本久久videos| 影音先锋日本三级资源| 久777| 婷色五月| 9|人妻人人操| 、激情六月天| 热的五码久久精品| 婷五月丁香| 婷婷九月激情| 天天情天天狠天天透| 色婷另类| 婷婷亚洲天堂| 日韩抽插操逼| 国产精品色一哟哟| 思思热99热| 淑女丝袜bi操逼123| 性色99| 淫荡综合网| 色色色色色色97| 五月天婷婷青青| 五月天激情网图片 - 百度| 超碰99久久| 人操人人| 亚洲色9| 婷婷五月天久久久| 婷婷色日本| 五月丁香婷色| 色五月女| 婷婷久久综合| 9久热精品在线视频| 久99久视频精品| 亚洲国产精品VA在线看黑人| 久久9热综合| 日本色超碰| 欧洲区自拍| 婷婷五月六月丁香| 国产色丁香| 天天在线天天综合网色| 岛国av网| 婷婷丁香综合成人| 丁香五月六月婷婷综合| 丁香六月激情综合| 91色色色视频| 五月婷婷色播视频| 色综合色色| 久久3p| 欧美色图天堂网| 九九热视频在线观看| WW婷婷五月天com| a毛片二逼wwwwwwwwww| 五月丁香A∨在线| 99热超碰天堂网| 激情五月综合网最新| 久久婷婷成人视频| 1024操逼视频| 性爱激情五月| 人人色人人摸人人看| 成人婷婷深爱综合网| 天天色综网| 九月丁香婷婷综合| 色婷婷女优有码五月亭| 五月天成人在线精品| 婷婷色5月激情网| 日本一道久久| www.综合久久| 99热这里只有的精品视| 9久精品| 国产探花一片区| 九九精品99| 色青青视频| 久久婷婷丁香| 一区二区传媒视频| 天天干天天色天天干| 色吧婷婷| 97色视频网| 亚州激情网站无码| 一级性爱视频| 91精产品自偷自偷综合| 五月天婷婷在线播放| 天天综合精品| www.丁香五月| 涩五月婷婷| 91人人人人人人人| 丁香美女主播视频在线观看| 99久久人妻精品无码二区| 久久激情天堂| 99视频在线| 欧亚成人A片一区二区| 久久婷婷夜| 婷婷综合在线| 色~性~乱~伦~噜| 婷婷六月成人| 国产色色色色| 亚洲视频码| site:minyis.com| 99日本黄站| 一起操 91N.com| 开心丁五月| 丁香色婷婷| 欧美色男人网站| 久久久久久久五月婷婷六月丁香综合,开心激情综合网 | 五月婷婷影| 最近中文字幕2019视频1| 色婷婷五月综合在线| 99久久玖玖| 日产精品一线二线三线芒果| 97婷婷丁香五月| 五月综合视频| 电影蜘蛛女| 久久婷婷六月综合| 成人操呦av| 国产成人AV在线| 亚洲色图在线视频| 翔田千里 50岁 无码| 九月婷婷综合网| 九九热免费| 色五月丁香A欧美com| www.日韩艹| 天天综合精品| 欧洲综合视频在线观看。欧洲,亚洲综合食品在线观看。 | 激情五月天影院| 爱iii做iiii日| 婷婷丁香激情| 99日在线观看视频| 九九色色网| 99久久99视频| 色激情五月天| 婷婷五月综合在线视频| 亚洲成人AV电影网| 99热综合网| 97超碰人人操| www.狠狠| 久久开心五月婷婷| 91久久综合亚洲噜噜成人在线 | 色婷婷很很丝袜| 五月丁香婷中文| www免费在线视频| 日日操,夜夜撸| 青吴乐视频| 亚洲情欲| 午夜婷婷| 九九无毛| 六月婷婷五月天| 五月天色播网| 婷婷久久婷婷| 久久婷婷成人| 婷婷五月天亚洲综合网| 噜噜色婷婷| 久久久91精品| 婷婷色中文字幕| 99热成人精品| 123草逼网| 少妇综合网| 俺去也在线官网| 白人荫道BBWBBB大荫道| 狠狠狠色激情综合适合| 丁香婷婷久久激情| 97人人做| www.com在线操视频免费观看| jiZZdr| 六月婷婷色综合| 无码免费人妻A片AAA毛片西瓜| 影音先锋 婷婷| 五月天丁香啪啪啪啪| 综合久久9| 欧美噜噜免费观看| 天堂呦 呦百度搜索-百度搜索| 五月婷亚洲精品| 天天综合网91| 丁香五月色色婷| 亚洲成人免费电影| 亚洲天天操| 五月婷婷干干干| 97婷婷五月| a网站免费观看| 亚洲女婷婷五月基地综合久久久| 伊人婷婷五月天| 超碰日韩成人| 影音先锋女人AA鲁色资源| 激情丁香五月天图片| 婷婷综合网站| 中文AV在线观看| 久久97久久99久久综合欧美| 无码色| 久草五月天| 99热这里只有99| 丁香六月婷婷社区| 操逼电影免费看| 亚洲激情综合| av久热| 99热这里只有精品一区| 五月丁香六月激情网| 91人妻人人操人人爽| Av狠狠色丁香婷| 99热一区| 婷婷深爱五月天| 色色色无码| 激情综合网激情五月欧美| www.五月婷婷久久.com| 殴美日比视频| 色9999日韩国产| 停停六月 综合| 欧美A片在线视频免费观看| 丁香五月天社区| 久久最新色| 九九精品视频在线观看| www、色色色| 日在线V视频在线播放| 在线日韩视频| 无码九九| 婷婷5月色| 色五月天.con| 激情美女五月天| 天天操加勒比| 激情网第九色| 欧美综合激情五月丁香| 丁香五月丁香伊人| 天天综合网网欲色| 亚洲丁香婷婷丁香五月天激情| 伊人AV五月婷| 色色色热| 五月丁香激情综合| 五月天婷婷在线视频| 色丁香五月婷婷| 九九色播五月丁香| 亚洲人妻AV| 色婷婷电影网| 色婷视频| 激情五月婷婷综合秋霞| 香蕉色色网| 久久婷婷一级片| 91黄色五月天视频| 大天天伊人| 日本天堂免费99| 91视频人人做97| 九九精彩久久| 久久与婷婷| 综合在线丁香五月| 亚洲日日日| 欧美狠狠色| 99亚洲视频| 网色99| 激情六月丁香| 大地资源色婷婷视频在线| 亚洲爆乳无码精品AAA片蜜桃| 久久AAAA片一区二区| 任你躁XXXXX麻豆精品| 激情五月四色| 青青草色在线视频观看| 婷婷的五月天另类视频| 色香欲综合| 久久五月天色婷婷| 午夜69成人做爰视频| 国产一级黄色影片,| 久久久噜噜噜操操操| 2022人人操人人看| 五月婷免费视频久久久| 色性日本| 婷婷六月丁香五月| 婷婷香蕉视频| 婷婷6月综合网| 日日射天天射| 99热国产精品| 99热伊人综合| 色色色色色色色综合| 丁香五月亚洲天堂| 天天综合网站| 自拍视频99| 黄久久久| 六月色色婷婷| 另类小说五月天| 国产操B| 97欧美在线| 婷婷五六日| 激情六月天婷婷| 久久九九@| 极品少妇XXXX精品少妇偷拍| 五月色婷婷影院| 色婷婷五月天天天做| 五月色综合| 婷婷丁香婷婷97| 久久综合婷婷| 久9免费视频| 欧美性生交A片免费看| 亚洲超级碰| www.色五月| 牛色色碰| 夜夜躁狠狠 | 色五月婷婷激情五月| 天天操,夜夜骑| 丁香五月六月综合激情| 97色啪| 六月婷五月丁香| 五月丁香啪啪啪综合网| 99视频在线观看视频| 五月天婷婷色播综合在线| 五月天综合网| www.99免费视频| 婷婷激情鹿城五月天| 免费亚洲婷婷中文字幕| 色综合天堂| 逼里香不卡| 99色热| www.99日本| 欧美va欧美va差| 最近中文字幕大全免费版在线 | 久久精品爱爱| 91色婷婷综合久久中文字幕二区| 99热这里只有精品1025| 亚洲六月婷婷| 激情婷婷99| 久久九九99亚洲国产久精综合| 久久综合九九| 97人妻碰碰碰久| 五月婷婷偷拍| 久久婷婷色色| 26uuu欧美| 99热日韩| 婷婷五月天影院| 棕合影院色色| 99在线精品视频| 亚洲五月天另类小说图片| 亚洲中文AV| 视色综合| 丁香综合久久| 久久五月网| 99九九综合久久九九| 日本色五月| 五月亭亭色| 一丁香五月天月AV| 91人人网| 五月天精品| eeuus五月婷| 色婷婷综合网| 婷婷丁香五月天中文字幕| 久久9情免费| 久热这里只有精品99re| 色老久久| 激情综合网五月婷婷| 婷婷激情五月天综合| 久久九九网| 蜜乳.comcom| 欧美顶级少妇做爰HD| 久久人妻情侣| 婷婷五月天综合AV| 涩涩涩五月天| 亚洲成人乱码av网站| 中文字幕91,综合| 97丁香五月| 第五婷婷伊人丁香| 九九热视频这里只有精品| 丁香无五月网| 真实熟女-91九色| 久色婷婷200| 伦乱天堂| 99视频热99| 天天色天天操天天射| 欧美大香蕉视频| 五月婷婷六月天| 五月天四色房丁香| 日韩 中文 欧美| 色色色综合| 热的无码综合视频| 乱码操操| 99婷婷综合| 激情伊人| 99久久玖玖| 激情久久综合网| 色色色五月婷婷| 五月天影院婷婷在线观看| 99久久婷婷国产综合亚洲| 大香蕉伊人99| A网在线欧洲| 亚洲综合在线播放| 一级片无码| 91狠狠色| 日韩啊啊啊| 99成人网一区| 丁香五月大香蕉AV| 4399无码视频| 色噜噜狠狠一区二区三区| 久久96热| 99综合色色色| 开心五月婷婷婷美女| 激情五月六月婷婷| 五月色丁香| 五月丁香六月婷婷不卡免费无码| 国产 亚洲 在线| 日韩三十六页| 成人无码髙潮喷水A片| 99热这里是精品| 久久五月网| 婷婷爱爱蜜臀天天操| 激情6月| 天天干天天干天天| 97精品欧美91久久久久久久| 无码区婷婷五月花开| 五月婷婷久久开心网| 国产婷婷五月天| 婷婷丁香91综合| 五月丁香黄色视频| 天天射美女| 五月天婷婷丁香视频| 色女人久久| 69久久久| 亚洲黄网在线| 操老逼综合网| 精品久久久中文字幕大豆网推荐理由| 丁香五月性| 九色自拍| 中文字幕永久免费| 五月丁香婷婷色色色| 五月丁香六月婷婷综合| 国产精品色一哟哟| 亚洲 小说 欧美 激情 另类| 人人色AV| 亚洲天堂亚洲色色色| www.久久爱.com| 99热九九在线| 丁香激情五月少妇| 国产精品色婷婷久久久精品| 色九亚洲| 在线中文av| 性生活视频98791| 久久九九re热| 123草逼网| 97碰碰草| 四川BBB搡BBB搡多人乱亂| 婷婷五月成人| 综合五月婷婷| 大香蕉啪啪啪| 成人做爰黄A片免费看直播室男男| 99热这里只有精品8| 99色色| 五月丁香色色网| 婷色五月| 激情五月综合网| 色情丁香五月婷婷精品| 天天激情站| 色5月婷婷| 狠狠五月天| 丁香六月婷婷综合| 亚洲中文AV| 涩玖玖免费视频| 激情久久丁香| 丁香五月情色| 9999色色色色| 99在线精品视频| 综合久久综合久久| 色五月婷婷在线视频| 丁香五月天欧美| 丁香婷婷视频一区二区| 丁香五月六月婷婷综合| 日日噜噜夜夜狠狠久久丁香六月| 内射在线CHINESE| 日本三级99人妇网站| www.久操| 亚洲永久免费| 亚洲婷婷成人五月天| 激情五月婷婷综合| 99久在线精品| 久在线88综合| 久久婷婷人人| 91热er| 中文字幕乱轮| 五月丁香婷婷欧美| A片试看50分钟做受视频| 99色在线观看视频者| 婷婷丁香综合| 婷婷六月色丁香视频在线观看| 婷婷五月色丁香在线看| 五月婷婷欧美| 人人操9| 色久女| 美女要搞搞天天搞搞搞网站| 色五月婷婷五月天| A片试看120分钟做受图片| 九九超日本| 久久久99视频| 99操逼| 亚洲国产99| 色婷婷色和| 色婷婷电影| 日日肏天天操| 99在线精品观看99| 色婷婷综合综合网| 婷婷五月天亚洲丁香| 国产亚洲在线| 狠狠色狠狠爱| 亚洲一区二区无码蜜乳av| 婷婷五月丁香六月| 久久一操| 99精品在线下载| 久草婷婷| 亚洲天堂啪啪| 五月天综合视频网| 大香蕉福利导航| 五月婷婷天堂| 婷婷五月丁香在线视频| 激情五月婷婷综合秋霞| 五月丁香综合激情在线观看| 亚洲无码成人| 婷婷久久伊人| 久久99精品久久只有精品| 天天干天天做| 草草视频91| 人人操av| 青青999| 99这里是99在线视频| 五月天婷婷久久| 五月丁香综合色婷婷| 婷婷五月丁香六月伊人网| 欧美99热| 欧美天天草人人草| www.色综合| 欧美日本VA| 色色网站| va中文资源在线观看| 婷婷五月天福利| 永久思思热在线| AAA久久| 99re在线视频| 久久看婷婷| 风流少妇A片一区二区蜜桃| 色噜噜狠狠色综合无码久久欧美| 综合久久综合久久| 人碰91| 婷婷久久亚洲| 9 大屁股在线视频精品| 内射激情在线| 婷婷D区| 五月四色色| 国产69久久久欧美黑人A片| A在线观看| 九九人人精品| 伦乱天堂| 婷婷五月天av| 午夜性爱影视一区77| 97干在线| 99热这里只有精品98| 成人片在线播放| 色情·com| 99ER热精品视频| 亚洲综合五月天综合| 日本无码专区| 五月丁香六月综合激情无码软件亮点 | 天天操,天天插| 亚洲欧美日韩另类| 综合另类视频| 色婷五月天亚洲| 91女人18毛片水多国产| 久久狼人天堂| 婷婷六月激情丁香| 97干在线观看视频| 五月色情| 丁香婷婷色色| 97婷婷丁香五月天激情图片| 色射7856五月天激情四射| 五月丁香久久网| www.狠狠狠狠| 男女免费视频999| 99爱精品| 婷婷狠狠操| 久久丁香| 激情五月婷色| 伊人久久婷婷| 成年人丁香五月| 色婷婷五月天亚洲| 91pornav在线| 国产黄大片在线观看画质优化| 激情婷婷五月| 日日干夜夜撸夜夜骑| www.com.色色| 亚洲亚洲人成综合网络| 碰碰女| 五月婷婷在线网站| 色五月色五天色情网| 九九色婷婷五月天| 婷婷深爱五月天| 五月婷婷激情综合网| 深爱女色婷婷丁香五月亚洲图区| 人人妻人人澡人人爽| 成人无码髙潮喷水A片| 亚洲乱码w在线观看| 婷婷激情综合网| 国产精品久久久久久白浆色欲| 久久久久久久91| 中文av网站| 五月花免费视频| 97深爱伊人综合| 996er热| 中文字幕av网站| 欧亚成人A片一区二区| 9l视频自拍9l视频自拍九色学生| 日韩操| 婷婷伊人激情婷婷| 色一情一乱一乱一区91Av| 久草视频大香蕉99| 猫咪伊人AV| 精品人妻伦九区久久AAA片| 色碰碰| 色香欲综合| 婷婷激情网五月天| 久久五月婷综合网| 国产激情综合五月| 丁香五月亚洲AV| 97久久草草超级碰碰碰| …亚洲黄色在线播放日韩、av中文a…| 天天干天天日蜜臀av| 国产美女无遮挡裸体毛片A片| 色吧综合网| 亚洲网站999| 丁香婷婷视频在线| 色五月婷婷综合| av中文网站| 丁香六月视频免费观看| 日日操日日射| 激情婷婷综合五月少妇| 伊人五月丁香| 婷婷狠狠干| 免费在线观看欧美激情xx小视频| 99免费在线| 欧美人妻一区二区| 天天爱天天吃狠天天透| 狠狠综合网| 丁香五月婷婷基地| 五月丁香自拍| 五月丁香香蕉| 久草热在线视频| 色人久久| 免看黄大片AA | 成人做爰高潮A片免费视频 | 91九色视频| 二色AV| XX色综合| 五月色情| 亚洲AV永久无码影院黑人| 伊人成综合五月婷婷| 欧美操综合| 激情99| 婷婷五月天成人网| 五月婷伊人| 亚洲激情综合五月婷婷啪啪| 天天爽,夜夜爽| 婷婷五月激情的图片| 99色婷婷| www.91av.com| 久久婷婷激情四射五月天| 久久久婷婷五月亚洲97号色| 狠狠色丁香久久久婷| WWW五月天| 丁香六月婷婷综合啪啪| 超碰在线观看9| 日日撸夜夜操| 99碰碰。| 久久久性爱视频| 樱花99视频| 五月天色网站| 4399在线日本A片| 少妇性BBB搡BBB爽爽爽电影| 狠狠色综合久久久久| 激情亚洲婷婷| 五月天色官网| 五月综合视频| 国外亚洲成AV人片在线观看| 秋霞av不能| 五月丁香六月综合情在线观看| 99re思思精品在线观看| 国产激情在线| 人人人操 超碰| 在线中文亚洲| 九九热在线视频,| 激情婷婷五月天| 538在线精品| 激情五月综合第一页| 一區四區歐美日韓| 碰碰女| 亚洲激情四谢| 激情五月丁香婷婷夜夜操| 婷婷色成人| www.久热| 黄网在线观看免费| 精品人妻久久久久久久| 99自拍视频在线观看| 免费碰碰视频久| 亚洲成人网无码| 久久久性爱视频| 婷婷在线视频| 五月婷婷欧美| 色五月激情五月| 草草夜夜操| 色六月丁香婷婷啪啪啪| 亚洲人人操| 六月色丁香婷婷| 思思99热在线| 欧美色婷婷| 成人在线日韩欧美| ji'qi'luan'ren'lun| 99re热视频这里只精品| 五月天无码| 丁香五月影视| 婷婷 伊人 久久| 婷婷五点亚洲| 伊人五月婷| 开心五月婷婷六月丁香| 五月天精品| 51XX午夜影福利| 激情五月天婷婷丁香| 九九综合影音先锋| AV 3P| 操91| 五月激情丁香六月狠狠干| 日本久久天堂| 色99日韩| 天天摸天天肏| 激情九月综合| 天天摸天天肏| 超碰成人在线观看| 婷婷的99视频网站| 色色丁香五月天| 99精品在线观看视频| 五月婷久久草| 五月天婷婷爱| 日韩在线视频中文字幕| 97丁香婷婷| 99九无网码| 久热69| 久久久99免费视频| 大香蕉婷婷丁香天堂AV| 六月丁香大香蕉| 色综合天堂| 99在线热| 深爱激情五月网| 超碰三级秋霞| 麻豆AV一区二区三区| 色插综合网| 狠狠色噜噜狠| 精品成人a v无码内射| 色婷大香蕉| 激情五月婷婷开心网| 欧美日本高清视频99| 俺去也五月天| 色婷天天| 操人91| 白天AV月月| 免费在线观看AV网站| 色婷婷丁香五月天激情综合网| 热热色色五月天婷婷| 国产成人99久久亚洲综合精品| 婷婷久久爱| 99精品在线观看| 久操干| 婷婷激情综合网| 99热18| 亚洲精品又粗又大又爽A片| www.精品99| 琪琪色网址| 五月天婷婷影院影院观看| 日本色久| 欧美激情综合| 亚洲99视频| 在线超碰91| 久久九色| 五月婷婷婷婷婷婷艺术| 亚洲成人av在线观看| 国产avapp 网| 婷婷在线播放av| 免费无码毛片一区二区A片 | 4399在线日本A片| 五月婷婷激情四季| 超碰av在| 91丨九色丨白浆秘| 色五月丁香总合网| 国产综合丁香五月天| 99热免费精品| 97色伦另类图片小说视频| 爱iii做iiii日日| 99热偷拍| 欧美噜一噜| 中文字幕,综合,91| 极品人妻VIDEOSSS人妻| 99精品大片| 九九视频网| 欧美三级视频| 久色视频| 岛国AV网| 五月天日日操夜夜操| 九九色综合九九色| 久久九网| 丁香婷婷九月| 欧美成人精品一区二区| 99自拍视频网站| 国产精品91抖高| 色婷婷AV在线| 天天情色五月天| 伊人色综合影院视频| 日韩在线视频9色| 丁香五月色五月婷婷宗合| 久久多色| 99热大| 激情五月天丁香| 激情五月婷婷丁香| 久久99激情| 99热在线精品观看| 久久看九九90| 欧美日韩999| 天天插综合| 天天看片日日夜夜| 丁香婷婷六月天| 女同在线9| 9l视频自拍9l九色成人| 丁香激情网| 色色免费网战视频| 色五月涩涩婷婷蜜桃| 久久狠狠干| 日韩美女在线视频19| 五月天激情国产综合婷婷婷 | 91窝窝| 青草视频在线观看视频 | 99热99ai| 狼人婷婷久久| 婷婷中文字幕在线| 丁香五月婷婷图片综合| 国产成人精品一区二三区熟女在线| 女同激情久久av久久| 精品国产va久久久| 亚洲一区二区无码蜜乳av| 大香蕉人妻| 色色色婷婷五月天| 男人天堂AV在线一区二区| 国产99久| 97五月婷| 怡红院AV亚洲一区二区三区H| 成人片在线播放| 五月婷婷综合激情网| 激情婷婷丁香五月天| 狠狠色综合精品视频在线| 色爱终和网| 丁香五月丐人妻| 国产欧美日韩性爱| 99色在线| 久久五月综合| 久久久久久xxxxx| 日韩久久视频| 五月婷俺去也| www.婷婷网| 在线五月婷婷小电影| 那里有AV网址| 狼人久草| 五月天婷婷午夜丁香| 久99热| 99综合视频在线| 丁香六月天AV| 亚洲色9| 色播丁香五月婷婷操:屄| 五月婷丁香花| 婷婷爱综合| 成人精品一区二区三区四区五区| 激情六月五月婷婷综合网| 狠狠干狠狠干狠狠干狠狠干| 再綫Av免费視品| 久久九九免费大视频| 九九视频精品在线免费| 久久人妻高清中文| 五月天婷婷中文字幕在线播放| 五月丁香婷婷成人综合网| 五月丁香六月花| 91午夜激情| 99亚洲精品| 99热精品中文字幕| 一本道在线电影| 日日躁夜夜躁狠狠久久AV| 亚洲人操亚洲人| 婷婷丁香五月天操逼| 在线中文亚洲| 夜夜躁狠狠 | 在线sebiav精品视频| 五月天丁香欧美激情| 青青草原亚洲天堂| 久久久久久xxxxx| 激情五月天色婷婷综合| 欧美色五月| 色色色色色色色色五月先| 色婷婷亚洲婷婷| 四虎国产精品永久在线国在线| 亲子乱AV-区二区三区| 国产真实乱了老女人视频| 狠狠狠狠青草| 婷婷丁香久久| 婷婷在线午夜| 91精品久久久久久久久| 香蕉操亚洲| 国产精品VIDEOSSEX久久发布| 日韩无码亚欧无码| 成人 在线 日韩| 先锋av性爱成人电影| 丁香婷婷久久老熟女综合网| 日本WWW九九九| 精品夜夜澡人妻无码AV| 91日综合欧美| 久久精品性爱视频,| 婷婷五月色亚洲| 欧美性爱五月天| 国产原创视频91九色| 成人av播放| 天天搞夜夜叫| 欧美一级操逼视频| 99热精品在线| 秋霞AV淫| www,婷婷五月天777me,com| 久久久久亚洲AV无码网影音先锋| 97久久超碰| 香焦网五月天| 久久人妻在线| 97色干| 天天综合网色欲香| 丁香五月天欧洲在线| 天天拍天天操| 真实的国产乱XXXX在线91| 丁香五月影视| 五月天狠狠网| 激情五月婷婷五月| 亚洲天堂无码| 丁香五月av在线| 婷婷导航| 九九99热| 狠狠草狠狠草| 欧美槡BBBB槡BBB少妇| 色婷婷丁香| 天堂草在线看www| 国产美女无遮挡裸体毛片A片| 97香蕉碰碰人妻国产欧美| 日本熟女内射| 国产黄色在线观看| 狠狠干狠狠色| 任你操精品免费| 另类图片五月天婷婷| 婷婷97狠狠干| 99热在线观看免费精品| 色婷| 五月婷婷丁香婷婷| 丁香色色五月| 五月丁六月香av| 99热免费| 99热最新精品| 色色激情网| 色婷婷AV在线| 色婷婷色99国产综合精品| 色综合久久88色综合天天| 色丁香久久久| 无码激情AAAAA片-区区| 五月色丁香综合| 亚洲中文乱字字幕在线永久| 丁香五月先锋| 97色97干| 久久总和99| 天天干天天干天天干天天干天天干| 丁香五月婷婷香| 欧洲综合色| 国产性爱在线| 噜噜噜色噜噜| 久久久亚洲精品一区二区三区浴池 | 天天草天天摸| 丁香五月九九| 久久免片| 亚洲超级碰| 这里只有精品免费| 人人插9| 99操无码视频观看| 亚洲成人中心| 99九九综合久久九九| 九色91国产| 日韩成人av在线| 久久激情五月| 日韩啪啪网| 色婷婷中文字母五月丁香| 婷婷丁香六月天| 99热国产国产| 狠狠爱成人综合网| 直接看的AV| 五月花激情网| 伊人狠狠丁香婷婷综合尤物| 色啪影院| 九热视频| 久久伊人日日夜夜| 人人综合色| 舔色婷婷| 91狠狠色| 欧美顶级少妇做爰HD| 99久久精品网| 九九99在线| 色小说五月天| 97人人操在线| 国产国产乱老熟女视频网站97| 精品无码人妻一区| 色 噜噜 九月 婷婷| 欧日韩成人| 97天堂| 国产免费性爱| AV性爱网| 婷婷六月色开| 欧美色一级色| AVDV久久| 欧美黑人大吊| 爱操天堂| 黄网在线免费观看| 亚洲 精品 综合 精品| 婷婷九九色| 99热老网站| 日本va欧美va精品发布视频| 婷婷WWW久久| 亚洲色99| 思思热久久爱| 91超级碰| 久热精彩视频98| 亚洲午夜视频| 26uuu91| WWW99热| 欧美槡BBBB槡BBB少妇| 天天透天天爱| 91操色| 奇米影视777在线_在线观看午夜_h小视频在线观看_岛国大片 | 五月天三级| 在线超碰精品| 综合色色网| 久狠狠狠| 亚洲激情免费久久| 国产免费av在线| 欧美性猛交99久久久久99按摩 | 婷婷激情五月综合基地| 99精品视频推荐| 成人精品视频99在线观看免费| 天堂综合久| 五月婷婷丁香五月亚洲色| 97色色综合| 真实的国产乱XXXX在线91| 大香蕉天堂| 色丁香影院| 天天日夜夜高潮| 色婷婷五月影视| 丰满少妇猛烈A片免费看观看| 类似婷婷激情综合网站| 五月熟妇婷婷久久| 久久久性爱视频| 日本久碰| 久久激情五月| 原琪琪色影院| 婷婷五月亚洲一本在线丁香| 久这里只有精品99| 激情人妻综合| 久久99免费视频| 噜噜在线| 可以看的AV| 2020日日干| 丁香五月久久综合| 99热20| 亚洲成人在线免费| 一本到不卡高清DVD| 欧美经典片免费观看大全| 97人人干| 五月天丁香婷婷社区| 色色色成人网| 伊人午夜综合色啪| 国产xxxxx在线观看| 九九热99视频| 久久98热re| 99人人看| 五月天婷婷丁香人人操91| 日日操夜夜操不卡| 亚洲精品V天堂中文字幕| 六月婷婷激情图片| 国产伊人大香蕉| 啪啪视频99| 三男玩一女三A片| 国产精品大香蕉| 欧美成人精品A片免费一区99| 天天肏高清在线| h在线看免费版在线看| 五月天天爽| 天堂草在线观| 婷婷激情五月综合丁香社| 婷婷五月天伊人网在线观看视频| 欧美激情综合| 婷婷永久在线| 欧美日韩999| 操久久网| 婷婷五月天堂| 91操人| 成人五月天婷婷| 婷婷丁香五月天婷婷| www,8050,午夜三级| 五月天日日操夜夜操 | 亚洲天堂制| 狠狠一日| 色吧99| 婷婷干六月综合旧址| 婷婷综合久久综合| 艹色18p| 六月激情网| 久99在线视频| 97精品欧美91久久久久久久| 丁香六月婷婷久久综合| 婷婷久久婷婷色五月| 欧美狠狠草| 亚洲五月丁| 99热无码| 久久婷婷五月天蜜桃| 综合久久久| 亚洲综合五月| 天堂无码人妻精品AV一区| 欧美大片| 中文字幕精品推荐免费在线观| 伊人五月综合网| 91色九| 狠狠夜夜五月丁香| 伍月婷丁香花全集| 天天插天天插| 大香蕉五月丁香| 超碰久热| 97综合视频在线| 男人天堂AV在线一区二区| BT综合在线视频观看| 伊人大香五月天| 99热只有这里才是精品| 天天天天天日| 激情五月婷婷综合| 风流少妇A片一区二区蜜桃| 色五月综合激情网| 久婷婷色| 欧美亚洲999| 岛国AV网| 草草操操| 97日韩无套内| 日本婷婷在线| 丁香婷婷六月激情| 国产午夜一区二区三区| 99九九精品| 久久婷婷九月国产精品| 伊人五月天久久| 婷婷第六色| 五月天伊人综合| 欧美这里只有精品| 婷婷久综合| 色色丁香五月天| 色五月成人网| 五月丁香婷婷AV| 亚洲无码色色| 欧美六月婷婷| 久久一热免费视频| 久久婷婷综合五月趴| 综合五月天| 青青草99热久久精品国| 丁香婷婷五月激情综合| 婷婷五亚洲| 色情婷婷五月天| 婷婷五月a| 丁香五月骚喷水视频| 天天色噜| 婷婷五月天国产传媒| 亚洲欧美婷婷五月色综合| 思思热AV| 大香蕉伊人久久| 97人人爱人人操| 狠狠狠五月婷婷六月丁香| 亚洲色久| 五月天丁香花婷婷| 丁香五月骚喷水视频| 超碰精品在线| 无毒黄色网址| 激情五月婷婷网在线观看| 超碰色综合| 色黄啪啪| 日韩一66精品| av网址在线| 成人午夜在线视频| 99惹精品视频| 99精品在线观看| 国产精品色婷婷久久久精品| 九热免费视频| 久久九九色| 91视频五月丁香| 色婷婷色情| 久热无码| 色99在线| 九九综合伊人| 天天综合网色欲香| 五月丁香六月婷婷在线播放| av国产精品| 色色自拍视频网站| 在线中文亚洲| 九九九午夜视频| 五月花在线观看视频| 丁香色色五月| 丁香婷婷免费| 欧洲色| AV激情五月| 97热这里只有精品| 色五月婷婷操逼| 婷婷狠狠97| 综合网啪| 久久婷婷六月综合综合| 日比视频91| 嫩草AV久久伊人妇女超级a| 99久久九九视频| 亚洲XX日本| 香蕉97碰碰碰欧美| 2050人人操免费工开爱| 日韩操人| 丁香香五月激情免费视频| 丁香五月激情五月| 99在线观看亚洲| 中文字幕成人| 五月亭亭六月激情| 色综啪啪网| 人人操A|