分布式事務(wù)淺析

個(gè)人學(xué)習(xí)分布式事務(wù)的總結(jié)坟岔,引用了很多優(yōu)秀文章的闡述谒兄。如有版權(quán)問題,請(qǐng)告知社付。

事務(wù)的特點(diǎn)

事務(wù)擁有以下四個(gè)特性承疲,習(xí)慣上被稱為ACID特性。

  1. 原子性(Atomicity):事務(wù)作為一個(gè)整體被執(zhí)行鸥咖,包含在其中的對(duì)數(shù)據(jù)庫的操作要么全部被執(zhí)行燕鸽,要么都不執(zhí)行。
  2. 一致性(Consistency):事務(wù)應(yīng)確保數(shù)據(jù)庫的狀態(tài)從一個(gè)一致狀態(tài)轉(zhuǎn)變?yōu)榱硪粋€(gè)一致狀態(tài)啼辣。一致狀態(tài)是指數(shù)據(jù)庫中的數(shù)據(jù)應(yīng)滿足完整性約束啊研。除此之外,一致性還有另外一層語義鸥拧,就是事務(wù)的中間狀態(tài)不能被觀察到(這層語義也有說應(yīng)該屬于原子性)党远。
  3. 隔離性(Isolation):多個(gè)事務(wù)并發(fā)執(zhí)行時(shí),一個(gè)事務(wù)的執(zhí)行不應(yīng)影響其他事務(wù)的執(zhí)行富弦,如同只有這一個(gè)操作在被數(shù)據(jù)庫所執(zhí)行一樣沟娱。
  4. 持久性(Durability):已被提交的事務(wù)對(duì)數(shù)據(jù)庫的修改應(yīng)該永久保存在數(shù)據(jù)庫中。在事務(wù)結(jié)束時(shí)腕柜,此操作將不可逆轉(zhuǎn)济似。

本地事務(wù)

本地事務(wù)一般指數(shù)據(jù)庫單庫事務(wù)柳爽。傳統(tǒng)關(guān)系數(shù)據(jù)庫對(duì)事務(wù)支持已經(jīng)非常完善。主流的開發(fā)框架碱屁,比如Spring,針對(duì)傳統(tǒng)數(shù)據(jù)庫的事務(wù)提供了便捷的支持蛾找,通過配置或者注解等方式來控制事務(wù)娩脾。

分布式事務(wù)

規(guī)模龐大的系統(tǒng),就要跟分布式事務(wù)打交道了打毛。主要的一些業(yè)務(wù)場(chǎng)景如下柿赊。

分庫分表

數(shù)據(jù)庫做水平切分時(shí),一個(gè)SQL操作會(huì)涉及多個(gè)數(shù)據(jù)庫幻枉,這些操作需要在一個(gè)事務(wù)中完成碰声。MyCat支持分布式事務(wù)。

image.png

微服務(wù)

業(yè)務(wù)拆分成眾多微服務(wù)之后熬甫,業(yè)務(wù)的調(diào)用鏈條變長(zhǎng)了胰挑,可能涉及眾多服務(wù)、數(shù)據(jù)庫椿肩、消息服務(wù)瞻颂,所有的資源操作需要在一個(gè)事務(wù)中完成。

兩階段提交

XA是一個(gè)分布式事務(wù)協(xié)議郑象。XA分為兩部分:事務(wù)管理器(Transaction Manager)和本地資源管理器(Resource Manager)贡这。其中本地資源管理器往往由數(shù)據(jù)庫實(shí)現(xiàn),比如Oracle厂榛、DB2這些商業(yè)數(shù)據(jù)庫都實(shí)現(xiàn)了XA接口盖矫,而事務(wù)管理器作為全局的調(diào)度者,負(fù)責(zé)各個(gè)本地資源的提交和回滾击奶。2PC和3PC提交都是基于XA協(xié)議實(shí)現(xiàn)的辈双。

兩階段提交的問題

  1. 同步阻塞問題。執(zhí)行過程中柜砾,所有參與節(jié)點(diǎn)都是事務(wù)阻塞型的辐马。當(dāng)參與者占有公共資源時(shí),其他第三方節(jié)點(diǎn)訪問公共資源不得不處于阻塞狀態(tài)局义。

  2. 單點(diǎn)故障喜爷。由于協(xié)調(diào)者的重要性,一旦協(xié)調(diào)者發(fā)生故障萄唇。參與者會(huì)一直阻塞下去檩帐。尤其在第二階段,協(xié)調(diào)者發(fā)生故障另萤,那么所有的參與者還都處于鎖定事務(wù)資源的狀態(tài)中湃密,而無法繼續(xù)完成事務(wù)操作诅挑。(如果是協(xié)調(diào)者掛掉,可以重新選舉一個(gè)協(xié)調(diào)者泛源,但是無法解決因?yàn)閰f(xié)調(diào)者宕機(jī)導(dǎo)致的參與者處于阻塞狀態(tài)的問題)

  3. 數(shù)據(jù)不一致拔妥。在二階段提交的階段二中,當(dāng)協(xié)調(diào)者向參與者發(fā)送commit請(qǐng)求之后达箍,發(fā)生了局部網(wǎng)絡(luò)異趁涣或者在發(fā)送commit請(qǐng)求過程中協(xié)調(diào)者發(fā)生了故障,這回導(dǎo)致只有一部分參與者接受到了commit請(qǐng)求缎玫。而在這部分參與者接到commit請(qǐng)求之后就會(huì)執(zhí)行commit操作硬纤。但是其他部分未接到commit請(qǐng)求的機(jī)器則無法執(zhí)行事務(wù)提交。于是整個(gè)分布式系統(tǒng)便出現(xiàn)了數(shù)據(jù)部一致性的現(xiàn)象赃磨。

  4. 二階段無法解決的問題:協(xié)調(diào)者再發(fā)出commit消息之后宕機(jī)筝家,而唯一接收到這條消息的參與者同時(shí)也宕機(jī)了。那么即使協(xié)調(diào)者通過選舉協(xié)議產(chǎn)生了新的協(xié)調(diào)者邻辉,這條事務(wù)的狀態(tài)也是不確定的溪王,沒人知道事務(wù)是否被已經(jīng)提交。

TCC

補(bǔ)償性事務(wù)大致含義是值骇,"補(bǔ)償是一個(gè)獨(dú)立的支持ACID特性的本地事務(wù)在扰,用于在邏輯上取消服務(wù)提供者上一個(gè)ACID事務(wù)造成的影響,對(duì)于一個(gè)長(zhǎng)事務(wù)(long-running transaction)雷客,與其實(shí)現(xiàn)一個(gè)巨大的分布式ACID事務(wù)芒珠,不如使用基于補(bǔ)償性的方案,把每一次服務(wù)調(diào)用當(dāng)做一個(gè)較短的本地ACID事務(wù)來處理搅裙,執(zhí)行完就立即提交”皱卓。

confirm和cancel就是補(bǔ)償事務(wù),用于取消try階段本地事務(wù)造成的影響部逮。因?yàn)榈谝浑A段try只是預(yù)留資源娜汁,之后必須要明確的告訴服務(wù)提供者,這個(gè)資源你到底要不要兄朋,對(duì)應(yīng)第二階段的confirm/cancel掐禁。

可靠消息最終一致性

可靠消息最終一致性是指產(chǎn)生消息的業(yè)務(wù)動(dòng)作與消息發(fā)送的一致。也就是說颅和,如果業(yè)務(wù)操作成功傅事,那么由這個(gè)業(yè)務(wù)操作所產(chǎn)生的消息一定要成功投遞出去(一般是發(fā)送到kafka、rocketmq峡扩、rabbitmq等消息中間件中)蹭越,否則就丟消息。

阿里云提供的MQMNS兩種消息產(chǎn)品都支持事務(wù)型消息教届,將這個(gè)特性跟數(shù)據(jù)庫事務(wù)結(jié)合响鹃,可以實(shí)現(xiàn)基于可靠消息的最終一致性驾霜。

image.png
image.png

GTS

GTS是阿里云提供的全局事務(wù)服務(wù)。GTS 支持 DRDS买置、RDS粪糙、Oracle、MySQL忿项、PostgreSQL蓉冈、OceanBase 和 Petadata 等多種數(shù)據(jù)源,可以配合 EDAS倦卖、Dubbo 和 Spring Cloud 等微服務(wù)框架使用, 兼容 MQ 實(shí)現(xiàn)事務(wù)消息椿争。通過各種組合怕膛,可以輕松實(shí)現(xiàn)分布式數(shù)據(jù)庫事務(wù)、多庫事務(wù)秦踪、消息事務(wù)褐捻、服務(wù)鏈路級(jí)事務(wù)等多種業(yè)務(wù)需求。

針對(duì)不同的應(yīng)用場(chǎng)景椅邓,GTS 主要提供標(biāo)準(zhǔn)模式(AT)和自定義模式(MT)兩種事務(wù)模式柠逞。AT模式會(huì)依賴數(shù)據(jù)庫,用戶需要?jiǎng)?chuàng)建txc_undo_log表景馁。MT模式更像TCC板壮,用戶需要自己實(shí)現(xiàn)兩階段提交的邏輯。

AT 模式

AT 模式是 GTS 最主要的事務(wù)模式合住,通過 GTS 基于 DRDS/RDS 的數(shù)據(jù)源绰精,對(duì) SQL 語句提供分布式事務(wù)支持。它幫助應(yīng)用方以最小的改造代價(jià)來實(shí)現(xiàn)數(shù)據(jù)庫的事務(wù)功能透葛。

AT 模式適合于 DRDS 分庫分表笨使、多數(shù)據(jù)庫數(shù)據(jù)源、跨進(jìn)程的多數(shù)據(jù)庫數(shù)據(jù)源等幾乎任何 DRDS 應(yīng)用場(chǎng)景下的分布式事務(wù)僚害。

MT 模式

MT模式提供用戶可以介入兩階段提交過程的一種模式硫椰。在這種模式下,用戶可以根據(jù)自身業(yè)務(wù)需求自定義在 GTS 的兩階段中每個(gè)階段的具體行為萨蚕。MT 模式提供了更多的靈活性靶草,可能性,以達(dá)到特殊場(chǎng)景下的自定義優(yōu)化岳遥,及特殊功能的實(shí)現(xiàn)爱致。

MT 模式不依賴于數(shù)據(jù)庫,這是它相對(duì)于 AT 模式的一個(gè)最大的優(yōu)勢(shì)寒随。MT 模式幾乎滿足任何事務(wù)場(chǎng)景糠悯。

樣例

GTS提供了豐富的樣例幫助大家理解產(chǎn)品的原理和使用帮坚。

基于消息的最終一致性

sample-txc-mq這個(gè)例子使用MQ實(shí)現(xiàn)的最終一致性。循環(huán)轉(zhuǎn)賬十次互艾,前五次會(huì)成功试和,后五次會(huì)因?yàn)橛囝~不足而失敗。

[root@izuf60wa1jflm222pngldrz bin]# ./run.sh 
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
JM.Log:INFO Init JM logger with Slf4jLoggerFactory success, sun.misc.Launcher$AppClassLoader@4617c264
JM.Log:INFO Log root path: /root/logs/
JM.Log:INFO Set txc log path: /root/logs/txc
JM.Log:INFO Set diamond-client log path: /root/logs/diamond-client
client mode:3 [0:None (only be client) 1:Default Mode 2:Manual Mode 3:Default Mode & Manual Mode 5:Default Mode & Service Mode 6:Manual Mode & Service Mode 7:Default Mode & Manual Mode &Service Mode]
txcAppName:gts_henshao_test.1162142976628250.SH
txcServerGroup:gts_henshao_test.1162142976628250.SH
Sat Dec 15 15:56:46 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Sat Dec 15 15:56:46 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Producer started!

Sat Dec 15 15:56:46 CST 2018
send msgId:AC139F2C46554617C26448F1D3960000 status:SEND_OK broker:shanghaishare-10 qid:0, topic:mq_henshao_test
A的中間狀態(tài)為:80元
本次轉(zhuǎn)賬結(jié)束纫普,A和B的余額為:
A賬戶現(xiàn)在余額為80元
B賬戶現(xiàn)在余額為120元
A和B的金額總和為200元

Sat Dec 15 15:56:47 CST 2018
Sat Dec 15 15:56:48 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Sat Dec 15 15:56:48 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
send msgId:AC139F2C46554617C26448F1D6BC0003 status:SEND_OK broker:shanghaishare-10 qid:0, topic:mq_henshao_test
A的中間狀態(tài)為:60元
本次轉(zhuǎn)賬結(jié)束阅悍,A和B的余額為:
A賬戶現(xiàn)在余額為60元
B賬戶現(xiàn)在余額為140元
A和B的金額總和為200元

Sat Dec 15 15:56:48 CST 2018
send msgId:AC139F2C46554617C26448F1D9D10006 status:SEND_OK broker:shanghaishare-10 qid:0, topic:mq_henshao_test
A的中間狀態(tài)為:40元
本次轉(zhuǎn)賬結(jié)束,A和B的余額為:
A賬戶現(xiàn)在余額為40元
B賬戶現(xiàn)在余額為160元
A和B的金額總和為200元

Sat Dec 15 15:56:49 CST 2018
send msgId:AC139F2C46554617C26448F1DA7E0009 status:SEND_OK broker:shanghaishare-10 qid:0, topic:mq_henshao_test
A的中間狀態(tài)為:20元
本次轉(zhuǎn)賬結(jié)束昨稼,A和B的余額為:
A賬戶現(xiàn)在余額為20元
B賬戶現(xiàn)在余額為180元
A和B的金額總和為200元

Sat Dec 15 15:56:49 CST 2018
send msgId:AC139F2C46554617C26448F1DAFE000C status:SEND_OK broker:shanghaishare-10 qid:0, topic:mq_henshao_test
A的中間狀態(tài)為:0元
本次轉(zhuǎn)賬結(jié)束节视,A和B的余額為:
A賬戶現(xiàn)在余額為0元
B賬戶現(xiàn)在余額為200元
A和B的金額總和為200元

Sat Dec 15 15:56:49 CST 2018
send msgId:AC139F2C46554617C26448F1DB80000F status:SEND_OK broker:shanghaishare-11 qid:0, topic:mq_henshao_test
A的中間狀態(tài)為:-20元
not enough money. 回滾到事務(wù)前狀態(tài)
本次轉(zhuǎn)賬結(jié)束,A和B的余額為:
A賬戶現(xiàn)在余額為0元
B賬戶現(xiàn)在余額為200元
A和B的金額總和為200元

Sat Dec 15 15:56:50 CST 2018
send msgId:AC139F2C46554617C26448F1DCF60012 status:SEND_OK broker:shanghaishare-11 qid:0, topic:mq_henshao_test
A的中間狀態(tài)為:-20元
not enough money. 回滾到事務(wù)前狀態(tài)
本次轉(zhuǎn)賬結(jié)束假栓,A和B的余額為:
A賬戶現(xiàn)在余額為0元
B賬戶現(xiàn)在余額為200元
A和B的金額總和為200元

Sat Dec 15 15:56:50 CST 2018
send msgId:AC139F2C46554617C26448F1DDC20015 status:SEND_OK broker:shanghaishare-11 qid:0, topic:mq_henshao_test
A的中間狀態(tài)為:-20元
not enough money. 回滾到事務(wù)前狀態(tài)
本次轉(zhuǎn)賬結(jié)束寻行,A和B的余額為:
A賬戶現(xiàn)在余額為0元
B賬戶現(xiàn)在余額為200元
A和B的金額總和為200元

Sat Dec 15 15:56:50 CST 2018
send msgId:AC139F2C46554617C26448F1DE870018 status:SEND_OK broker:shanghaishare-11 qid:0, topic:mq_henshao_test
A的中間狀態(tài)為:-20元
not enough money. 回滾到事務(wù)前狀態(tài)
本次轉(zhuǎn)賬結(jié)束,A和B的余額為:
A賬戶現(xiàn)在余額為0元
B賬戶現(xiàn)在余額為200元
A和B的金額總和為200元

Sat Dec 15 15:56:50 CST 2018
send msgId:AC139F2C46554617C26448F1DF75001B status:SEND_OK broker:shanghaishare-11 qid:0, topic:mq_henshao_test
A的中間狀態(tài)為:-20元
not enough money. 回滾到事務(wù)前狀態(tài)
本次轉(zhuǎn)賬結(jié)束匾荆,A和B的余額為:
A賬戶現(xiàn)在余額為0元
B賬戶現(xiàn)在余額為200元
A和B的金額總和為200元
wait for several seconds  ------------------
checking result --------------------
A原來來有100元拌蜘,現(xiàn)在為0元
B原來來有100元,現(xiàn)在為200元
A和B的金額總和為200元

三個(gè)分支事務(wù)分別是兩個(gè)數(shù)據(jù)庫牙丽,一個(gè)MQ消息简卧。

image.png

去MQ里面可以看到一共發(fā)送了五條消息,失敗的五條是看不到的烤芦。

image.png

預(yù)留和補(bǔ)償事務(wù)

MT模式的兩個(gè)例子举娩,預(yù)留事務(wù)是在rollin的時(shí)候預(yù)留資源,commitRollin的時(shí)候操作資源及刪除分支事務(wù)的數(shù)據(jù)构罗。補(bǔ)償事務(wù)則是在rollin的時(shí)候就操作資源晓铆,commitRollin的時(shí)候只刪除分支事務(wù)的數(shù)據(jù)。

參考資料

  1. MySQL 中基于 XA 實(shí)現(xiàn)的分布式事務(wù)
  2. GTS解密--GTS的原理绰播、架構(gòu)與特點(diǎn)
  3. 阿里P8架構(gòu)師談:分布式事務(wù)的特征骄噪、原理、以及常見3種解決方案
  4. 分布式事務(wù)
  5. 全局事務(wù)服務(wù) GTS
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蠢箩,一起剝皮案震驚了整個(gè)濱河市链蕊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谬泌,老刑警劉巖滔韵,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異掌实,居然都是意外死亡陪蜻,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門贱鼻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宴卖,“玉大人滋将,你說我怎么就攤上這事≈⒒瑁” “怎么了随闽?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)肝谭。 經(jīng)常有香客問我掘宪,道長(zhǎng),這世上最難降的妖魔是什么攘烛? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任魏滚,我火速辦了婚禮,結(jié)果婚禮上坟漱,老公的妹妹穿的比我還像新娘鼠次。我一直安慰自己,他們只是感情好靖秩,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布须眷。 她就那樣靜靜地躺著竖瘾,像睡著了一般沟突。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捕传,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天惠拭,我揣著相機(jī)與錄音,去河邊找鬼庸论。 笑死职辅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的聂示。 我是一名探鬼主播域携,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼鱼喉!你這毒婦竟也來了秀鞭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤扛禽,失蹤者是張志新(化名)和其女友劉穎锋边,沒想到半個(gè)月后丁存,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奈揍,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡破衔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年轧铁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了兵拢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缎讼,死狀恐怖澎语,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瓤球,我是刑警寧澤融欧,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站卦羡,受9級(jí)特大地震影響噪馏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜绿饵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一欠肾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拟赊,春花似錦刺桃、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至屋匕,卻和暖如春葛碧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背过吻。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工进泼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纤虽。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓乳绕,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親逼纸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子洋措,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

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