免费国产精品自在自线-91精品国产色综合久久久浪潮-99热久久免费频精品-国产精品国模在线观看-久久亚洲国产精品成人?V秋霞-久久国产一级A片免费播放-亚洲国产欧洲综合97久久-久久国产白嫩美女呻吟高潮

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
返回資訊列表
婷婷99狠狠躁天天躁中文| 色婷婷狠狠18yy| 五月丁香色婷婷伊人| 亚洲精品V天堂中文字幕| 亚洲成人噜噜| 天天日夜夜草进麻麻的子宫| 成人网在线视频| 婷婷激情在线| 《丁香激情综合久久伊人久久》影视在线观看 -高清预告手机免费播放 -三妹影院 | www.色综合| 天天免费日日夜夜夜夜| 夜夜夜夜做天天天做无码视频| 亚洲成人网站在线播放| 怡春院天天干| 国产在线网址1| 97操在线视频| 日本精品99网站| 搡BBBB搡BBB搡18| 婷婷色正月| 国产在线6| 99久久新视频| 亚洲色色五月| 狠狠久久婷婷| 丁香五月综合久久| 丁香五月综合无码趴趴| 丁香久久九九99| 婷婷五月天成人| www.黄色片-久久成人国产精品在线播放-999AV| 亚洲五月天天| 日本特黄aaaaa| 亚洲精品国产成人AV在线| 婷婷五月天在线综合| 久久婷婷五月综合| 人妻中文在线| 台湾综合丁香五月蜜桃| 婷五月丁香| 久婷五月| 激情另类综合| www.五月天婷婷姐姐| 99操逼视频| 五月婷婷黄网站大全| 四LLL少妇BBBB槡BBBB| 99热老网站| 99色色网| 久久性爱视频| 激情综合网五月天| 五月激情小说| 婷婷五月丁香四射| 国产超碰人人| 婷婷五月在线免费| 99热骚货| 婷婷五月天开心网| www.五月婷婷.com| 九九热精品| 伊人婷婷五月天| 色色婷| 免费精品99| 开心色五月天久久久久久久| 91色色色18| 久9久成人精品视频| 亚洲99热| 啪啪一区| WWW.五月com| 欧美怡红院黄站| 少妇2做爰HD韩国电影| 激情五月天婷婷| 色婷婷香蕉| 色综合色综合网| 99久久99久久综合| 婷婷丁香色女人| 97操资源婷婷| 久久久这里都是精品| 色色色激情| 色婷五月婷婷| 色色网五月激情| 99re8这里只有精品99re8热视频| 久久久WWW| 五月婷婷天| 五月天婷婷成人网| 99啊精典免费视频| 国产精品噜噜在线视频| 亚洲色婷婷五月天| 色情五月综合婷婷| 精品爆操| 婷婷五月丁香色情| 激情综合五月天| 五月天另类激情在线| 清纯唯美 激情四射| 日本激情综合| 成人精品在线观看| 99热在线只有精品| 三人荫蒂添的好舒服A片| 青青草原亚洲久| 欧美精品A片一区在线观看| 九月婷婷久久久| 日本本土色网第一区| 色婷婷丁香中文在线播放| 草综合14| 一级黄色片看看| 日本色99| 五月天综合视频| 丁香六月婷婷久久综合| 99热碰碰| 丁香五月婷婷欧美成人色图| 五月丁香在线| 色婷婷香蕉| 丁香五月激情视频在线| 一本色道久久综合狠狠躁小说| 免费观看欧美成人AA片爱我多深| www.99热| 免费婷婷| 干一干xxxx| 99er免费在线观看| 五月丁香成人网| 五月婷婷性爱网| 色婷婷五月天中文字幕| 9l视频自拍9l九色9l成人| 人人干人人看| 91尤物九色在线| 五月丁香婷中文| 欧美五月婷婷| 97操碰碰无码视频| 久碰婷婷视频| 99热热这里只精品996小说| 五月丁香人人婷婷在线观看| 欧美性爱五月天| 六月久久婷婷| 99久久精品国产色欲| 九九综合影音先锋| 激情黄色五月天| 色婷婷九月| 9一精品视频观看| 色色亚卅| 婷婷福利影院| www99热| 亚洲激情久久| 人色五月天婷婷| av九九| 99久久.www| 久久久久久五月天| 91人人看| 久久免费精彩视频| 爆乳熟妇一区二区三区爆乳照片| 伊人久久婷| 亚洲影院婷婷色| 呦呦v线| 色99色| 激情五月天在线观看婷婷| 日本五月天网站| 欧美碰碰| 久久婷婷五月综合色奶水99啪| 欧美啪啪五月天| 色播激情五月天| 激情综合文学| 热99免费在线| 激情婷婷丁香五月天小说| 亚洲综合色色| 丁香六月婷月91婷月| www.狠狠| 欧美成人网婷婷综合在线| 天天操夜夜操| 日韩色情亚洲五月天婷婷| 成人超碰网| 婷婷色五月久久| 亚洲爆乳无码精品AAA片蜜桃| 伊人婷婷青青cao| 思思久久精品| 日本在线噜噜| 久久久久久99精品无码| 狠狠穞A片一區二區三區| 五月丁香香蕉| 色婷婷六月| 日韩精品色| 久月久在线视频| 日日夜夜爽爽| 久久婷婷五月综合色奶水99啪| 日本激情91| 日本久久人人| 成人网在线观看视频| 五月婷婷自拍视频| 日韩综合网络男女香蕉a片| 99热这里只有精品22| 在线,国产,色,热视频| 99国产精品白浆在线观看免费| 777丁香六月青青草婷婷综合久月| 成人免费黄色短视频| 色婷婷狠狠久久综合五月| 1024在线视频| 五月天激情影院| 丁香五月综合在线播放 | 任你爽视频| 亚洲欧洲色色| 91丨九色|PRNY熟妇| 婷婷五月天激情电影| 91超碰人人操| 色拍九九九| 日韩一级网站| 色色婷婷综合网| 99日在线观看视频| 日操| 热99一二三| 99久久99久久综合| 人人爽天天爽| 91精品国产综合久久密臀| 97碰成超视频免费视频| 大香蕉220| 狠狠穞A片一區二區三區| 日本激情ⅩXX免费视频| 国产精品色婷婷99久久精品| 色婷婷丁香花五月天| 天天日天天插| 婷婷日日夜夜| 丁香五月天激情AV| 五月亭亭六月色| 超碰99成人在线| 伊人五月综合网| 婷婷十月激情综合网| 亚洲AV综合网| 激情五月婷婷视频一区二区三区| 综合久久十三| 少妇搡BBBB搡BBB搡毛茸茸| 丁香五月婷婷五月| 五月丁香激情婷婷| 一本伊人色婷| 国产精品久久久60086| 激情综合在线观看| 婷婷色啪| 在线观看亚洲视频影院| 成人VAV视频在线观看| 日本精品久久久久中文字幕| 久久五月丁香| 亚洲中文字幕网| 婷婷五月天高清无码| 久久久久久草黄色片AV在线观看| 狠狠色婷婷777| 成人片在线免费看| 性爱激情小说AV五月丁香花| 久久日婷婷| 国产精品久久久久久久久久久久| 丁香五月综合| 国产精品美女| 午夜大香蕉| 九九av| 99a级片| 色色综合网络| 激情五月影院| 丁香五月激情网| www.婷婷com| 这里只有精品久久| 男女啪啪做爰高潮无遮挡| 亚洲综合五月天婷婷| 色日本综合| 橾逼网| 久久五月综合| 久狠狠狠| 国产在线黄色| 99这里只有精品视频| 色婷婷综合久久久久| 天天插综合| 天天日日夜夜爽。| 色色五月婷婷久久| 另类视频五月天| 99热这里只有精品16| 婷婷五月天综合久久| 婷婷久久色| 丁香六月欧美| 美日韩成人| 99久.| 丁香六月啪| 综合色五月| 日本老女人黄页在线播放| 久久婷婷超碰| 五月婷婷丁香五月亚洲色| 99re这里只有精品9| 三级三久久线久久99久目本WW| 丁香五月欧美色综合| 香蕉久久国产av一区二区| 婷婷六月综合基地| 色五月婷婷婷婷婷婷婷婷婷婷| 色色日韩网| 玖玖在线资源视频| 激情五月,色播五月| 五月丁香影院| 久久怡红院| 激情98色婷婷五| 男人的天堂在线婷婷| 丁香五月久久社区| 91丨九色丨大屁股| 综合色在线| 婷婷五月天综合久久日美女| 亚洲AV中文在线| 婷婷丁香色五月亚洲| 色综合性视频| 91久久| 日韩一级片| 中文AV网站| 精品99在线看| 夜夜夜叫天天天做| 婷婷91| 九九热精品在线| 新激情婷婷| 玖玖五月丁香| 婷婷五月天影视| 激情综合丁香五月| 国产精品色色| 超碰com| 婷婷五月天,影院| 99热在这里只有精品| 97自拍视频在线| 国产成人AV不卡| 色婷婷AV在线| 99热亚洲只有色| 五月婷婷综合激情网| 色综合五月婷婷狠狠干| 丁香六月婷婷综合激情欧美| 丁香五月天堂亚洲社区| 这里只有精品,日韩视频| 777色色色| 五月婷婷片| 热99热久| 亚洲 无码 中文字幕 中出| 亚洲啪啪网| 综合色、色综合| 99re热在线视频| 色播五月丁香| 色图亚洲91| 狠狠干五月天婷婷网| 可以免费看的AV网站| 婷婷丁香五月综合| 色婷婷婷av| 天天爱天天狠天天透| 久久国产一区二区三区| 五月天婷亚洲天综合网综合| 欧美久热| 成年人夜夜喷水| 九九在线这里只有精品视频| 丁香激情综合| 五月丁香在线国产 | 亚洲另类视频| 91综合色噜噜| 99久久激情视频| 欧美日韩精品人妻狠狠躁免费视频| 人人妻人人澡| 婷婷永久在线| 久久综合干| 婷婷成人五月天成人文学| 激情五月天。| av免费人人| 拍真实国产伦偷精品| www.99热视频| XX色综合| 狠狠色丁香综合| 丁香五月电影| 六月婷婷网| 色无码| 91欧美| 丁香六月久久| 亚洲五月丁香综合网| 丁香九月激情| 婷婷丁香视频在线观看免费 | 成人在线网站| 97碰久久| 欧美日韩AAAAA| 日韩人妻无码专区| 99 色色吧| 99ER热精品视频| 色激情综合狠狠婷婷| 丁香久久| 这里只有精品视频一区| 色色网91| 五月天啪啪视频| 成人av在线电影| 久久婷婷啪啪视频| 色综合xx| www.cao.com久久| 天天干天天操天天拍| 碰久久精品w| 五月婷婷开心五月| 狠狠色婷婷7777久| 一级AV片| 色色色婷| 国产精品在线视频| 青草青草久9视频在线视频| 五月丁香在线观看| 久热这里只有精品性色AV| 久久久久婷婷| 婷婷丁香色五月| 懂色av蜜臀av粉嫩av永陈冠希| 99在线资源| 四月婷婷五月色综合| 大香蕉久久| 色情五月天婷婷| AVV黄| 91婷婷色五月| 六月丁香婷婷尤物| 成人视频在线免费播放| 欧美韩国日本| 五月婷婷天堂| 五月婷婷丁香av| 丁香五月天天| 欧美性猛交99久久久久99按摩 | 婷婷俺去也| 激情五月婷婷丁香六月| 日韩欧美性爱| 九九精品热| 天天碰夜夜操| 丁香婷婷色情| 五月丁香直播| 97操视频| 91丨人妻丨国产丨丝袜| 99久久综合网| 丁香五月六月综合欧美| 激情五月婷婷欧美极品| 久9免费视频| 五月丁香六月激情| 久草五月婷婷| 桔色成人在线| 婷婷五月精品在线| 综合五月婷婷| 二级黄色毛片| A片天天| 成人在线网址| 色婷婷五月天在线观看| 玖玖九九99| 激情综合九月| 亚洲无aV在线中文字幕| 久久性都花花世界成人免费视频| 五月天丁香| 亚洲午夜一区二区| 四色AVwww| 激情五月天婷婷久久久久久久久久久| 成人免费在线电影| 丁香婷婷老司机久操| 99操逼| 丁香五月激情网| 色小说五月婷婷| 99热这里只有99| 狼人婷婷综合| 99热这里只有精品3| 丁香五月婷婷深爱综合激情| 婷婷色五月激情强奸四射| 97日本在线播放| 99精品视频在线观看| 激情婷婷五月天| 操啊操av| 99热视精品| 五月天激情网图片 - 百度| 激情婷婷丁香五月天| 久热伊人在91| 久久免费试看120秒| 香蕉97碰碰碰欧美| 青青草免费公开视频| 超碰免费在线| 狠狠五月天| 色一情一乱一乱一区91| 大香蕉伊人99| 夜夜 操无码| 激情丁香五月| 噜噜操操| 丁香五月色情| 99热99色| 99精品偷自拍| 婷婷五月天VI| 久久99精品久| 2015WWW永久免费观看播放| 丁香六月综合| 五月天AV大香蕉| 丁香五月很很肏| 亚洲中文AV网站| 激情五月天福利| 99热99日天天干| #NAME?| 啪啪色激情五月天| 色五月欧美| 超碰无码318604| 人妻久热| wWw色五月| 婷婷六月综合在线| 人人人舔人人人操人人人摸人人人97| 丁香婷婷噜噜| 午夜丁香婷婷| 亚洲欧洲中文日韩久久AV乱码| 国产黄大片在线观看画质优化| 在线看片h站| 五月九九综合| 中文精品在| 五月婷在线| 国产婷婷五月中文字幕高清| 九九视频这里只有精彩| www.久久爱.com| 日本综合色图| 五月婷三级片| 天天肏在线观看| 激情综合网五月在线播放| 亚色网站小视频| 亚洲丁香五月| www.久久久久| 成人超碰网| 日本欧美999久久久三级片| 91打屁股视频网站| 五月丁香WWW| 91色情播放| 丁香五月香蕉| 亚洲综合色婷| 成人短视频在线观看| 婷婷色五月天第7色| 丁香婷在线| 久久99精品久久久久久噜噜| www.色五月| 亚洲精品视频电影| 天天综合永久| 五月婷婷色| 9九九久久精品无码专区| 色色色在线| 狠狠久久婷五月综合色| 五月天婷综合| 国产精品久久久爽爽爽麻豆色哟哟 | 99re思思| 夜夜撸日日操| 色欧美一级| 玖玖婷婷综合| 五月天久久丁香| 婷婷99狠狠躁天天躁| 天堂美国久久| 亚洲 综合中文| 五月激情六月综合| www婷婷色| 女婷久久| 开心五月婷婷| 丁香五月天影院| 只有精品在线观看| 欧美日韩成人免费在线| 色色色色色日韩午夜激情| 国产欧美婷婷| 五月丁香婷婷综合网| 91丨九色丨首页| 综合激情五月四射婷婷| 97人人操| 亚洲色图81p| 婷婷狠狠五月综合| 亚洲综合色网| 婷香五月网在线| 五月丁香色婷婷久久| 97人碰人操| 国产五月丁香在线| 色婷婷色99国产综合精品| 婷婷爱五月| 久久精品亚洲热| 中文字幕精品无码一区二区| 色激情综合狠狠婷婷| 五月丁香操婷逼| 亚洲精品444久久久久久| 丁香五月婷婷成人综合| 丰满少妇猛烈A片免费看观看| 97资源欧美日韩大香蕉超碰一区| www.天天干| 色综合久久88色综合天天| 婷婷中文字幕版| 色婷婷久久| 9色在线| 亚洲婷婷91丁香| 色哟哟性爱av| 色五月婷婷综合在线| 草久私拍| 五月天婷婷久久| 五月丁香中文婷婷中文| 婷婷五月天综合在线| 日本性视频| 色情五月天婷婷| 成人免费黄色短视频| 深爱激情小说五月婷婷| 青青久在线视频免费观看| 性爱在线播放av| 久久ww| 五月激情偷拍婷婷| 日碰日| 亚洲色色香蕉| 91久久色| 丁香五月天综合| 包操45分钟网站| 蜜臀AV在线观看| 玖玖资源网站最新站| 国产精产国品一二三在观看| 婷婷丁香激情五月天色色| 天天日色情| 99热99色| 日本色天堂| 91九色首页| 婷婷五月在线综合| 婷婷激情六月中文| 婷婷五月激情图片| 免费精品66| 教师性爱毛片| 91肏| 色狠狠伊人久久五月丁香| 色九九综合色| 九热视频在线精品15| 五月天婷婷激情网| 天天插操| 成人短视频在线| 成人必爱视| 久热A片| 综合性爱网| 六月婷婷之青青草| 久久五月天丁香花| 99国产在线| 天天干天天操天天上| 久久五月婷婷视频| 99操99| 婷婷五月亚洲一本在线丁香| 九九热这里只有精品7| 色色欧美色色| 久99久在线| 色五月天网| 天堂中文国产| 开心色色五月天综合| 久久婷婷五月天激情| www.婷婷网| 99热www| 日韩aaaaa| 丁香六月婷婷综合欧美| 秋霞午夜理论| www.婷婷.com| 91制片厂久久久国产电影| 五月丁香久人妻中文| 色五月丁香婷婷综合| 99热碰碰| 91丨九色丨首页| 久久98| 久久五月综合| WWW、日本色丁香、co m| 99精品女人天堂| 国产精品美女久久久久AV超清| 九热免费视频| 欧美成人网99网| 久久99热这里| 涩五月婷婷| 五月丁香中文婷婷中文| 丁香五月开心七月| 久久婷婷五月天| 亚洲五月天婷婷| 五月婷婷六月综合| 99成人无码| 涩涩五月天综合| 久久婷五月综合| 亚洲美女裸体被操在线观看| 99精品国产在热久久| 国产激情AV| 国产日韩欧美性爱| 可以看的AV网站| 99热精品9| wwW天天干| 欧美99热| 激情视频网址| 91一起艹| 91色五月| 91碰| 中文字幕,综合,91| 五月天婷婷久草丁香| 1级欧美日韩| 91无码一区人妻A片蜜| www.夜夜| av中文在线| 五月婷婷中文字幕| 久热 91| 91九色 婷婷| 都市激情亚洲| 九热久| 大香蕉久热| 中文久久婷婷| 9久热在线视频精品| 啪啪操操| 人妻AV在线观看| 丁香婷婷九月| 久久精品99| 在线99热| 欧日韩AV| 开心五月深爱五月婷| 五月婷综合性中心| 另类综合网| 婷婷瑟瑟五月天| 丁香五月成人av| 天天日天天爽夜夜爽| www夜夜| 久久婷婷五月天激情四射| 色噜噜狠狠色综合成人网| 操碰99| 狠狠色噜噜狠狠狠888| 婷婷久久五月天| 国产午夜成人免费看片无遮挡| 超碰只有精品在线| 97超碰在线观看免费| 九九精品99久久久| 久久婷婷精品| 秋霞网在线观看理论91| 九九视频在线观看视频6| 国产真实乱对白精彩| av操B网站| 加勒比日本一区二区三区| 丁香六月啪啪啪| 秋霞三级色戒| 婷婷丁香在线播放| 色色五月天丁香婷婷| 俺去也综合| 婷婷情色开心五月天99| 加勒比久热| 欧美久久婷婷| www激情网| 五月天婷婷免费视频| 五月婷婷中文字幕| 99亚洲精品综合在线| 欧美日韩国产一区| 狠狠另类视频| 亚洲欧洲午夜成人精品av| 狠狠狠狠狠狠| 欧洲区自拍| 免费国产VA国产免费| 色噜噜婷婷| 操91| 狠狠色噜噜色狠狠狠综合色 | 日本啪啪视频HD| 丁香密臀AV激情网| 色欲丁香久久| 国产欧美第五十五页| 亚洲第一成人无码A片| 国产午夜精品一区二区| 亚洲婷婷丁香五月亚洲| 狠狠穞A片一區二區三區| 久久性视频| 日本少妇AA一级特黄大片| 六月激情久久婷婷| 丁香五月伊人| 五月丁香六月激情网站| 久久综合首页| 五月天开心色色网| 日本九九九九| 久久人妻人人| 丁香五月花影院| 新97人人上人人| 九九九九这里只有精品| 欧美三级A做爰在线观看| 久9热视频| 五月婷婷深爱六月| 很很干天天干| 婷婷五月天综合久久| 中文国产五月天| 婷婷伊人綜合中文字幕| 亚洲成人AV在线观看| 婷婷五月天在线综合| 天天插天天干| 五月丁香六月在线欧美| 狠狠色噜噜狠狠| 91人人人人人人人| 五月婷婷伊人久久| 国产成人精品亚洲线观看| 婷婷五月丁香久久| 99国产精品久久久久久久久久久| 婷婷五月天综合久久日美女| 激情五月六月婷婷综合啪啪| 五月天婷婷综合网| 色五月首页| 99视频在线播放大全| 色九综合| 26uuu精品一区二区| 日日操夜夜操不卡| 五月丁香婷婷伊人| 亚洲无码 图片区| 丁香五月综合图片在线观看| JAPANRCEP老熟妇乱子伦视频| 99色色爰| 亚洲午夜av| 天天综合情| 夜夜操天天干| 丁香六月婷月91婷月| 亚洲九区| 激情五月婷婷丁香六月| 亚洲热热视频| 激情综合自拍五月婷婷色五月| 激情色色色| 五月丁香六月久久| 五月丁香久久| WWW.桔色成人.COM入口| 黄桃AV无码免费一区二区三区| 无码G高清天| 国外亚洲成AV人片在线观看| 激情五月丁香激情综合网| 五月日韩中文字幕| 婷婷五月天资源| 强奸幻女毛片| 9九色首页| 九九九九国产| 亚洲五月天激情| 久热这里精品免费| 玖玖@三月天天丁香婷婷| 婷婷丁香五月亚洲| 1024成人在线观看| 九九碰九九爱97超碰| 99久久免费性爱视频`| 色婷婷丁香五月天| 成人欧美Va| 69久久久| 国产成人综合在线| av婷婷丁香 六月| 婷婷99狠狠躁天天久久久九九九| 26uuu亚洲精品国产| 操日本三片99| 久久这里只精品| 久久这里只有精品无码| 吾爱AV导航| 日韩成人免费电影| 天天拍夜夜爽| 視频福利乱色| 婷婷五月天综合网| 人人做天天爱| 超碰93在线观看| 久久伊人大香蕉| 色五月婷婷内射| 婷婷色五月激情强奸四射| 综合网色| 欧美α√| 色VA| 综合网色综合| 激情第四色| 狠狠搞亚洲| 97久久草草超级碰碰碰| 香蕉AV777XXX色综合一区| 久久精品这里只有精品免费首页| 色色色激情| 色碰97| 丁香五月在线播放| 五月婷婷在线综合| 深爱婷婷基地| 丁香婷婷久久综合在线| 五月婷婷色播| 五月婷婷之婷婷| av在线超清中文| 色五月综合97| 成人做爰A片免费看视频| 五月天综合色| 精品九九视频| 在线中文av| 久久久久97| 91中文在线| 99热综合色图| 99er久久| peg 2区三区四区的| 色五月婷婷伊人| 国产熟妇的荡欲午夜视频| 99精品在线| 色五月综合网| 激情综合网络插| 91精品国产日韩91久久久久久国模| 久久AAAA片一区二区| 日韩久热| 欧美婷婷成人| 99热九九在线| 中文字幕丰满乱孑伦无码专区| 婷婷九九视频| 五月天大香蕉婷| 亚洲精品久久久无码| 久9视频| 日日爽夜夜爽| 九九久久视频| 俺五月| 成久综合视频| 99无码超碰| A级毛片高清免费不卡播放谢谢谢谢| 婷婷色色亚洲| 午夜天堂一区人妻| 欧美在线干| 少妇高潮一区二区三区99欧美| 丁香五月婷婷六月丁香| 日日舔夜夜操| 97韩国久久电影院| 九九视频热| 五月婷婷综合激情| 色五月综合婷婷久久综合婷婷久久综合婷婷久久综合婷婷久久 | 深夜男女福利刺激影院一区完整| 久久大香蕉伊人| 97se在线视频| 久草婷| 91在线精品一区二区| 精品一二三区久久AAA片| 婷婷精品| 99re6在线视频精品免费| 可以看的av网站| 色色色图| 99热精品在线观看| 激情色色| 四虎国产精品永久在线国在线| 婷婷综合激情| 无码人妻少妇色欲AV一区二区| 婷婷丁香五月综合| 婷色五月天| 99re6在线视频精品免费| 国产精品一区在线观看你懂的| 99综合视频一体| 丰满少妇猛烈A片免费看观看| 色丁香五月婷婷| 亚洲欧洲中文日韩久久AV乱码| 粉嫩AV久久一区二区三区| 中文字幕人成乱码在线观看| 欧美大片免费观看| 91九色白丝| 亚洲久艹| 人人干99| 天天插天天插天天日| 丁香六月av| 人人操超踫| 激情丁香五月天图片| 思思热在线| 五月丁香激情啪啪| 91人妻PORNY九色大屁股| 欧美大片| 国产性爱色| 色欲九区| 婷婷爱综合| 久色国产| 国产精品日日躁夜夜躁| 丁香婷婷六月| 丁香五月综合狠狠| 九九人人看| 中海油常州环保涂料有限公司| 五月丁香婷婷五月色| 骚货艹网站视频| 色情五月婷| 五月天综合| 97碰 在线视频观看| 色婷婷丁香九月| 丁香六月AV| 狠狠激情五月天| 亚洲综合五月天婷婷丁香| 亚洲九区| 国产色色色色色| 色色吧综合| 色色色色av777| www.91在线观看| 五月丁香六月激情综合| 超碰五月婷婷五月天| 色婷五月| 国产,欧美,日韩,性爱| 猫咪伊人久久| 五月网站| 色狠狠色综合久久久绯色AⅤ影视| 99热这是里只有精品| 日日操夜夜骑| 亚洲激情av| 牛牛色av| 人人人人人人人人人草| 久色| av网站不卡在线| 五月天色综合| 伊人网色婷婷五月天| 欧美日韩99| 99ri精品在线观看| 亚洲综合激情五月天婷婷| 深爱激清网| 大香蕉综合网| 婷婷五月丁香91| 天天射综合网夜夜操| 久久婷婷精品| 影音先锋综合网| 欧美综合激情五月丁香| 久久人人九九| 岛囯综合激情网| 五月丁香六月婷婷啪啪综合| 五月天桃色深爱网| 五月天色色无码| 亚洲久热| 99久超碰| 免费观看日韩成人av| 亚洲第一色色色| 97碰在线| 亚洲成人av在线播放| 人妻 性久久久久久| 狠狠干五月天| 涩综合网| 99爱精品| 综久久久| 婷婷十月丁香| 国产成人一区二区三区在线观看| 婷婷伊人久久| 丁香五月婷婷偷拍| 免费成片在线观看| 国产精品视频久久99| 日本猛少妇色XXXXX猛叫| 亚洲综合婷婷| 亚欧州精品视频| 六月色婷婷综合影视| 五月开心婷婷| 国产SUV精品一区二区6| 在线观看熟女少妇| 色五月婷婷丁香五月| 超碰资源在线| 狠狠色大香蕉| 久久婷婷五月综合色丁香| 婷婷丁香五月综合激情小说| 又大又粗九一在线| 精品99网站| 久久99国产综合精品免费| 第2色五月婷| 免费视频无码| 永久思思热在线| 另类小说色婷婷| 性爱先锋AV| 五月婷婷开心网| 天天做天天要天天爱| 九九av| 久久五月天激情美女| 九九免费视频| 五月天激情综合在线| 可以看的AV| 99色精品视频| 九九亚洲| 色婷婷五月婷婷五月婷婷五月| 香蕉97碰碰碰欧美| 婷婷丁香色五月久久88| 97涩婷婷| 开心激情网五月天| 人人插9| 欧美色色色色色色色| 337p大胆噜噜噜噜噜91Av| 日日色综合| 99色色网站| 97日韩无套内| 亚洲天天综合| 射区导航| 激情99| 丁香五月激情六月综合| 91在线视频观看午夜福利| 五月亭亭六月天| 国产激情av| 五月丁香婷婷综合网| 夜夜天天久久婷婷| 九九精品丁香花| 婷婷五月色情| 欧美性二区| 1024操逼| 综合网激情| 五月丁香婷婷色| 久久精品一区二区三区四区| 九九无码视屏| 香蕉婷婷色五月| www.久久爱| 激情五月天激情综合网| 日韩精品超碰在线观看| 99这里都是精品6| 五月天成人手机在线视频| 婷婷色基地在线看 | 九九热最新视频| 日韩成人电影AV| 日韩黄色中文字幕| 日日干夜夜干| 99这里只有精品视频在线| 中文超碰视在线| 无码人妻激情| 激情影院免费视频婷婷五月天| 久久99jiu9| 99热这里只有精品在线| 精品一区二区三区木瓜| 色色丁香五月| 涩涩五月天| 91精品久久久久、久五月天| 婷婷成人网五月天| 91丁香色五月| 亚洲综合激情五月久久| 激情小说婷婷五月| 综合97五月| 9一精品视频观看| 99色婷婷| 夜色综合网| 99色视频在线观看| 国产精品成人AV在线| 草草夜夜操| 激情九月综合| wwwwww.色| 激情婷婷五月久久| 青青草Avb在线| 亚洲成av人影院| 99热免费精品| 丁香五月综合网亚洲综合欧美狠狠 | 五月婷婷人人人操| 欧美va欧美va差| 婷婷五月天改成什么了| 玖玖婷婷色| 色综合视频在线| 丁香五月AV| pom538精品视频| 六月狠狠综合| 色色成人網| 日本久久婷| 狠狠 久久| 婷婷五月花| 日日天天干| av在线免费网站 | 婷婷丁香97| 色情婷婷五月天| 9这里只有精品| 99这里有精品久久97| 久久精品系列| 色网站9| AV成人在线网站| 狠狠综合| 99热免| 91碰在线| 毛片新网地| 噜噜国产| 五月天激情亚洲| 色区域网站视频| 亚洲成人电影aaaa| 亚洲精品乱码久久久久久综合| 狠狠操综合| 另类激情五月| 五月天天综合| 亚洲午夜Av| 青青日韩| 婷婷五月天丁香成人社区| 久热精彩视频98| 日韩啪啪视品| 999热视频精品99免费在线| 亚洲视频一区| 国产亚洲成AV人片在线观黄桃| 久久曰曰| 色区久久| 嫩草AV久久伊人妇女超级A| 综合色播| 成人视频网| 免费视频WWW在线观看网站| 九九在线精品| 色一情一乱一伦一区二区三区| 亚洲无码99| 都市激情亚洲| 天天干电影| 激情五月色婷婷| 夜夜谢天天干| 亚洲色五月| 亚洲综合激情五月久久| 五月激情啪啪| 国产午夜精品一区二区三区嫩草| 99噜噜噜在线播放| 成人国产欧美大片一区| 天天揷综合网| 大香焦A∨| www99xxxx五月丁| 97操碰在线视频| 一区视频网站| 六月丁香啪啪| 婷婷爱综合| 激情综合网激情五月欧美| 午夜婷婷五月天在线| 天天摸天天日天天舔| 四色五月婷婷| 久久精品婷婷| 婷婷综合网| 日韩人妻AV在线| 久久九九亚洲| 曰曰久久| 一区二区三区四区五区| 亚洲色色色色| 丁香六月久久| 九月婷婷| 91久久久久久久久久18| 亚洲在线成人| 粉嫩av懂色av蜜臀av熟妇| www.婷婷网| 五月天婷婷视频30| 久久视频婷婷| 欧美99热| 五月九九综合| 久久婷婷网| 天天综合.com| 欧美一级操逼视频| 99超级碰免费视频| 成人国产欧美大片一区| 中文网婷婷字幕婷| 99热这里是精品| 人妻 性久久久久久| 婷婷六月综合基地| 99热精品在线| 久青草大香蕉| 丁香色六月| 99免费视频在线观看爱| 五月婷网| av在线婷婷| 熟女激情网| 91大屁股| Av大香蕉| 91九九九色在| 啪啪啪综合网| 欧美激情综合色丁香婷婷五月天 | 九色综合网| 九九99九九99| 亚洲精品国产精品乱码不99| 亚洲成人一区| 久草婷妨| 天天 青草 制服丝袜 在线| 亚洲六月色| 99热精品在线在线| 婷婷色在线播放| 蜜臀九九九九| 婷婷亚洲天堂| 色停停影院五月天| www.夜夜操.con| 亚洲综合五月天婷婷丁香| AA片在线观看视频在线播放 | 中文字幕av久久爽| WWW.激情| 久久草中文日韩欧美| 五月天丁香婷婷网| 丁香五月婷婷久久综合激情网 | 人妻在线中文字幕久久| 色久女| 激情网色五月| 六月丁香婷婷天堂| 五月婷婷性爱| avv在线| 日撸夜撸日操| 色五月激情综合网| 九九色综合网| 天天婷婷综合亚洲亚洲| 99原创自拍视频在线观看| 色色婷婷丁香| 男女免费视频999| 欧美日韩国产成人在线| 夜夜爽日日躁| 久青草影院| 久久久久亚洲AV无码网影音先锋| 成人综合伍月天| 91精品激情9| 99 色色吧| www夜夜操| 色综合色五月| 人人综合久| www.久久久久久久久久久| 欧美成人精品老美女噜噜噜| 国外亚洲成AV人片在线观看| 这里只有精品在线视频精品| 大香蕉久久久久| 久久色9| 色色色热热热| 玖色色综合| 亚洲欧美一区二区三区四区爱爱动图| 国产精产国品一二三在观看| 99re思思在线视频| 婷婷五月色| 99这里有精品久久97| 色婷婷香蕉| 思思热久久艹| 亚洲AV综合在线观看| 激情文学第四色婷婷丁香五月| 99这里只有精品视频| 97操在线资源| 国产密乳av一区二区三区四区| 五月丁香婷婷老司机| 深爱激情网五月天| 激情综合文学| 亚洲aV写真天天综合网久久| 婷婷五月丁香国产| 五月天久久综合婷婷丁香| 1024AV视频| 啄木鸟丝袜美女福利视频| 亚洲av成人一区二区电影在线| 九一99| 六月丁香激情| 中文AV在线播放| 丁香五月天啪啪|