微服務架構(gòu)與領(lǐng)域驅(qū)動設(shè)計應用實踐

本篇文章一共分為三個部分他匪,分別是微服務架構(gòu)的演進過程、具體實踐微服務的應用技術(shù)和領(lǐng)域驅(qū)動設(shè)計的意識轉(zhuǎn)變夸研。微服務架構(gòu)已經(jīng)滲透到互聯(lián)網(wǎng)應用的方方面面诚纸,而領(lǐng)域驅(qū)動設(shè)計也逐漸被業(yè)界所接收。

微服務架構(gòu)幾乎都是從 ALL IN ONE 的單體架構(gòu)演進而來陈惰,中間又經(jīng)歷了分布式架構(gòu)畦徘、面向服務架構(gòu)的演進過程。

單體架構(gòu)往往以煙筒式方式發(fā)展抬闯,往往存在兩個主要問題:中心化和耦合度高井辆。所謂中心化,就是數(shù)據(jù)集中存儲在單個數(shù)據(jù)庫中溶握,業(yè)務系統(tǒng)集中部署在單臺服務器上杯缺,通過集群部署方式提供服務能力,然而中心化的問題睡榆,也就是單點問題萍肆。而耦合度高袍榆,主要是指其中一個功能模塊升級,其它的模塊都得一起升級塘揣。這里要說明下包雀,模塊依賴度高不是單體架構(gòu)的錯,是因為本來架構(gòu)可能就沒有設(shè)計好亲铡,但是才写,在實際場景中,隨著快速迭代開發(fā)奖蔓,研發(fā)換了一波又一波赞草,產(chǎn)品走了一茬又一茬,難免系統(tǒng)架構(gòu)腐化嚴重吆鹤。

看到了單體架構(gòu)的諸多問題厨疙,系統(tǒng)開始通過按功能或模塊進行拆分,拆分成多個獨立的子系統(tǒng)疑务,系統(tǒng)間通過 RPC沾凄、MQ 方式調(diào)用,由此逐漸演變?yōu)榉植际降姆占軜?gòu)暑始。分布式服務架構(gòu)主要通過服務化和層次化進行解耦拆分搭独,《架構(gòu)整潔之道》書中提到一點,系統(tǒng)可以降解為策略和層次廊镜,而架構(gòu)設(shè)計就是把相同的策略分到同一個組件中牙肝,反之,分屬于不同的組件嗤朴。所以配椭,架構(gòu)設(shè)計可以通過分層設(shè)計,由高層次服務調(diào)用低層次服務雹姊,低層次服務通過接口向上提供服務股缸,以實現(xiàn)系統(tǒng)之間的解耦。也正是在這一階段吱雏,單體架構(gòu)一下子被拆分成幾個或幾十個系統(tǒng)敦姻。

但是隨著架構(gòu)的發(fā)展,問題又接踵而來歧杏,在沒有做好邊界的劃分之前镰惦,系統(tǒng)拆分的服務往往是松散的。正如《架構(gòu)整潔之道》所講:軟件架構(gòu)設(shè)計本身就是一門劃分邊界的藝術(shù)犬绒。所以旺入,很多系統(tǒng)在這一階段,又往往進行了服務內(nèi)聚和去層次化的演變過程。所謂服務內(nèi)聚茵瘾,就是以領(lǐng)域驅(qū)動設(shè)計為原則礼华,重新界定領(lǐng)域邊界,對模塊進行服務整合拗秘,對系統(tǒng)進行合并圣絮。而去層次化,則是去除服務層次高低之分聘殖,按服務調(diào)用最優(yōu)鏈路提供服務請求晨雳,降低深度行瑞,以此保證系統(tǒng)的穩(wěn)定性能奸腺。

系統(tǒng)如何從 0 到 1,從 1 到 2血久,從 2 到 100突照,在具體實踐微服務的過程并不容易。首先氧吐,考慮的第一個問題是:微服務是什么讹蘑?其實,微服務是一個動作:拆筑舅。說到拆座慰,就涉及到兩個問題,第一翠拣,怎么拆版仔?第二,拆到什么程度误墓。

第一個問題蛮粮,關(guān)于怎么拆,需要關(guān)注兩個層面谜慌,一是發(fā)版速度然想,如商品、交易欣范、促銷等不同領(lǐng)域的迭代速度和開發(fā)速度是不一致的变泄,所以,應該拆分到不同的領(lǐng)域恼琼,否則妨蛹,就可能耦合在一起,A 上線 B 必須跟著一起上驳癌,這可能就應該合并到一起滑燃。另一個是能源協(xié)同,每個系統(tǒng)后面對應不同的研發(fā)團隊颓鲜,一個項目往往需要幾個團隊分工協(xié)作表窘,那么系統(tǒng)拆分必然導致團隊協(xié)作的成本典予,所以拆分系統(tǒng)同樣也是拆分團隊,要考慮協(xié)作溝通所帶來的成本乐严。

第二個問題瘤袖,拆到什么程度。其實昂验,已經(jīng)有很多人對微服務進行了定義捂敌,其中我認為最重要的兩點:一是微服務或一組微服務,應該是一套獨立部署運行的服務既琴,二是微服務所依賴的數(shù)據(jù)資源應該是彼此間相互獨立隔離部署的占婉。

其實,拆只是實踐微服務的開始甫恩,要搭建整體的微服務框架還要進行四部曲:拆逆济、服務化、高可用磺箕、隔離奖慌。

1,服務拆分

微服務講究拆分松靡,那么多微才是微简僧,以及,怎么才是比較合理的拆分雕欺。在架構(gòu)設(shè)計領(lǐng)域岛马,有一個大家都在講的著名定律:康為定律,可以理解為:一個系統(tǒng)架構(gòu)的組織關(guān)系是和團隊的組織關(guān)系相匹配的阅茶。如交易系統(tǒng)會對應一個交易系統(tǒng)的研發(fā)團隊蛛枚,商品系統(tǒng)會對應一個商品系統(tǒng)的研發(fā)團隊,這種職責明確的組織結(jié)構(gòu)會使得系統(tǒng)開發(fā)更高效脸哀。

(圖片來自網(wǎng)絡(luò))

《未來架構(gòu)》一書中講過一個 AKF 立方體模型蹦浦,從三個緯度講述功能拆分、水平擴展撞蜂、數(shù)據(jù)分區(qū)所產(chǎn)生的復雜度盲镶,如果只有一個系統(tǒng),單臺部署蝌诡,單點存儲溉贿,那么它就應該只是一個點,因為隨著量級的增大浦旱,系統(tǒng)在每個緯度不斷延長宇色,逐漸成為一個龐大的立方體。

(圖片來自網(wǎng)絡(luò))

拆分可以分為系統(tǒng)拆分、功能拆分和讀寫拆分宣蠕。如一個單體系統(tǒng)中例隆,按照用戶的交互場景看,門戶首頁可以拆分為前臺系統(tǒng)抢蚀,類目镀层、商品、搜索等功能可以拆分到商品中心皿曲,訂單唱逢、結(jié)算、發(fā)票等功能則可以拆分到交易中心屋休,這就是簡單的系統(tǒng)拆分和功能拆分坞古。而有些功能較為特殊,如商詳頁博投,在讀取時需要聚合讀取绸贡,所以又可以進行讀寫拆分盯蝴。

2毅哗,服務化

微服務首先需要有微服務基礎(chǔ)設(shè)施,沒有微服務基礎(chǔ)設(shè)施捧挺,實踐微服務就是一場災難虑绵。以 SOA 落地方式為例,SOA 落地方式主要有:分布式服務化和集中式管理(ESB)闽烙,分布式服務化的技術(shù)手段有 dubbo 或 spring cloud 等等翅睛,必須有整套的如服務發(fā)現(xiàn)、服務訂閱黑竞、服務監(jiān)控捕发、服務追蹤、服務日志等微服務基礎(chǔ)設(shè)置很魂,才能進行微服務架構(gòu)扎酷。不能簡單只有 p2p 的服務調(diào)用就開始服務化,那是不現(xiàn)實的遏匆。

3法挨,服務治理

當服務拆分的設(shè)計方案確認完畢,而服務化的基礎(chǔ)設(shè)施也部署到位幅聘,那么系統(tǒng)往往一下子就會突然發(fā)布出成百上千個服務接口凡纳,就像一個網(wǎng)絡(luò)一樣,每個服務或微服務就像網(wǎng)中的一個節(jié)點帝蒿,彼此之間關(guān)聯(lián)和聯(lián)系荐糜。但是,服務網(wǎng)絡(luò)應該被設(shè)計成為一個有向無環(huán)圖,否則暴氏,就是一團麻丛版。如開始的時候,只是 A 調(diào)用 B偏序,但隨著業(yè)務發(fā)展页畦,需要修改,但是因為對 A 不了解研儒,就加個環(huán)節(jié) B 調(diào)用 A豫缨,如此形成了環(huán)形調(diào)用,不僅邏輯復雜了,還降低了穩(wěn)定和性能丧肴。

這里的服務治理不是講中間件團隊的服務治理焰络,如超時優(yōu)化、啟動優(yōu)化等等舍败,而是作為應用平臺對服務的治理。服務治理又分為三個階段:服務梳理敬拓、服務界定和服務編排邻薯。所謂服務梳理就是梳理系統(tǒng)對外開放的服務化接口,包括服務的 provider 和 consumer乘凸,以及服務分組厕诡、動態(tài)路由等依賴的梳理,然后對拆散的服務進行歸類营勤、界定灵嫌,確定服務領(lǐng)域從屬性,依據(jù)領(lǐng)域模型重新界定服務邊界葛作,最后通過服務遷移寿羞、切換,對同一領(lǐng)域的服務接口進行服務整合赂蠢,提供統(tǒng)一的服務出口绪穆,實現(xiàn)服務編排。

為什么要進行服務治理客年?那先來看看不進行服務治理的壞處霞幅。

微服務化拆分必然會在初期產(chǎn)生代碼到處拷貝,沒有一套代碼量瓜,必然會造成復雜的擴散司恳,如同樣語意的 A、B 兩個接口绍傲,如果 A 接口存在性能問題需要加緩存扔傅,那么 B 接口也會存在同樣的問題耍共,并需要同樣的改造,這樣復雜度就會到處蔓延猎塞,同時也無法實現(xiàn)統(tǒng)一的服務層架構(gòu),還有荠耽,如果同樣語意或相似語意的接口太多钩骇,那么接口就是混亂的,無法實現(xiàn)有限接口的治理铝量,如果系統(tǒng)出了問題倘屹,可能很難定位問題。業(yè)務邏輯是依賴于數(shù)據(jù)的慢叨,如果接口是混亂的纽匙,那么慢 SQL 等質(zhì)量差的 SQL 就無法進行有效收口改造,同樣就更加難以實現(xiàn)數(shù)據(jù)庫拆分和解耦拍谐。綜上烛缔,服務治理的過程就是從無序到有序的過程。

總結(jié)一下看從拆分到服務化的過程轩拨,就是將原來一個整體的服務打碎践瓷,碎成一塊一塊的零碎服務,然后再對服務重新歸類气嫁、整合当窗,形成一個一個新領(lǐng)域的、獨立的服務寸宵。如單體架構(gòu)就像一個宏偉的城堡,如果相對其中一個點進行調(diào)整和改造元咙,那么可能面臨著牽一發(fā)而動全身的風險梯影。

微服務化就是以一系列小的服務去支撐一個應用的方法論。簡明扼要的說庶香,就是:分而治之甲棍。

4,服務高可用

服務拆分并服務化之后赶掖,是不是就完事了感猛,不!真正的微服務實踐才剛剛開始奢赂,簡單提供了一個接口陪白,是沒有意義的,它必須具備高可用膳灶、高性能咱士、高并發(fā)的三高特性立由,尤以高可用最為重要。保障服務高可用的方法有很多序厉,如數(shù)據(jù)異構(gòu)锐膜、多級緩存、超時與重試弛房、熔斷道盏、異步并發(fā)、降級文捶、限流捞奕、消息隊列、壓測與預案等 拄轻。

重點說下數(shù)據(jù)異構(gòu)颅围,所謂數(shù)據(jù) 異構(gòu),就是將通過順序消費或并發(fā)消費的方式恨搓,訂閱 MySQL 數(shù)據(jù)庫的 binlog院促,然后通過消息,如 Kafka 等 MQ 方式斧抱,異地存儲到緩存或其它數(shù)據(jù)源中常拓,如 Redis、Elasticsearch 等辉浦。數(shù)據(jù)異構(gòu)現(xiàn)在被普通使用弄抬,實現(xiàn)數(shù)據(jù)聚合,形成數(shù)據(jù)閉環(huán)宪郊。

在進行數(shù)據(jù)異構(gòu)的過程中掂恕,需要關(guān)注幾個關(guān)鍵點,一是 CAP 原則弛槐,即強一致性往往被舍棄懊亡,而采用最終一致性的設(shè)計。二是緩存乎串,緩存在微服務架構(gòu)中店枣,不能被當成銀彈來使用,使用緩存必須正視的問題有:熱點緩存 & 大 Value 緩存叹誉、緩存穿透等問題鸯两。三是消息,消息現(xiàn)在還存在的問題有:延遲問題长豁、消息的不穩(wěn)定性(如丟消息)钧唐、消息的不確定性(如 timeout)、消息補償蕉斜、柔性事務等問題逾柿。而這些是微服務高可用架構(gòu)實踐中缀棍,不能不面對的問題。

5机错,服務隔離

隔離也是服務拆分的一種爬范,為什么單獨講?因為服務拆分弱匪、服務化青瀑、服務治理和服務高可用都是在事前或事中可以做的,然而萧诫,有些系統(tǒng)已經(jīng)成了某個樣子斥难,那么我們接收時,首先能做到的就是迅速對系統(tǒng)進行隔離帘饶,保證業(yè)務之間不互相影響哑诊,具體實踐包括:進程線程隔離、集群/機房隔離及刻、讀寫隔離镀裤、動靜隔離、爬蟲/熱點隔離等缴饭。

從單體架構(gòu)開始暑劝,到分布式架構(gòu)設(shè)計、微服務架構(gòu)颗搂,再到現(xiàn)在領(lǐng)域驅(qū)動設(shè)計担猛,作為實踐微服務的架構(gòu)師,思想上又有什么變化丢氢?

我覺得傅联,程序員都是很悶騷的,但每個程序員心里都住一個大俠卖丸,金庸《笑傲江湖》里有氣宗和劍宗之分纺且,什么是劍宗,我理解就像是劍招稍浆、招數(shù),如 spring猜嘱、spring boot衅枫、spring cloud,還有 tomcat朗伶、netty弦撩、serviceless 等,這些技術(shù)论皆、中間件益楼、框架等就像腳手架一樣可以幫助我們提高效率猾漫,但是,我們是否需要出現(xiàn)一個新技術(shù)就學習一個技術(shù)呢感凤?而這就讓我想到了氣宗悯周,它就像是通過對內(nèi)在規(guī)律的掌握,打通任督二脈陪竿,實現(xiàn)融會貫通禽翼,正如《九陽神功》所說:他強任他強,清風拂山崗族跛,我自一口真氣足闰挡。如 Kakfa、Flink礁哄、Hbase 等分區(qū)可用性保障的設(shè)計思想都是基于 BigTable 的分區(qū)復制策略长酗。

正是重心由外到內(nèi)的轉(zhuǎn)變,讓我認知到桐绒,現(xiàn)在系統(tǒng)架構(gòu)的發(fā)展夺脾,很多系統(tǒng)架構(gòu)的復雜度,已經(jīng)不是簡簡單單通過引入一些新技術(shù)或框架掏膏,就能降低系統(tǒng)復雜的劳翰。它需要大大的提前對風險、問題馒疹、隱患的預知佳簸,做到未雨綢繆∮北洌《從零開始學架構(gòu)》書中提到:架構(gòu)設(shè)計的發(fā)展歷程就是在于降低軟件系統(tǒng)復雜的歷程生均。

《架構(gòu)整潔之道》書中提到:一個軟件系統(tǒng)存在的意義,是系統(tǒng)用來賺錢或省錢的那部分代碼腥刹,那才是整個系統(tǒng)的皇冠明珠马胧。所以,當拿到一個需求的時候衔峰,首先考慮的是要解決什么問題佩脊,它的問題域是什么,而不是先考慮用哪種技術(shù)去實現(xiàn)或解決這個問題垫卤,這是本末倒置的處理方法威彰。

從領(lǐng)域驅(qū)動設(shè)計的角度來看,需求首先是問題域穴肘,屬于業(yè)務邊界的事情歇盼,梳理了解要實現(xiàn)什么功能和需求,然后在外延到工作邊界评抚,確認團隊合作的方式豹缀,因為很多需求都可能需要跨團隊合作的伯复,最后才會到應用邊界,即技術(shù)實現(xiàn)的解決問題領(lǐng)域邢笙。

上圖是一個典型的洋蔥頭模型啸如,它的思想就是闡述了從內(nèi)到外的思考過程。然后鸣剪,現(xiàn)實工作中组底,經(jīng)常有人從外往內(nèi)去考慮問題,從我過往的經(jīng)歷舉例筐骇,一次是數(shù)據(jù)異構(gòu)的方案债鸡,之前是采用 Storm,后來 flink 開始流行铛纬,我就將業(yè)務切換到了 flink厌均,但是對于 flink 的調(diào)優(yōu)不到位,從而影響了系統(tǒng)穩(wěn)定性告唆,還有一次是之前搜索用 solr棺弊,后來 es 開始流行,就像切到 es擒悬,但是 es 和 solr 兩套搜索引擎的搜索排序結(jié)果是不一樣的模她,最后,我們只能強奸了業(yè)務懂牧。其實侈净,這都是不太對的∩铮《架構(gòu)整潔之道》也提到:良好的架構(gòu)設(shè)計應該盡可能地允許用戶推遲和延后決定采用什么框架畜侦、數(shù)據(jù)庫、Web 服務以及其他與環(huán)境相關(guān)的工具躯保。

理解領(lǐng)域驅(qū)動設(shè)計旋膳,需求或問題它開始于一個領(lǐng)域意愿,由領(lǐng)域?qū)<液徒桓秷F隊一起途事,輸出統(tǒng)一語言和領(lǐng)域知識验懊,統(tǒng)一語言可以是敏捷看板,因為一個團隊是由產(chǎn)品尸变、運營鲁森、研發(fā)、測試組成的振惰,彼此之間是基于統(tǒng)一語言進行溝通的,然后定義領(lǐng)域邊界垄懂,區(qū)分核心領(lǐng)域骑晶、普通領(lǐng)域痛垛、支持領(lǐng)域,其中核心領(lǐng)域就是由核心團隊開發(fā)的桶蛔,支持領(lǐng)域可以是外包等實現(xiàn)的匙头,在通過映射上下文,確認限界上下文仔雷,最終確認系統(tǒng)應用邊界蹂析。

(圖片來自網(wǎng)絡(luò))

采用領(lǐng)域驅(qū)動設(shè)計的六邊形架構(gòu)繪制了一張交易系統(tǒng)的領(lǐng)域邊界圖,不同顏色表明不同領(lǐng)域碟婆,U/D 代表上游和下游电抚。這個圖還不算完整,因為領(lǐng)域業(yè)務邏輯是要為端服務的竖共,而通過對領(lǐng)域的梳理蝙叛,可以通用的支持很多端。即表達為領(lǐng)域有界公给,端無界借帘。最 終,每個限界上下文即是微服務淌铐。

其實肺然,每個系統(tǒng)的微服務架構(gòu)演進道路各不相同,所以腿准,實踐微服務不能一板一眼原封照抄际起,而是要根據(jù)自己的業(yè)務特征,合理的裁剪释涛,找到合適落地方案加叁。總結(jié)一句話唇撬,那就是:因需而變它匕。雖然微服務的路徑是不一樣的,但方向是相同的窖认。再次回顧微服務的架構(gòu)演進歷程豫柬,你會發(fā)現(xiàn),從單體架構(gòu)開始扑浸,進行拆分烧给,形成微服務之后,又因為各種這樣的原因喝噪,很多微服務架構(gòu)又在進行合并础嫡,現(xiàn)在領(lǐng)域驅(qū)動設(shè)計來了,又開始重新拆分。真可謂:話說天下大勢榴鼎,分久必合伯诬,合久必分。https://mp.weixin.qq.com/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末巫财,一起剝皮案震驚了整個濱河市盗似,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌平项,老刑警劉巖赫舒,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異闽瓢,居然都是意外死亡接癌,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門鸳粉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扔涧,“玉大人,你說我怎么就攤上這事届谈】菀梗” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵艰山,是天一觀的道長湖雹。 經(jīng)常有香客問我,道長曙搬,這世上最難降的妖魔是什么摔吏? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮纵装,結(jié)果婚禮上征讲,老公的妹妹穿的比我還像新娘。我一直安慰自己橡娄,他們只是感情好诗箍,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著挽唉,像睡著了一般滤祖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瓶籽,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天匠童,我揣著相機與錄音,去河邊找鬼塑顺。 笑死汤求,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播首昔,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼寡喝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了勒奇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤巧骚,失蹤者是張志新(化名)和其女友劉穎赊颠,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體劈彪,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡竣蹦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了沧奴。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片痘括。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖滔吠,靈堂內(nèi)的尸體忽然破棺而出纲菌,到底是詐尸還是另有隱情,我是刑警寧澤疮绷,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布翰舌,位于F島的核電站,受9級特大地震影響冬骚,放射性物質(zhì)發(fā)生泄漏椅贱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一只冻、第九天 我趴在偏房一處隱蔽的房頂上張望庇麦。 院中可真熱鬧,春花似錦喜德、人聲如沸山橄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽驾胆。三九已至,卻和暖如春贱呐,著一層夾襖步出監(jiān)牢的瞬間丧诺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工奄薇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留驳阎,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像呵晚,于是被迫代替她去往敵國和親蜘腌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

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