TOP100summit:【分享實(shí)錄-貓眼電影】業(yè)務(wù)縱橫捭闔背后的技術(shù)拆分與融合

本篇文章內(nèi)容來(lái)自2016年TOP100summit貓眼電影商品業(yè)務(wù)線技術(shù)負(fù)責(zé)人姿搜,技術(shù)專家王洋的案例分享。

編輯:Cynthia

王洋貓眼電影商品業(yè)務(wù)線技術(shù)負(fù)責(zé)人候齿、技術(shù)專家迄靠。主導(dǎo)了貓眼商品供應(yīng)鏈和交易體系從0到1的建設(shè),并在貓眼與美團(tuán)拆分卓缰、與點(diǎn)評(píng)電影業(yè)務(wù)融合過(guò)程中计呈,從技術(shù)層面保障了商品業(yè)務(wù)的平穩(wěn)切換,同時(shí)也是美團(tuán)點(diǎn)評(píng)《領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)》課程的講師征唬。在加入貓眼電影之前捌显,曾就職于螞蟻金服,參與了阿里網(wǎng)商銀行從0到1的建設(shè)总寒,以及支付寶錢包扶歪、花唄等產(chǎn)品的研發(fā)。

導(dǎo)讀:互聯(lián)網(wǎng)電影行業(yè)在2016年經(jīng)歷了較大的變動(dòng)摄闸,其中包括貓眼電影和原美團(tuán)的拆分善镰,以及貓眼電影和點(diǎn)評(píng)電影業(yè)務(wù)的融合。業(yè)務(wù)發(fā)生大的變化時(shí)年枕,技術(shù)通常也會(huì)做出較大的重構(gòu)炫欺,貓眼后臺(tái)技術(shù)團(tuán)隊(duì)在整個(gè)拆分、融合的過(guò)程中熏兄,對(duì)系統(tǒng)架構(gòu)品洛、領(lǐng)域模型進(jìn)行了比較多的調(diào)整和思考,探索出一套成本和收益較為平衡的技術(shù)方案霍弹。本文將分享實(shí)踐的具體過(guò)程毫别、步驟和方法,希望給后互聯(lián)網(wǎng)時(shí)代典格,遭遇業(yè)務(wù)拆分和融合的技術(shù)團(tuán)隊(duì)提供一些參考案例岛宦。

一.問(wèn)題的提出

具有一定規(guī)模的互聯(lián)網(wǎng)公司,通常會(huì)有很多的細(xì)分領(lǐng)域和垂直業(yè)務(wù)耍缴,為了提高效率砾肺,大部分公司都會(huì)采用平臺(tái)化的思路:建設(shè)一套通用的基礎(chǔ)平臺(tái)挽霉,所有業(yè)務(wù)線基于這套基礎(chǔ)平臺(tái)搭建自己的業(yè)務(wù)和技術(shù)服務(wù)。這種做法一方面可以縮減人力成本变汪,另一方面也可以提高新業(yè)務(wù)的開(kāi)發(fā)效率侠坎。貓眼的商品業(yè)務(wù)一開(kāi)始為了快速發(fā)展,就采用了這種發(fā)展模式裙盾,將整個(gè)業(yè)務(wù)的交易都搭建在美團(tuán)的團(tuán)購(gòu)體系之上实胸,如圖1所示:



從上圖可以看出,商品業(yè)務(wù)完全依賴于美團(tuán)的商品番官、訂單庐完、支付、促銷徘熔、劵服務(wù)门躯,耦合性非常高。由于當(dāng)時(shí)美團(tuán)和貓眼是同一家公司酷师,這種耦合性是可以接受的讶凉。但后來(lái)貓眼獨(dú)立了,組織架構(gòu)山孔、業(yè)務(wù)規(guī)劃出現(xiàn)了較大的不同懂讯,這種耦合性就變成了商品業(yè)務(wù)后續(xù)發(fā)展的一大難題。

基于獨(dú)立發(fā)展的考慮饱须,貓眼需要將商品業(yè)務(wù)從團(tuán)購(gòu)體系拆分出來(lái)域醇,并和點(diǎn)評(píng)電影的商品業(yè)務(wù)融合在一起台谊,組建一套新的業(yè)務(wù)和技術(shù)體系蓉媳,用來(lái)支撐后續(xù)的業(yè)務(wù)發(fā)展。

經(jīng)過(guò)大量的現(xiàn)狀分析和調(diào)研之后锅铅,團(tuán)隊(duì)確定了此次技術(shù)升級(jí)的目標(biāo):

●產(chǎn)品需求不能中斷酪呻。

●最低的客戶感知度。

●新舊體系可以自由切換盐须。

●最低的試錯(cuò)成本玩荠。

●持續(xù)分階段交付、驗(yàn)證贼邓。

電商體系從供應(yīng)鏈到交易再到結(jié)算阶冈,復(fù)雜度已經(jīng)很高, 再加上業(yè)務(wù)切換塑径、數(shù)據(jù)整合的時(shí)間女坑,必然會(huì)是一場(chǎng)持久戰(zhàn)。為了減少風(fēng)險(xiǎn)统舀,讓商務(wù)匆骗、財(cái)務(wù)等團(tuán)隊(duì)更好地配合我們劳景,技術(shù)團(tuán)隊(duì)必須分階段產(chǎn)出,做線上驗(yàn)證碉就。

確定上述的5個(gè)目標(biāo)之后盟广,接下來(lái)我們就要思考如何圍繞這些目標(biāo)設(shè)計(jì)整體的方案。

二.技術(shù)拆分方案

首先瓮钥,我們來(lái)分析一下業(yè)務(wù)場(chǎng)景筋量,圖2是商品業(yè)務(wù)的簡(jiǎn)圖:



從圖2可以看出,整個(gè)業(yè)務(wù)可以被拆解為四個(gè)大的模塊碉熄,這樣我們就粗略地確定了團(tuán)隊(duì)的分工:供應(yīng)鏈毛甲、交易、消費(fèi)具被、消費(fèi)后服務(wù)玻募。確定好團(tuán)隊(duì)的組成,接下來(lái)我們需要對(duì)服務(wù)的重要性和優(yōu)先級(jí)做一個(gè)明確的劃分一姿。分析的維度如下:

●基礎(chǔ)數(shù)據(jù)層面七咧,如商家、用戶叮叹、合同艾栋,這些是公司長(zhǎng)期積累下的資源,短期內(nèi)不可能重建蛉顽,所以這個(gè)層面的服務(wù)蝗砾,盡量復(fù)用以前的服務(wù)。

●核心服務(wù)層面携冤,供應(yīng)鏈的核心是上單悼粮,交易的核心是商品、訂單曾棕、支付扣猫、促銷,消費(fèi)的核心是物流翘地、商品券和與之對(duì)應(yīng)的網(wǎng)關(guān)服務(wù)申尤,這些都是交易的主流程,必須重建衙耕。

●財(cái)務(wù)層面昧穿,如對(duì)接商家的結(jié)算,以及反應(yīng)業(yè)務(wù)運(yùn)轉(zhuǎn)情況的賬務(wù)橙喘,在公司拆分時(shí)时鸵,通常是需要獨(dú)立核算的,所以這個(gè)層面的服務(wù)也必須重建渴杆。

●非功能性服務(wù)寥枝,例如客服宪塔、售后,這些服務(wù)通常優(yōu)先級(jí)不高囊拜,但是沒(méi)有的話某筐,會(huì)影響用戶的體驗(yàn),所以盡量考慮復(fù)用以前的服務(wù)冠跷,后期再考慮重建南誊。

經(jīng)過(guò)上面的分析,我們確定了一期工程需要重建的服務(wù)蜜托。

2.1 拆分的前置方案

確定了需要重建的服務(wù)之后抄囚,還不能急于開(kāi)發(fā),要提前思考如果所有的服務(wù)都已經(jīng)有了橄务,該如何做切換幔托。需要考慮的事情有這么幾點(diǎn):

切換期間,商品如何售賣蜂挪。

在前面我們確立了“新舊體系可自由切換”的目標(biāo)重挑,所以在切換過(guò)程中,需要保證商家和運(yùn)營(yíng)上一次單棠涮,就可以在美團(tuán)谬哀、點(diǎn)評(píng)、貓眼三個(gè)體系中售賣严肪,這樣可以提高切換的靈活性史煎,減少切換帶來(lái)的交易損失。

版本問(wèn)題驳糯。

前文已經(jīng)提到篇梭,商品業(yè)務(wù)一開(kāi)始是在團(tuán)購(gòu)之上搭建起來(lái)的,客戶端調(diào)用的大部分接口都是美團(tuán)團(tuán)購(gòu)的接口结窘。最直觀的做法是在團(tuán)購(gòu)接口中加上判斷很洋,將電影品類的交易請(qǐng)求導(dǎo)流到貓眼這邊充蓝,這種做法速度快隧枫,且沒(méi)有流量損失,但以后修改接口參數(shù)谓苟、擴(kuò)展業(yè)務(wù)的負(fù)擔(dān)比較重官脓,可維護(hù)性比較差。

切換的方式和粒度涝焙。

為了達(dá)成“新舊體系可自由切換”和“最低試錯(cuò)成本”的目標(biāo)卑笨,在切換過(guò)程中,必然會(huì)處于一個(gè)新老并存的狀態(tài)仑撞,所以我們不能簡(jiǎn)單地替換接口赤兴,而要采用更靈活的切換方式和更細(xì)的切換粒度妖滔。

與貓眼現(xiàn)有業(yè)務(wù)的關(guān)系。

貓眼本身有一套選座交易桶良,但受制于行業(yè)模型座舍,暫時(shí)無(wú)法支撐商品交易≡煞考慮到未來(lái)肯定是需要融合的曲秉,所以需要提前考慮兩套交易的關(guān)系。

2.1.1 上單雙推

針對(duì)售賣問(wèn)題疲牵,貓眼采用了“上單雙推”的做法承二,如圖3:



正常情況下,上單系統(tǒng)在確認(rèn)商家提交的商品信息后纲爸,會(huì)將商品推送到商品中心亥鸠。為了讓商品在美團(tuán)、點(diǎn)評(píng)识啦、貓眼三個(gè)體系中售賣读虏,貓眼需要做以下幾步操作:

歷史單遷移。

先從美團(tuán)商品中心將當(dāng)下可以售賣的商品同步到貓眼袁滥,保持對(duì)齊盖桥。

建立關(guān)系映射。

對(duì)于商家來(lái)說(shuō)题翻,無(wú)論商品在幾個(gè)體系中售賣揩徊,都是一個(gè)商品,在統(tǒng)計(jì)銷量嵌赠、結(jié)算時(shí)塑荒,都應(yīng)該是一個(gè)商品,所以我們需要將多個(gè)商品中心的商品關(guān)聯(lián)起來(lái)。這個(gè)做起來(lái)比較簡(jiǎn)單勤揩,只要給貓眼的商品分配一個(gè)id寓落,然后在商品數(shù)據(jù)中存下對(duì)方的id就可以了。

另外凌箕,為了區(qū)分兩個(gè)體系的商品,我們采用分段的策略來(lái)分配商品id词渤,比如當(dāng)下的美團(tuán)商品最大id是X牵舱,那么貓眼的商品就采用2*X作為id的起始,而在美團(tuán)商品id增長(zhǎng)到2*X之前缺虐,我們肯定完成了切換芜壁,不用再考慮id序列統(tǒng)一的問(wèn)題了。

商品雙推,庫(kù)存按比例分配慧妄。

貓眼上單系統(tǒng)確認(rèn)商品信息后顷牌,將商品推送到美團(tuán)、貓眼兩個(gè)商品中心塞淹,并創(chuàng)建各自的庫(kù)存韧掩,根據(jù)當(dāng)下的交易比例分配庫(kù)存量。由于美團(tuán)窖铡、點(diǎn)評(píng)兩個(gè)體系是經(jīng)過(guò)融合的疗锐,所以只需要推送美團(tuán)團(tuán)購(gòu),點(diǎn)評(píng)就可以售賣了费彼。

2.1.2 業(yè)務(wù)入口回收

解決了售賣問(wèn)題之后滑臊,接下來(lái)我們來(lái)考慮版本和切換方式的問(wèn)題。

眾所周知箍铲,移動(dòng)App一旦發(fā)版就很難再改動(dòng)代碼了雇卷,所以切換完成后,老的版本很難支持現(xiàn)有的體系颠猴。但經(jīng)過(guò)分析我們發(fā)現(xiàn)关划,貓眼涉及的幾個(gè)App,2~3個(gè)版本可以覆蓋到90%以上的客戶端翘瓮,而核心 服務(wù)自建足夠支撐3個(gè)版本以上的迭代贮折,這樣全部切換完成的時(shí)候,可以把老版本的流量損失降到5%以內(nèi)(老版本的用戶交易意愿有一定折損)资盅,這是一個(gè)可以接受的范圍调榄。

為了加快切換的速度,我們需要在核心服務(wù)自建之前呵扛,先把交易和消費(fèi)環(huán)節(jié)所有的業(yè)務(wù)入口每庆,也就是客戶端調(diào)用的接口全部替換成貓眼自己的接口,由貓眼來(lái)對(duì)接美團(tuán)的服務(wù)今穿,如圖4所示:



在美團(tuán)的服務(wù)之上缤灵,先建立一個(gè)業(yè)務(wù)流程層,給客戶端提供交易和消費(fèi)環(huán)節(jié)所需要的接口蓝晒,然后由業(yè)務(wù)流程層轉(zhuǎn)接美團(tuán)團(tuán)購(gòu)的基礎(chǔ)服務(wù)腮出。例如下單操作,原先是直接調(diào)用美團(tuán)訂單的接口拔创,現(xiàn)在由交易業(yè)務(wù)系統(tǒng)做轉(zhuǎn)接利诺,一旦貓眼的訂單系統(tǒng)開(kāi)發(fā)完成,只需要將美團(tuán)訂單服務(wù)替換成貓眼訂單服務(wù)就可以實(shí)現(xiàn)無(wú)縫對(duì)接了剩燥。

2.1.3 切換方法和粒度

收回業(yè)務(wù)入口以后,接下來(lái)需要考慮切換的粒度。

目前有這么幾個(gè)粒度:商品灭红、 影院侣滩、App、入口位置(場(chǎng)次頁(yè)变擒、支付頁(yè)君珠、取票機(jī)、搜索娇斑、推薦)策添。綜合起來(lái)看,影院+入口位置是比較合理的粒度毫缆。

商品粒度太細(xì)唯竹,且數(shù)據(jù)是動(dòng)態(tài)變化的,維護(hù)起來(lái)比較麻煩苦丁;App維度又太粗浸颓,一次性切換起來(lái)涉及的范圍太大,且無(wú)法回滾旺拉;影院的粒度處于中間产上,數(shù)據(jù)變化小,流量也比較好控制蛾狗,所以我們采用了影院作為主要的切換粒度晋涣。

另外,由于商品業(yè)務(wù)本身的特點(diǎn)比較碎片化沉桌,入口眾多姻僧,還得對(duì)接美團(tuán)、點(diǎn)評(píng)的搜索蒲牧、推薦等服務(wù)撇贺,所以將入口位置作為輔助的切換粒度。

切換之前冰抢,先給所有的展示入口分配固定的渠道號(hào)松嘶,如圖5所示。支付頁(yè)是渠道1挎扰,取票機(jī)是渠道3翠订,客戶端在請(qǐng)求后臺(tái)數(shù)據(jù)時(shí),需要帶上渠道號(hào)遵倦;然后商品業(yè)務(wù)系統(tǒng)將查詢邏輯抽象成處理器尽超,例如貓眼支付頁(yè)處理器對(duì)接貓眼的商品中心,而美團(tuán)的支付頁(yè)處理器對(duì)接美團(tuán)的商品中心梧躺,公共流程如排序似谁、最低價(jià)計(jì)算傲绣,可以抽象到父類中。



當(dāng)一個(gè)查詢請(qǐng)求到達(dá)商品業(yè)務(wù)系統(tǒng)后巩踏,由渠道分發(fā)控制器根據(jù)渠道號(hào)選擇對(duì)應(yīng)的處理器秃诵,同時(shí),渠道分發(fā)控制器需要詢問(wèn)渠道切換服務(wù)的建議塞琼,看看是走團(tuán)購(gòu)體系還是走貓眼體系菠净。而我們只需要在渠道切換服務(wù)內(nèi)部維護(hù)一個(gè)走貓眼體系的影院+渠道列表,然后用配置推送服務(wù)動(dòng)態(tài)更新彪杉,就可以實(shí)現(xiàn)影院+入口位置兩個(gè)維度的自由切換了毅往。

通過(guò)以上的辦法,后臺(tái)系統(tǒng)已經(jīng)在商品展示層面實(shí)現(xiàn)了兩個(gè)體系的自由切換派近,但后續(xù)的交易流程還有很長(zhǎng)攀唯,需要客戶端能夠分辨后續(xù)該使用哪些接口,才可以走到正確的交易流程构哺。圖6是客戶端需要配合做的改動(dòng):



客戶端需要維護(hù)兩套交易接口的列表革答,一套走美團(tuán),一套走貓眼曙强。后臺(tái)接口在返回商品數(shù)據(jù)時(shí)残拐,會(huì)帶上商品是否貓眼的標(biāo)記,如果為true碟嘴,則后續(xù)流程都使用貓眼的交易接口溪食;如果為false,則都使用美團(tuán)的交易接口娜扇。等到切換完成错沃,后臺(tái)返回的標(biāo)記全部變成true,客戶端也可以考慮刪除這段邏輯雀瓢,直接使用貓眼的接口列表枢析。

2.1.4 統(tǒng)一id服務(wù)

最后,考慮商品交易和已有業(yè)務(wù)的關(guān)系刃麸。

交易的核心是訂單醒叁,而貓眼內(nèi)部已經(jīng)存在一套選座訂單了,但這兩者的模型差異很大泊业,無(wú)法復(fù)用把沼,所以只能選擇自建訂單,在訂單號(hào)層面做好統(tǒng)一吁伺,降低未來(lái)數(shù)據(jù)融合的復(fù)雜度饮睬。

統(tǒng)一訂單id,就需要一個(gè)統(tǒng)計(jì)id服務(wù)篮奄,如圖7所示捆愁。每個(gè)交易業(yè)務(wù)在下單前割去,都從統(tǒng)一id服務(wù)獲取訂單號(hào),然后再下單牙瓢,這樣可以保證整個(gè)公司的訂單號(hào)分布在同一個(gè)遞增序列下劫拗,降低促銷间校、結(jié)算等系統(tǒng)融合的復(fù)雜度矾克。

2.2 核心服務(wù)自建



完成了前置方案的設(shè)計(jì),接下來(lái)要分析交易需要哪些核心服務(wù)憔足,下面是商品業(yè)務(wù)的行為分析圖:



從上圖中可以看出胁附,整個(gè)交易過(guò)程可以簡(jiǎn)單的劃分為三個(gè)階段:交易前(商品為核心)、交易中(訂單為核心)滓彰、交易后(即消費(fèi)過(guò)程控妻,商品券為核心)。下面詳細(xì)分析每個(gè)階段的核心模型該如何設(shè)計(jì)揭绑。

2.2.1 商品輸出模型

根據(jù)商品的作用弓候,我們可以將商品信息的存在形式分成三個(gè)階段:編輯階段、使用階段他匪、業(yè)務(wù)聚合階段菇存。以下是這三個(gè)階段的說(shuō)明:

編輯階段,即還未成形的商品邦蜜。

這個(gè)階段以上單流程為核心依鸥,維護(hù)商品的寫模型,所以需要重點(diǎn)關(guān)注商品的增刪改操作悼沈,并做好審核機(jī)制和操作記錄贱迟。這個(gè)階段的模型主要維護(hù)在上單系統(tǒng)里邊。

使用階段絮供,即通過(guò)審核衣吠,允許售賣的商品。

這個(gè)階段維護(hù)的是商品的基礎(chǔ)信息壤靶,一部分信息是只讀的缚俏,例如商品標(biāo)題、價(jià)格萍肆、所屬的門店等袍榆;另外一部分是可變的,例如庫(kù)存量塘揣、銷量包雀、商品狀態(tài)等。使用階段的模型主要維護(hù)在商品中心里邊亲铡。

業(yè)務(wù)聚合階段才写,即整合其它信息以后的商品葡兑。

這個(gè)階段維護(hù)的是商品的讀模型,不能改變商品的任何信息赞草,例如商品列表是聚合了多個(gè)商品信息讹堤,商品詳情則是聚合了商品基礎(chǔ)信息和促銷信息。當(dāng)外部系統(tǒng)厨疙,例如搜索等服務(wù)需要接入商品體系的時(shí)候洲守,都應(yīng)該輸出業(yè)務(wù)聚合階段的商品。這個(gè)階段的模型主要維護(hù)在商品業(yè)務(wù)里邊沾凄。

定義好商品的三個(gè)階段以后梗醇,就可以根據(jù)每個(gè)系統(tǒng)使用商品的方式來(lái)組織系統(tǒng)的關(guān)系,得到圖9所展示的輸出模型撒蟀。



2.2.2 訂單處理模型

訂單是交易過(guò)程中最重要的模型之一叙谨,也是最容易和業(yè)務(wù)耦合過(guò)重的模塊。所以在設(shè)計(jì)訂單模型的時(shí)候保屯,需要重點(diǎn)考慮如何讓訂單和業(yè)務(wù)流程分離手负,只關(guān)注訂單的基本信息和狀態(tài)流轉(zhuǎn)」贸撸考慮點(diǎn)主要有以下幾點(diǎn):

命令模型和查詢操作需要分開(kāi)竟终,即CQRS。

例如下單和查詢訂單詳情兩個(gè)操作股缸,前者是交易的主流程衡楞,會(huì)寫入訂單的信息,而后者不會(huì)改變訂單的任何信息敦姻,只需要查詢到訂單即可瘾境。另外,下單重視的是業(yè)務(wù)流程镰惦,核心指標(biāo)是穩(wěn)定性和準(zhǔn)確性迷守,而查詢訂單詳情重視的是數(shù)據(jù)聚合,核心指標(biāo)是完整性和用戶體驗(yàn)旺入。

業(yè)務(wù)流程和訂單處理過(guò)程需要分離兑凿。

例如下單操作可能會(huì)分為好幾個(gè)步驟:判斷商品是否可售、計(jì)算商品的價(jià)格茵瘾、鎖庫(kù)存礼华、寫訂單數(shù)據(jù)等。這些步驟是業(yè)務(wù)流程拗秘,訂單不應(yīng)該關(guān)心圣絮。而且每個(gè)業(yè)務(wù)的交易流程可能會(huì)不一樣,所以需要一個(gè)靈活性更高的辦法來(lái)處理交易流程雕旨。

考慮以上兩個(gè)問(wèn)題后扮匠,我們?cè)O(shè)計(jì)出了訂單處理模型捧请,如圖10所示。

首先得開(kāi)發(fā)一個(gè)任務(wù)處理引擎棒搜,負(fù)責(zé)處理業(yè)務(wù)流程中的單個(gè)任務(wù)疹蛉,例如鎖庫(kù)存、生成商品券力麸、推送訂單信息等等可款。每一個(gè)任務(wù)都對(duì)應(yīng)一條數(shù)據(jù)庫(kù)記錄,用來(lái)說(shuō)明要使用哪個(gè)處理器末盔、用到的數(shù)據(jù)該從哪里獲取筑舅,以及步驟完成之后該怎么辦座慰,記錄之間也會(huì)使用編號(hào)連接起來(lái)陨舱,用來(lái)處理優(yōu)先級(jí)和依賴關(guān)系。

接單服務(wù)負(fù)責(zé)將不同業(yè)務(wù)的下單流程拆解成一個(gè)個(gè)子任務(wù)版仔,并確定好任務(wù)之間的優(yōu)先級(jí)和依賴關(guān)系游盲,進(jìn)行簡(jiǎn)單的編排,然后寫入到任務(wù)引擎的數(shù)據(jù)庫(kù)中蛮粮,而任務(wù)引擎則負(fù)責(zé)撈取這些任務(wù)益缎,分析并執(zhí)行已經(jīng)編排過(guò)的任務(wù)。這種方式的好處在于業(yè)務(wù)流程被拆得很細(xì)然想,不同業(yè)務(wù)之間可以重用一些任務(wù)處理步驟莺奔,當(dāng)一個(gè)新的交易業(yè)務(wù)接入的時(shí)候,只需要添加對(duì)應(yīng)的子任務(wù)處理器变泄,然后在接單系統(tǒng)中配置編排的規(guī)則令哟,即可快速支持。

如圖10所示妨蛹,我們將訂單的寫模型和查模型分開(kāi)屏富,讓增刪改三個(gè)操作都走訂單核心系統(tǒng)的寫模型,而用戶查詢操作則走訂單查詢系統(tǒng)的查模型蛙卤。每次訂單信息有變化的時(shí)候狠半,訂單核心會(huì)通知任務(wù)引擎,由任務(wù)引擎負(fù)責(zé)更新查模型颤难。這期間會(huì)有時(shí)間上的延遲神年,所以訂單查詢維護(hù)的查模型只能給用戶端展示需求使用,而退款過(guò)程中查詢訂單狀態(tài)則必須走訂單核心的寫模型行嗤,因?yàn)閷懩P偷臓顟B(tài)是實(shí)時(shí)的已日。



用戶成功支付訂單以后,訂單核心會(huì)收到支付成功消息昂验,然后將不同類型的訂單拆分捂敌,并挨個(gè)通知任務(wù)引擎艾扮,執(zhí)行支付成功后的業(yè)務(wù)流程,例如生成商品券占婉、推送訂單信息到美團(tuán)訂單列表等泡嘴。

2.2.3 商品券與結(jié)算模型

商品券和物流是消費(fèi)過(guò)程中的核心模型,而結(jié)算剛好要的就是消費(fèi)維度的數(shù)據(jù)逆济,所以這兩者的設(shè)計(jì)緊密相關(guān)酌予。由于商品券和物流比較類似,所以本文只介紹商品券的模型奖慌。

商品券的本質(zhì)是一串?dāng)?shù)字抛虫,用來(lái)作為兌換服務(wù)的憑證。它的特點(diǎn):

一是要足夠亂简僧,不能讓你隨便輸入一個(gè)數(shù)字就可以使用建椰;

二是不能重復(fù),否則無(wú)法分清對(duì)應(yīng)的是哪個(gè)服務(wù)岛马。

在數(shù)據(jù)操作上棉姐,商品券需要支持生成、驗(yàn)證啦逆、撤銷等操作伞矩。

經(jīng)過(guò)以上分析,我們?cè)O(shè)計(jì)出了商品券和結(jié)算的模型夏志,如圖11:



為了足夠亂乃坤,系統(tǒng)需要一個(gè)隨機(jī)數(shù)生成的模塊,同時(shí)為了不重復(fù)沟蔑,需要為隨機(jī)數(shù)建立一個(gè)防沖突表湿诊,每次生成完隨機(jī)數(shù),都需要到防沖突表里查一下是否有使用過(guò)溉贿。由于隨機(jī)數(shù)是有限的枫吧,生成的碼越多,沖突的概率就越高宇色,對(duì)并發(fā)度會(huì)有一定的影響九杂。為了優(yōu)化這個(gè)問(wèn)題,我們采用了異步生成的方式:先預(yù)生成一定數(shù)量的劵碼宣蠕,并添加到一個(gè)可用劵碼的隊(duì)列中例隆,在不同的并發(fā)數(shù)下,只要調(diào)整隊(duì)列的容量和預(yù)生成速度就可以支持了抢蚀。

當(dāng)用戶通過(guò)pos機(jī)等設(shè)備驗(yàn)證券碼的時(shí)候镀层,商品券會(huì)發(fā)消息給結(jié)算系統(tǒng),結(jié)算系統(tǒng)會(huì)寫一條流水?dāng)?shù)據(jù)到數(shù)據(jù)庫(kù)中,并按照結(jié)算周期聚合到一起形成付款計(jì)劃唱逢。結(jié)算系統(tǒng)也會(huì)每天掃描合同中約定的結(jié)算周期吴侦,觸發(fā)打款操作。

2.3 線上線下切換

在前文介紹的前置方案里坞古,我們已經(jīng)提前將切換點(diǎn)埋入到了客戶端中备韧,當(dāng)交易模型搭建起來(lái)時(shí),線上實(shí)際已經(jīng)有大量的客戶端支持在兩個(gè)體系切換了痪枫。但此時(shí)织堂,我們還不能著急將所有的商家都切換到新體系,需要考慮更多的問(wèn)題:

舊體系已有的業(yè)務(wù)奶陈,在新體系是否都已經(jīng)支持易阳。例如促銷、優(yōu)惠券吃粒,必須在業(yè)務(wù)對(duì)齊的情況下才能切換潦俺,否則會(huì)干擾到商家的正常運(yùn)營(yíng)活動(dòng)。

商家結(jié)算的模式是否支持切換声搁。在拆分過(guò)程中黑竞,結(jié)算、財(cái)務(wù)方面的數(shù)據(jù)是唯一不能遷移的數(shù)據(jù)疏旨,任何的變化都需要兩個(gè)公司財(cái)務(wù)之間核算清楚才能執(zhí)行。所以在切換之前扎酷,需要根據(jù)結(jié)算的模式檐涝,將商家做好分類,優(yōu)先將結(jié)算方式簡(jiǎn)單的商家切換到新體系法挨,用于驗(yàn)證線上服務(wù)的正確性和切換方案的合理性谁榜。

交易過(guò)程中是否依賴第三方系統(tǒng)。例如貓眼在交易后的過(guò)程中凡纳,依賴了影院的第三方券系統(tǒng)窃植,導(dǎo)致了這部分影院必須在對(duì)接完依賴的第三系統(tǒng)之后,才可以切換荐糜。

分析完上述三個(gè)因素巷怜,確定好可以切換的商家列表之后,就可以開(kāi)始和商務(wù)一起推進(jìn)線上線下的切換了暴氏。切換的過(guò)程中延塑,需要注意線下的切換通常比線上要緩慢,所以要預(yù)先啟動(dòng)線下的切換答渔,并讓商務(wù)團(tuán)隊(duì)給商家做好培訓(xùn)关带。

三.技術(shù)融合方案

經(jīng)過(guò)技術(shù)拆分,貓眼實(shí)際擁有了一套完整的商品供應(yīng)鏈和交易體系沼撕,而此時(shí)點(diǎn)評(píng)的商品業(yè)務(wù)也有一套自己的供應(yīng)鏈和交易宋雏。為了降低今后的維護(hù)成本芜飘,我們必須將點(diǎn)評(píng)的商品業(yè)務(wù)適配到貓眼的這套供應(yīng)鏈和交易體系之上。

供應(yīng)鏈層面的解決方案和拆分的方案類似磨总,這里不再詳述燃箭,重點(diǎn)說(shuō)說(shuō)交易層面的適配和融合辦法。設(shè)計(jì)融合技術(shù)方案的時(shí)候舍败,需要重點(diǎn)考慮這么幾個(gè)問(wèn)題:

客戶端調(diào)用接口的遷移問(wèn)題招狸。點(diǎn)評(píng)客戶端之前對(duì)接的都是點(diǎn)評(píng)的業(yè)務(wù)服務(wù),需要替換成貓眼的業(yè)務(wù)服務(wù)邻薯。

交易流程銜接以及頁(yè)面跳轉(zhuǎn)的問(wèn)題裙戏。融合之后,核心的如訂單厕诡、支付累榜、券消費(fèi)肯定得走貓眼的交易體系,所以整個(gè)交易的頁(yè)面和跳轉(zhuǎn)都應(yīng)該使用貓眼的頁(yè)面灵嫌。

已經(jīng)有的數(shù)據(jù)整合問(wèn)題壹罚。在融合之前,點(diǎn)評(píng)已經(jīng)積累了大量的商品訂單和券數(shù)據(jù)寿羞,這部分?jǐn)?shù)據(jù)需要和貓眼的數(shù)據(jù)進(jìn)行整合猖凛,才能滿足用戶和商家的查詢需求。

3.1 業(yè)務(wù)入口適配

針對(duì)客戶端調(diào)用接口的問(wèn)題绪穆,解決思路和拆分的方案差不多辨泳,也是提前建立業(yè)務(wù)層,將客戶端使用的接口都回收到業(yè)務(wù)系統(tǒng)玖院,然后再適配到貓眼的業(yè)務(wù)服務(wù)菠红,如圖12所示。

為了盡量不維護(hù)兩套業(yè)務(wù)系統(tǒng)难菌,貓眼在融合一期工程的時(shí)候先采用了簡(jiǎn)單的適配试溯,目的是將業(yè)務(wù)入口先牽引到貓眼的交易體系,然后在后續(xù)的開(kāi)發(fā)中再讓點(diǎn)評(píng)客戶端直接對(duì)接貓眼的業(yè)務(wù)系統(tǒng)郊酒,逐步取代點(diǎn)評(píng)的適配層遇绞,等到需要適配的版本越來(lái)越少的時(shí)候,就可以廢棄掉這個(gè)適配層了猎塞。

3.2 交易過(guò)程使用觸屏版



交易流程的銜接和跳轉(zhuǎn)是個(gè)比較棘手的問(wèn)題试读,一是貓眼以前沒(méi)有在點(diǎn)評(píng)客戶端做過(guò)開(kāi)發(fā),為了融合單做一套native交易頁(yè)面的代價(jià)較高荠耽;二是今后在做功能迭代的時(shí)候钩骇,要適配的端太多,會(huì)拖慢產(chǎn)品迭代的速度。綜合考慮了流量倘屹、體驗(yàn)和團(tuán)隊(duì)多方面的因素之后银亲,貓眼決定使用觸屏版來(lái)解決這個(gè)問(wèn)題。

商品交易有一個(gè)特點(diǎn)纽匙,即大部分的下單操作都會(huì)先經(jīng)過(guò)商品詳情頁(yè)务蝠,所以只要從商品詳情頁(yè)開(kāi)始,做一套觸屏版頁(yè)面烛缔,就可以將交易流程都引導(dǎo)到貓眼的頁(yè)面了馏段。

然而商品的展示通常比較碎片化,可能會(huì)有搜索践瓷、推薦院喜、商品列表、猜你喜歡等各種入口晕翠,所以進(jìn)入交易的第一步就是盡可能的讓展示入口都跳轉(zhuǎn)到觸屏版的商品詳情頁(yè)喷舀,然后繼續(xù)下單、支付淋肾,再跳轉(zhuǎn)到觸屏版的結(jié)果頁(yè)硫麻。訂單成功之后,貓眼再將自己的訂單數(shù)據(jù) 推送到點(diǎn)評(píng)的訂單中心樊卓,同時(shí)將訂單詳情頁(yè)的跳轉(zhuǎn)設(shè)置成觸屏版拿愧。一旦用戶點(diǎn)擊訂單列表,就又回到了貓眼可控的范圍內(nèi)简识,后續(xù)的退款赶掖、消費(fèi)、客服就走回到貓眼的交易體系七扰,具體的做法如圖13所示。



整個(gè)過(guò)程中陪白,可能會(huì)遇到一些其它的問(wèn)題颈走,例如跳轉(zhuǎn)登錄:點(diǎn)評(píng)客戶端登陸的是點(diǎn)評(píng)賬號(hào),而貓眼的觸屏版登陸的是貓眼賬號(hào)咱士,所以這個(gè)做法還依賴于賬號(hào)的融合立由。在跳轉(zhuǎn)收銀臺(tái)的時(shí)候也需要小心謹(jǐn)慎,需要點(diǎn)評(píng)收銀臺(tái)和貓眼收銀臺(tái)采用同樣的驗(yàn)證方式和解析規(guī)則序厉,否則極容易出現(xiàn)金額錯(cuò)誤锐膜,或者無(wú)法支付的情況。這些也是觸屏版需要考慮的問(wèn)題弛房。

使用觸屏版的前提是:交易流程必須經(jīng)過(guò)商品詳情頁(yè)道盏,假如交易流程不經(jīng)過(guò)商品詳情頁(yè)的話,就必須對(duì)多個(gè)業(yè)務(wù)入口進(jìn)行適配,但跳轉(zhuǎn)到收銀臺(tái)之后的流程荷逞,仍然是可以復(fù)用的媒咳。

3.3 數(shù)據(jù)整合思路

數(shù)據(jù)整合是技術(shù)融合中最繁瑣的部分,做法通常有三種:

數(shù)據(jù)層面不做整合种远,在代碼層面區(qū)分該走哪個(gè)數(shù)據(jù)源涩澡。這個(gè)方法的優(yōu)勢(shì)在于數(shù)據(jù)可不做改動(dòng),但需要維護(hù)兩套數(shù)據(jù)源坠敷,成本較高妙同。

數(shù)據(jù)層面建立映射關(guān)系,然后通過(guò)轉(zhuǎn)換層將數(shù)據(jù)轉(zhuǎn)換成業(yè)務(wù)方需要的模型膝迎。這個(gè)方法的改動(dòng)成本比較可控粥帚,可以快速實(shí)現(xiàn)兩個(gè)體系的互通。

數(shù)據(jù)層面做徹底的整合弄抬,將兩方的數(shù)據(jù)遷移到一個(gè)數(shù)據(jù)源中茎辐。這個(gè)方法的優(yōu)勢(shì)是只保留一套數(shù)據(jù)模型,后期可維護(hù)性高掂恕,但整合的難度大拖陆,需要重點(diǎn)處理差異數(shù)據(jù)。

貓眼和點(diǎn)評(píng)數(shù)據(jù)的整合過(guò)程中懊亡,主要以后兩種方法為主依啰,如圖14所示:



查詢數(shù)據(jù)通常使用的都是id,而我們可以簡(jiǎn)單的將數(shù)據(jù)id分為兩類:一類是不能變化的店枣,例如影院id速警;一類是可以變化的,例如訂單id鸯两。

對(duì)于影院id闷旧,貓眼和點(diǎn)評(píng)都有自己的一套序列,而且這兩套id都依附在各自的商家體系上钧唐,不能輕易統(tǒng)一起來(lái)忙灼,所以只能通過(guò)建立映射關(guān)系的方式來(lái)實(shí)現(xiàn)互通。圖14中左半部分的示例就是解決數(shù)據(jù)id不能改變的場(chǎng)景:

先將點(diǎn)評(píng)的影院id和貓眼的影院id建立映射關(guān)系钝侠,例如貓眼的影院id=1和點(diǎn)評(píng)的影院id=2该园,可能指向同一家影院(只是舉例使用,不保 證一定是對(duì)應(yīng)關(guān)系)帅韧。而貓眼app和點(diǎn)評(píng)app依然使用之前的id里初,只是在查詢數(shù)據(jù)的時(shí)候, 會(huì)先經(jīng)過(guò)數(shù)據(jù)轉(zhuǎn)換層忽舟,由數(shù)據(jù)轉(zhuǎn)換分析映射關(guān)系双妨,拿到統(tǒng)一之后的影院信息淮阐。

對(duì)于訂單id,用戶通常不會(huì)手動(dòng)記錄訂單id是多少斥难,完全依靠后臺(tái)返回枝嘶,這時(shí)候就可以將點(diǎn)評(píng)的訂單數(shù)據(jù)按照貓眼的格式,遷移到貓眼的數(shù)據(jù)庫(kù)中哑诊,并將id轉(zhuǎn)換成貓眼序列的id群扶,字段如果不同的話,可以使用擴(kuò)展字段或者差異表做一層兼容镀裤。

圖14的右半部分描述 的就是這種做法:用戶在查詢訂單列表的時(shí)候竞阐,返回的是貓眼的訂單id,那么進(jìn)入到詳情的時(shí)候自然就會(huì)查詢貓眼的訂單數(shù)據(jù)暑劝,這樣就實(shí)現(xiàn)了數(shù)據(jù)整合骆莹。

需要注意的是:修改訂單id的時(shí)候,通常需要修改所有和訂單相關(guān)的數(shù)據(jù)担猛,例如促銷幕垦、商品券等系統(tǒng),都是以訂單id為區(qū)分依據(jù)的傅联,這就需要同時(shí)改動(dòng)所有受牽連的數(shù)據(jù)先改,需要小心謹(jǐn)慎地去推進(jìn)。

四蒸走、案例啟示和教訓(xùn)

技術(shù)拆分和融合的過(guò)程在貓眼內(nèi)部持續(xù)將近半年時(shí)間仇奶,期間遇到了不少困難,對(duì)系統(tǒng)架構(gòu)和模型也進(jìn)行了較多的思考比驻,以下是從案例中獲得的啟示:

在大公司做垂直業(yè)務(wù)時(shí)该溯,如果要復(fù)用平臺(tái)的服務(wù),最好在客戶端和平臺(tái)服務(wù)之間建立業(yè)務(wù)層别惦,做一層服務(wù)轉(zhuǎn)接狈茉,這樣可以為服務(wù)的替換提供更好的靈活性。

在設(shè)計(jì)系統(tǒng)模型時(shí)掸掸,盡量讓業(yè)務(wù)入口渠道化论皆、處理過(guò)程組件化,這樣不僅可以提高系統(tǒng)的橫向擴(kuò)展性猾漫,而且也可以對(duì)每個(gè)入口做更精細(xì)的把控

不同業(yè)務(wù)在快速發(fā)展時(shí),可以有自己的核心服務(wù)感凤,但必須使用統(tǒng)一的id生成策略悯周,保證模型的主要id屬于同一個(gè)遞增序列,這樣可以為以后的融合陪竿,或者平臺(tái)化減少數(shù)據(jù)整合的復(fù)雜度禽翼。

數(shù)據(jù)模型層面屠橄,盡量將命令模型和查詢模型分開(kāi),一方面可以將主流程和數(shù)據(jù)展示操作徹底分開(kāi)闰挡;一方面也可以降低數(shù)據(jù)操作的復(fù)雜性锐墙。

系統(tǒng)的流量控制和切換粒度要足夠精細(xì),這樣可以提高應(yīng)對(duì)風(fēng)險(xiǎn)的能力长酗。

也從本案例中積累了一些教訓(xùn):

設(shè)計(jì)技術(shù)拆分和融合方案時(shí)溪北,需要全面考慮非技術(shù)因素的影響,比如結(jié)算夺脾、財(cái)務(wù)之拨,數(shù)據(jù)既不能遷移,也不能修改咧叭,此時(shí)財(cái)務(wù)的結(jié)論很有可能會(huì)影響整體的切換方案和模式設(shè)計(jì)蚀乔。

線下的切換要提前進(jìn)行,以便盡早收集到業(yè)務(wù)一線的反饋菲茬,可以并行的去修復(fù)問(wèn)題吉挣,這樣才能保證在線上開(kāi)始切換的時(shí)候,不被拖慢進(jìn)度婉弹。

五睬魂、總結(jié)和感謝

技術(shù)拆分和融合是一個(gè)龐大的工程,涉及的技術(shù)點(diǎn)比較多马胧,由于篇幅有限汉买,本文只是介紹了整體的設(shè)計(jì)方案,希望給行業(yè)中遭遇相同問(wèn)題的工程師們提供一個(gè)參考案例佩脊。

最后蛙粘,在此感謝所有參與本次技術(shù)拆分和融合的技術(shù)、產(chǎn)品威彰、運(yùn)營(yíng)和商務(wù)出牧、財(cái)務(wù)團(tuán)隊(duì)所有的小伙伴,以及美團(tuán)點(diǎn)評(píng)熱?心幫助的同事們歇盼。有了大家的緊密協(xié)作舔痕,才能在有限的時(shí)間里,完成如此復(fù)雜的技術(shù)升級(jí)豹缀,感謝伯复。

11月9-12日,北京國(guó)家會(huì)議中心邢笙,第六屆TOP100全球軟件案例研究峰會(huì)啸如,美團(tuán)外賣算法架構(gòu)師郝井華將分享《美團(tuán)配送智能調(diào)度系統(tǒng)演進(jìn)》;美團(tuán)點(diǎn)評(píng)酒旅質(zhì)量團(tuán)隊(duì)工具鏈負(fù)責(zé)人王鵬將分享《微服務(wù)架構(gòu)下的自動(dòng)化測(cè)試和持續(xù)集成工具鏈實(shí)踐》氮惯。

大會(huì)開(kāi)幕式單天體驗(yàn)票免費(fèi)入口叮雳。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末想暗,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子帘不,更是在濱河造成了極大的恐慌说莫,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寞焙,死亡現(xiàn)場(chǎng)離奇詭異储狭,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)棺弊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門晶密,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人模她,你說(shuō)我怎么就攤上這事稻艰。” “怎么了侈净?”我有些...
    開(kāi)封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵尊勿,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我畜侦,道長(zhǎng)元扔,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任旋膳,我火速辦了婚禮澎语,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘验懊。我一直安慰自己擅羞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布义图。 她就那樣靜靜地躺著减俏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪碱工。 梳的紋絲不亂的頭發(fā)上娃承,一...
    開(kāi)封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音怕篷,去河邊找鬼法梯。 笑死遭殉,一個(gè)胖子當(dāng)著我的面吹牛锄开,可吹牛的內(nèi)容都是我干的桃移。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼蹂析,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼舔示!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起电抚,我...
    開(kāi)封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤惕稻,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后蝙叛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體俺祠,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年借帘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蜘渣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡肺然,死狀恐怖蔫缸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情际起,我是刑警寧澤拾碌,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站街望,受9級(jí)特大地震影響校翔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜灾前,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一防症、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧哎甲,春花似錦蔫敲、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至础嫡,卻和暖如春指么,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背榴鼎。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工伯诬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人巫财。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓盗似,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親平项。 傳聞我的和親對(duì)象是個(gè)殘疾皇子赫舒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容