大數(shù)據(jù)時(shí)代的微服務(wù)之路

大數(shù)據(jù)是什么,大數(shù)據(jù)如同少年談性,都好像很明白的樣子漩仙,但是誰都不怎么明白露该。

有人說大數(shù)據(jù)就是大量海量數(shù)據(jù)處理册倒。是嗎西雀?我說這樣理解可能有點(diǎn)片面萨驶。

在此我舉兩個(gè)小例子,希望有助于對(duì)于這個(gè)概念能做一定的闡述艇肴。

例 1:

當(dāng)你有一天在樹林里面運(yùn)送一塊大木樁,你想一次性運(yùn)回農(nóng)場育谬,你牽一頭牛來,這頭牛來運(yùn)輸這塊木頭帮哈,拉的動(dòng)嗎膛檀,可以

當(dāng)你有一天有10塊大木樁,你還牽頭牛來咖刃,它拉得動(dòng)嗎憾筏,可能也拉的動(dòng),但是它會(huì)比較費(fèi)力氧腰,效率會(huì)低一點(diǎn),但是它還是能完成任務(wù)箩帚。

當(dāng)你有一天有50塊大木樁黄痪,你還牽頭牛來,它拉得動(dòng)嗎桅打,拉不動(dòng),為什么鹅搪,50塊木樁的重量超過了它的負(fù)載能力潦嘶,在這種情況下崇众,這50塊木頭對(duì)于這頭牛來說就是一個(gè)大數(shù)據(jù)航厚。

例 2:

NASA美國航空航天總局需要24小時(shí)內(nèi)完成對(duì)月球上面?zhèn)鬏敾貋淼臄?shù)據(jù)進(jìn)行計(jì)算分析,于是部署了一臺(tái)計(jì)算機(jī)眯漩,24小時(shí)內(nèi)完成了

突然麻顶,有一天,領(lǐng)導(dǎo)一上班說队萤,我需要今天下班前得到當(dāng)天數(shù)據(jù)報(bào)告矫钓,大家就慌了,因?yàn)檎D莻€(gè)部署的計(jì)算機(jī)需要16小時(shí)完成新娜。在這種情況的概龄,在8小時(shí)內(nèi)完成對(duì)正常一天數(shù)據(jù)量的分析對(duì)于那臺(tái)計(jì)算機(jī)來就是大數(shù)據(jù)。

那對(duì)于這兩個(gè)例子私杜,當(dāng)遇到大數(shù)據(jù)情況下,解決方案是什么呢嚎幸?

在例一的情況下寄猩,你有兩個(gè)選擇。第一田篇,牽來一頭大象箍铭,大象一次就能拉80個(gè)大木樁,50個(gè)對(duì)于它來說綽綽有余诈火。第二,牽來五頭牛刀崖,一樣可以順利完成任務(wù)。

在例二的情況下馆截,你同樣有兩個(gè)選擇蜂莉,立刻把數(shù)據(jù)分析計(jì)算程序部署到一臺(tái)超級(jí)計(jì)算機(jī)上面,譬如中國的天河-2窖张,美國的Cray蚁滋,這樣可能一下子數(shù)據(jù)就能出來,或者你說我把程序部署到3臺(tái)同等級(jí)別計(jì)算機(jī)上面澄阳,利用這3臺(tái)計(jì)算機(jī)的計(jì)算能力來完成任務(wù)踏拜。

那么問題來了,從成本上面來說哪個(gè)合算肮塞,大家會(huì)驚訝的發(fā)現(xiàn)姻锁,在同樣完成任務(wù)的情況下,五頭牛的成本比一頭大象成本小很多拷窜,而三臺(tái)普通計(jì)算機(jī)比一臺(tái)超級(jí)計(jì)算機(jī)成本小很多涧黄。而那五頭牛和三臺(tái)計(jì)算機(jī),在協(xié)力合作的條件下懊昨,完成了對(duì)于任何一個(gè)單元都不可能完成的任務(wù)春宣,這就是一個(gè)簡單的分布式系統(tǒng) (Distributed system)的例子嫉你,而每個(gè)單元可以從廣義上稱之為一個(gè)微服務(wù)(MicroService)躏惋。

微服務(wù),一個(gè)最近被炒的很火的名字油挥,那他到底是個(gè)什么東西呢款熬?

微服務(wù)沒有一個(gè)精確的定義,可以說這是一種軟件架構(gòu)風(fēng)格惋鹅,利用模組化的方式組合出復(fù)雜的大型應(yīng)用程序殉簸,各功能區(qū)塊使用與語言無關(guān) (Language agnostic) 的 API 集相互通訊般卑,而實(shí)現(xiàn)方法也多種多樣,每個(gè)公司使用微服務(wù)的出發(fā)點(diǎn)也不盡相同蝠检。但是微服務(wù)卻有幾個(gè)重要的共同特點(diǎn):

1. 小而單一 (small and single resposibility)叹谁,并且專注于做一件事情,只負(fù)責(zé)一個(gè)系統(tǒng)下的某一個(gè)功能焰檩。

? ? 譬如我們在第一個(gè)例子中的一頭牛析苫,他只做一件事情,那就是拉車運(yùn)輸衩侥,而且他做的很好顿乒。而你作為趕車的泽谨,也可以是整個(gè)運(yùn)輸系統(tǒng)中的一個(gè)微服務(wù)特漩,你也負(fù)責(zé)一件事件骨杂,就是這幾頭牛都走同一方向,而且方向正確蛤售,你并不負(fù)責(zé)拉車妒潭。

? ?在初步劃分模塊的時(shí)候,通常公司可以按照自己的業(yè)務(wù)領(lǐng)域來分塊服務(wù)漠酿,一個(gè)典型的例子就是垂直電商系統(tǒng)一般可以分塊為用戶模塊服務(wù) Customer Service, 產(chǎn)品模塊服務(wù) Product Service, 訂單模塊服務(wù) Order Service, 支付模塊服務(wù) Payment Service 和 運(yùn)送模塊服務(wù)Shipping Service谎亩,每一個(gè)服務(wù)只負(fù)責(zé)一個(gè)領(lǐng)域模型中所需要完成的任務(wù)。這樣輕松實(shí)現(xiàn)整個(gè)微服務(wù)系統(tǒng)的松耦合和較高的維護(hù)能力匈庭。

2. 獨(dú)立部署 (independently deployable),升級(jí)夭拌,擴(kuò)展或者替換

? ? 每個(gè)服務(wù)都可以單獨(dú)部署及重新部署而不影響整個(gè)系統(tǒng)紊选。這使得服務(wù)很容易升級(jí)。

? ?在此我們可以對(duì)比一下單體應(yīng)用(monolithic application)兵罢。譬如上文中提到的垂直電商系統(tǒng),在單體應(yīng)用下巩那,所有這些模塊都是打包在同一個(gè)WAR此蜈,或者EAR文件下面,部署到一個(gè)應(yīng)用服務(wù)器上面东囚,這個(gè)應(yīng)用服務(wù)器可以Web應(yīng)用服務(wù)器战授,譬如TOMCAT,或者是J2EE應(yīng)用服務(wù)器份帐,譬如WebLogic, IBAM WebSpeher或者是Jboss畜挨。 通常在這樣架構(gòu)下噩凹,當(dāng)我們需要替換,升級(jí)务冕,或者一個(gè)簡單的修改某一個(gè)模塊幻赚,譬如支付模塊的話,我們需要怎么做箩退?修改支付模塊代碼佳谦,編譯整個(gè)項(xiàng)目钻蔑,重新打包成一個(gè)WAR,EAR文件咪笑,然后替換整個(gè)應(yīng)用系統(tǒng)窗怒。即使我們修改的模塊和其他模塊沒有任何關(guān)系,但是扬虚,我們必須一起替換辜昵。這就增加了我們?nèi)粘5墓ぷ髁亢惋L(fēng)險(xiǎn),譬如測試方便贷洲,除了做單元測試,我們還需要做一個(gè)集成測試,來保持我們其他模塊一樣工作雁竞;風(fēng)險(xiǎn)就是如果是一個(gè)架構(gòu)不是很好的軟件,軟件個(gè)模塊之間沒實(shí)現(xiàn)松耦合彪腔,那么修改一個(gè)模塊进栽,很有可能導(dǎo)致另外一個(gè)模塊的不工作快毛,別告訴我你沒有遇到過,當(dāng)你是一個(gè)新人唠帝,加入一個(gè)開發(fā)組襟衰,team leader告訴你,把支付模塊一個(gè)bug修了绍坝,你廢了九牛二虎之力苔悦,很開心的修完了那個(gè)bug,通過單元測試灾挨,提交了代碼竹宋,過了一會(huì)一封郵件過來,jenkins上面出錯(cuò)了秒拔,某一個(gè)和支付模塊完全不相關(guān)的用戶管理模塊出錯(cuò)了飒硅。是誰的錯(cuò),不是你的錯(cuò)庵芭,可能是架構(gòu)師沒有架構(gòu)好軟件,但是通常情況下眨唬,你得負(fù)責(zé)好乐。

? ? 而微服務(wù)的獨(dú)立部署能力就是為了避免這樣類似的問題再出現(xiàn)蔚万,通常一個(gè)微服務(wù)是領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)下完成的,各模塊之間有非常清楚明晰的邊界昵慌。

? ? 再拿第一個(gè)例子來說版扩,你趕著五頭牛運(yùn)送木樁,突然有一頭牛脫水倒下了蜻韭,這個(gè)時(shí)候你并不荒柿扣,打個(gè)電話到農(nóng)場,給你再牽一頭或者是牛俯画,或者是驢司草,或者是馬埋虹,你很輕松的就替換了那頭倒下的牛,而且對(duì)于其他幾頭牛并沒有影響胰柑,他們還是可以繼續(xù)安全的工作。

? ? ?那么有人會(huì)說崩瓤,那怎么從一個(gè)單體應(yīng)用踩官,轉(zhuǎn)換成一個(gè)成功,松耦合肾扰,易于升級(jí)和擴(kuò)展的微服務(wù)架構(gòu)的蛋逾,這有一個(gè)非常有趣的話題区匣,包括很多方面的考慮蒋院,從領(lǐng)域驅(qū)動(dòng)設(shè)計(jì),到技術(shù)選擇和實(shí)現(xiàn)姑丑,到怎么一步一步分解一個(gè)巨大而復(fù)雜的單體應(yīng)用辞友,到一個(gè)個(gè)微服務(wù),以及各個(gè)微服務(wù)之間的通信選擇留拾,畢竟當(dāng)你擁有200個(gè)微服務(wù)的時(shí)候痴柔,微服務(wù)之間的通信已經(jīng)不是簡單的進(jìn)程內(nèi)呼叫了疫向,而是通過網(wǎng)絡(luò)協(xié)議來實(shí)現(xiàn)的,穩(wěn)定性和性能都會(huì)有影響谈火。

3. 輕量級(jí)通信協(xié)議 (lightweight communication protocol)

? 最常用的是HTTP協(xié)議下的REST匙奴,或者M(jìn)essage機(jī)制,譬如JMS谍肤, 或者AMQP (Advanced Message Queuing Protocol)

? ? 由于每個(gè)微服務(wù)都是一個(gè)獨(dú)立的應(yīng)用程序荒揣,這個(gè)獨(dú)立程序可以部署在同一個(gè),或者不同的服務(wù)器上面恳蹲,從java程序角度來講俩滥,每一個(gè)微服務(wù)就是一個(gè)java進(jìn)程。所以服務(wù)之間的通信就不再是一個(gè)進(jìn)程內(nèi)的呼叫错忱。我們就需要一個(gè)輕量級(jí)通信協(xié)議來完成各個(gè)分布式服務(wù)之間的通信挂据。而這種通信可以分為兩種崎逃,同步和異步。當(dāng)我們需要一個(gè)同步呼叫來完成一個(gè)業(yè)務(wù)邏輯勒葱,通常會(huì)通過HTTP下的REST API來實(shí)現(xiàn)障贸,通常可以選擇Spring下的Restful框架或者是Oracle下的JAX-RS涩维。而當(dāng)我們需要服務(wù)之間做異步通信時(shí)袁波,Message會(huì)是一個(gè)很好的協(xié)議篷牌。 Java微服務(wù)應(yīng)用程序之間可以使用非常成熟的JMS,如果是Java和非Java程序應(yīng)用之間戳杀,現(xiàn)在比較流行的是AMQP協(xié)議。

4. 去中心化數(shù)據(jù)管理 (decentralized data management)

?多樣化持久性(Polyglot Persistence)隔缀,即讓每一個(gè)微服務(wù)都有其自己的數(shù)據(jù)庫傍菇,并且允許其各自擁有不同類型的數(shù)據(jù)持久化特性一直是微服務(wù)架構(gòu)所倡導(dǎo)的丢习。

? 當(dāng)我們開發(fā)一個(gè)企業(yè)化大型應(yīng)用時(shí),我們通常會(huì)發(fā)現(xiàn)揽思,數(shù)據(jù)的類型见擦,屬性和被查詢和修改的頻率都會(huì)不一樣,而傳統(tǒng)的單體應(yīng)用下,我們通常會(huì)使用一個(gè)中心數(shù)據(jù)庫执俩,來存儲(chǔ)所有數(shù)據(jù)癌刽。譬如一個(gè)垂直電商的應(yīng)用里面可以有客戶信息數(shù)據(jù)显拜,商品數(shù)據(jù),購物車數(shù)據(jù)矮固,訂單數(shù)據(jù)譬淳,支付數(shù)據(jù)邻梆。單體應(yīng)用下,我們很可能就使用一個(gè)MYSQL數(shù)據(jù)庫就解決所有問題尼摹。而微服務(wù)框架下,允許也提倡每一個(gè)服務(wù)模塊下?lián)碛凶约旱臄?shù)據(jù)庫玄呛,這個(gè)數(shù)據(jù)庫可以是SQL類型的數(shù)據(jù)庫惠赫,譬如Oracle儿咱,MYSQL,Postgres等等怠缸,也可以是NOSQL類型數(shù)據(jù)庫钳宪,譬如MongoDB吏颖,Cassandra, Amazon DynamoDB等等,當(dāng)然你也可以根據(jù)你的數(shù)據(jù)類型疚俱,在NOSQL里面來選擇哪種類型的數(shù)據(jù)庫缩多。那么說我們就不能讓兩個(gè)或多個(gè)微服務(wù)之間共享一個(gè)數(shù)據(jù)庫了嗎衬吆,個(gè)人認(rèn)為是不提倡,但是也不反對(duì)逊抡,具體情況具體分析冒嫡。譬如當(dāng)你需要一個(gè)request call里面的多個(gè)數(shù)據(jù)持久化在一個(gè)事務(wù)內(nèi)完成,在這種情況下潜秋,通常一個(gè)SQL數(shù)據(jù)庫會(huì)讓事情變得簡單峻呛。譬如當(dāng)你擔(dān)心數(shù)據(jù)的一致性能否得到保障,而且要達(dá)到ACID級(jí)別時(shí)寨躁,可能分布式數(shù)據(jù)管理會(huì)變得不可能牙勘。當(dāng)然如果你一定要分布式管理數(shù)據(jù)的話方面,可以通過最終一致性(Eventual Consistency)來做。實(shí)現(xiàn)數(shù)據(jù)的強(qiáng)一致性恭金,強(qiáng)最終一致性操禀,還是最終一致性一直是分布式計(jì)算下的一個(gè)難題。這也是我們在設(shè)計(jì)微服務(wù)架構(gòu)時(shí)可能會(huì)遇到也需要考慮的問題横腿。

5. 公共設(shè)施自動(dòng)化 (Infrastructure Automation)

?通過采用一系列的開源軟件颓屑,自動(dòng)化開發(fā),測試耿焊,部署流程揪惦,可以大大提高產(chǎn)品的質(zhì)量和交付能力。

? 在決定是否要采用微服務(wù)架構(gòu)前罗侯,應(yīng)該考慮團(tuán)隊(duì)是否有足夠的經(jīng)驗(yàn)在公共設(shè)施自動(dòng)化方面丹擎。實(shí)戰(zhàn)用例告訴我們,那些在微服務(wù)系統(tǒng)上面取得成功的團(tuán)隊(duì)都擁有豐富的連續(xù)集成和連續(xù)交付能力。這涉及到一連串的自動(dòng)化能力再愈,包括編譯榜苫,單元測試,功能測試翎冲,集成測試垂睬,用戶體驗(yàn)測試和性能測試上面的自動(dòng)化,包括部署自動(dòng)化抗悍。我們只有通過做大量的自動(dòng)化測試驹饺,才能大大的增強(qiáng)團(tuán)隊(duì)的信心。因?yàn)楫?dāng)我們采用微服務(wù)架構(gòu)時(shí)缴渊,我們所要處理的不是一個(gè)單體應(yīng)用所帶來的問題赏壹,而且?guī)资畟€(gè),幾百個(gè)微服務(wù)衔沼,甚至是部署在上百個(gè)服務(wù)器上面蝌借,到那時(shí)候我們再考慮自動(dòng)化昔瞧,可能未免太晚了。

? 這邊也值得聽一下亞馬遜云服務(wù)團(tuán)隊(duì)一直倡導(dǎo)的兩個(gè)微服務(wù)開發(fā)的原則:

? ?1. Two Pizza Size

? ? ? ? 就是說每一個(gè)團(tuán)隊(duì)只需要定兩個(gè)Pizza就能吃飽菩佑,當(dāng)然這邊是指美式Pizza自晰,不是意大利 ? Pizza,基本就是說一個(gè)團(tuán)隊(duì)在6 - 10 人之間稍坯,這也完全符合一個(gè)敏捷開發(fā)團(tuán)體的個(gè)數(shù)酬荞。

? ?2. ?You Build It, You Run It

? ? ? ? 是指誰開發(fā)和編譯的軟件,誰來運(yùn)行瞧哟。這也就是為什么亞馬遜每一個(gè)團(tuán)隊(duì)成員都會(huì)輪流On Call混巧,這也是被很多亞馬遜員工所批評(píng)的。

? ? 不管怎么樣我們從這兩個(gè)原則可以看到在采用微服務(wù)架構(gòu)時(shí)候可以采用的方法绢涡,每一個(gè)團(tuán)隊(duì)負(fù)責(zé)一個(gè)或者多個(gè)微服務(wù)牲剃,采用自動(dòng)化的編譯,測試雄可,集成凿傅,部署,檢測開源工具数苫,讓這個(gè)流程變得很boring聪舒,大大提高交付能力。而且負(fù)責(zé)開發(fā)的團(tuán)隊(duì)當(dāng)然對(duì)于軟件是最熟悉的虐急,一旦出現(xiàn)什么問題箱残,可以立即就能找到根源和解決,而不是需要通過復(fù)雜的部門之間的溝通再來解決問題止吁。

? 這期我們從大數(shù)據(jù)被辑,分布式系統(tǒng),談到了當(dāng)前非常流行的微服務(wù)架構(gòu)以及其共享的一些重要特征敬惦。當(dāng)然盼理,當(dāng)你真正開始著手開始把一個(gè)單體應(yīng)用變?yōu)橐幌盗形⒎?wù)時(shí),所需要面臨的挑戰(zhàn)還有很多俄删,譬如怎么來對(duì)你已經(jīng)存在的碩大的單體應(yīng)用來解體宏怔;譬如當(dāng)你成功解體到一系列的微服務(wù)后,怎么來解決由于分布式結(jié)構(gòu)導(dǎo)致的系統(tǒng)性能問題畴椰;譬如當(dāng)你實(shí)現(xiàn)了多樣持久化后臊诊,發(fā)現(xiàn)事務(wù)處理變得積極復(fù)雜,怎么來管理分布式系統(tǒng)下的數(shù)據(jù)斜脂,保證數(shù)據(jù)一致性抓艳,等等。這些我們希望會(huì)在接下來幾期進(jìn)行討論帚戳。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末壶硅,一起剝皮案震驚了整個(gè)濱河市威兜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌庐椒,老刑警劉巖椒舵,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異约谈,居然都是意外死亡笔宿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門棱诱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泼橘,“玉大人,你說我怎么就攤上這事迈勋【婷穑” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵靡菇,是天一觀的道長重归。 經(jīng)常有香客問我,道長厦凤,這世上最難降的妖魔是什么鼻吮? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮较鼓,結(jié)果婚禮上椎木,老公的妹妹穿的比我還像新娘。我一直安慰自己博烂,他們只是感情好香椎,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著禽篱,像睡著了一般畜伐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谆级,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音讼积,去河邊找鬼肥照。 笑死,一個(gè)胖子當(dāng)著我的面吹牛勤众,可吹牛的內(nèi)容都是我干的舆绎。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼们颜,長吁一口氣:“原來是場噩夢啊……” “哼吕朵!你這毒婦竟也來了猎醇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤努溃,失蹤者是張志新(化名)和其女友劉穎硫嘶,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體梧税,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沦疾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了第队。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哮塞。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖凳谦,靈堂內(nèi)的尸體忽然破棺而出忆畅,到底是詐尸還是另有隱情,我是刑警寧澤尸执,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布家凯,位于F島的核電站,受9級(jí)特大地震影響剔交,放射性物質(zhì)發(fā)生泄漏肆饶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一岖常、第九天 我趴在偏房一處隱蔽的房頂上張望驯镊。 院中可真熱鬧,春花似錦竭鞍、人聲如沸板惑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冯乘。三九已至,卻和暖如春晒夹,著一層夾襖步出監(jiān)牢的瞬間裆馒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國打工丐怯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喷好,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓读跷,卻偏偏與公主長得像梗搅,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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