sonar

Sonar簡(jiǎn)介


Sonar是一個(gè)用于代碼質(zhì)量管理的開源平臺(tái),用于管理源代碼的質(zhì)量在扰,可以從七個(gè)維度檢測(cè)代碼質(zhì)量


通過插件形式缕减,可以支持包括java,C#,C/C++,PL/SQL,Cobol,JavaScrip,Groovy等等二十幾種編程語言的代碼質(zhì)量管理與檢測(cè)


Sonar是從七個(gè)維度檢測(cè)代碼質(zhì)量,而作為開發(fā)人員至少需要處理前5中代碼質(zhì)量問題桥狡。


sonarQube能帶來什么?

?

1沒有代碼標(biāo)準(zhǔn),不遵循代碼標(biāo)準(zhǔn) sonar可以通過PMD,CheckStyle,Findbugs等等代碼規(guī)則檢測(cè)工具規(guī)范代碼編寫


2潛在的bug,潛在的缺陷? sonar可以通過PMD,CheckStyle,Findbugs等等代碼規(guī)則檢測(cè)工具檢測(cè)出潛在的bug


3糟糕的復(fù)雜度分布? 文件裹芝、類娜汁、方法等,如果復(fù)雜度過高將難以改變存炮,這會(huì)使得開發(fā)人員難以理解它們蜈漓,且如果沒有自動(dòng)化的單元測(cè)試宫盔,對(duì)于程序中的任何組件的改變都將可能導(dǎo)致需要全面的回歸測(cè)試


4重復(fù) 顯然程序中包含大量復(fù)制粘貼的代碼是質(zhì)量低下的,sonar可以展示源碼中重復(fù)嚴(yán)重的地方


5沒有足夠的或者過多的注釋 沒有注釋將使代碼可讀性變差融虽,特別是當(dāng)不可避免地出現(xiàn)人員變動(dòng)時(shí)灼芭,程序的可讀性將大幅下降,而過多的注釋又會(huì)使得開發(fā)人員將精力過多地花費(fèi)在閱讀注釋上

?

6缺乏單元測(cè)試 sonar可以很方便地統(tǒng)計(jì)并展示單元測(cè)試覆蓋率


7糟糕的設(shè)計(jì)(原文Spaghetti Design,意大利面式設(shè)計(jì))? 通過sonar可以找出循環(huán)彼绷,展示包與包、類與類之間的相互依賴關(guān)系? 可以檢測(cè)自定義的架構(gòu)規(guī)則? 通過sonar可以管理第三方的jar包? 可以利用LCOM4檢測(cè)單個(gè)任務(wù)規(guī)則的應(yīng)用情況? 檢測(cè)耦合




tips:PMD萤衰,CheckStyle猜旬,F(xiàn)indbugs這些工具都叫靜態(tài)代碼分析工具脆栋。什么是靜態(tài)代碼分析洒擦?靜態(tài)代碼分析是指無需運(yùn)行被測(cè)代碼,僅通過分析或檢查源程序的語法熟嫩、結(jié)構(gòu)、接口等來檢查程序的正確性掸茅,找出代碼隱藏的錯(cuò)誤或缺陷,如參數(shù)不匹配希坚,有歧義的嵌套語句,錯(cuò)誤的遞歸,非法計(jì)算个束,空指針引用等。


Checkstyle


Checkstyle是一個(gè)開源工具茬底,可以幫助實(shí)施編碼標(biāo)準(zhǔn)和最佳實(shí)踐,特別注重編碼慣例殿如。


雖然Checkstyle涵蓋了一些靜態(tài)代碼分析功能(與PMD和Findbug的方式大致相同)贡珊,但是我們將主要在Checkstyle檢測(cè)和執(zhí)行編碼編寫規(guī)范


PMD

PMD是一種靜態(tài)代碼分析工具涉馁,能夠自動(dòng)檢測(cè)范圍很廣的潛在缺陷和不安全或非優(yōu)化的代碼(不良做法)。 而其他工具(如Checkstyle)可以檢查編碼約定(規(guī)范)和標(biāo)準(zhǔn)寒随,PMD更側(cè)重于缺陷檢測(cè)(確保遵循良好做法)。 它附帶了豐富且高度可配置的規(guī)則集妻往,可以輕松地配置給定項(xiàng)目應(yīng)使用哪些特定規(guī)則试和。


例如:

捕捉異常而不做任何事情

死循環(huán)代碼

太多復(fù)雜的方法

直接使用實(shí)現(xiàn)而不是接口

實(shí)現(xiàn)或重寫了hashcode()沒有實(shí)現(xiàn)或重寫equals(Object object)方法

返回對(duì)可變對(duì)象的引用可能會(huì)對(duì)外暴露內(nèi)部實(shí)現(xiàn)



Findbug


Findbug是Java的另一個(gè)靜態(tài)分析工具讯泣,在某些方面類似于Checkstyle和PMD阅悍,但是具有不同的重點(diǎn)。


Findbug不關(guān)心格式化或編碼標(biāo)準(zhǔn)晦墙,它的目標(biāo)是檢測(cè)潛在的錯(cuò)誤和性能問題。它很擅長(zhǎng)做這類檢查晌畅」烟担可以檢測(cè)到許多常見但難以發(fā)現(xiàn)的錯(cuò)誤抗楔。


Findbug能夠以比較高的精度檢測(cè)出與PMD或Checkstyle不同的問題拦坠。 因此,它可以是一個(gè)有用的補(bǔ)充贞滨。


為什么要選擇sonarQube?

到目前為止

沒有哪個(gè)CI工具可以提供良好的鉆取功能勺良。

沒有CI插件可以將所有的軟件質(zhì)量的度量數(shù)據(jù)整合到一起。

沒有CI插件提供管理視角尚困。

沒有設(shè)計(jì)/架構(gòu)問題相關(guān)的CI插件

沒有CI工具或插件提供整體項(xiàng)目質(zhì)量的儀表盤链蕊。


但是sonarQube都有事甜,而且相比于阿里編碼規(guī)約這種市面上常見類似軟件,能提供但不限如下優(yōu)點(diǎn)

1更加優(yōu)秀的圖形化界面掌实,基本上通過界面就可以對(duì)自己項(xiàng)目的代碼狀況一目了然


2可以查詢出其它軟件難以定位到的問題

a可能導(dǎo)致空指針異常的問題 (對(duì)象在進(jìn)行使用前沒有加空的判斷) ??????

b可能導(dǎo)致內(nèi)存泄漏的問題, 在try catch 塊里面,直接使用e.printStackTrace()將堆棧 信息打印到內(nèi)存的

c可能導(dǎo)致的漏洞跨跨,成員變量使用public定義的

d流等未關(guān)閉或者是非正常關(guān)閉都能夠檢測(cè)出來

............



Sonar組成

sonarqube系統(tǒng)是一個(gè)代碼質(zhì)量檢測(cè)工具 由以下四個(gè)組件組成

1一個(gè)sonarqube服務(wù)器,包含三個(gè)子進(jìn)程(web服務(wù)(界面管理)勇婴,搜索服務(wù),計(jì)算引擎服務(wù) (寫入數(shù)據(jù)庫))

2一個(gè)sonarqube數(shù)據(jù)庫耕渴,配置sonarqube服務(wù)? ?

3多個(gè)sonarqube插件,位于解壓目錄extensions\plugins目錄? ?

4一個(gè)或者多個(gè)sonarqube scanners用于分析特定的項(xiàng)目础米,相當(dāng)于客戶端


?

Sonar工作流程

通過客戶端插件分析源代碼,sonar客戶端可以采用IDE插件屁桑、Sonar-Scanner插件栏赴、Ant插件和Maven插件方式蘑斧,并通過各種不同的分析機(jī)制對(duì)項(xiàng)目源代碼進(jìn)行分析和掃描须眷,并把分析掃描后的結(jié)果上傳到sonar的數(shù)據(jù)庫,通過sonar web界面對(duì)分析結(jié)果進(jìn)行管理

?

?

Sonar安裝前準(zhǔn)備

要求:

Centos7, jdk8捕传,mysql 5.6-5.7, sonarqube-6.7.6(LTS)

請(qǐng)先確保linux已經(jīng)安裝了jdk8,并且已經(jīng)配置好了環(huán)境變量

tips:Sonar是基于Java開發(fā)的庸论,因此運(yùn)行Sonar自然需要JDK


Sonar安裝前準(zhǔn)備

CentOS中默認(rèn)安裝有MariaDB棒呛,這個(gè)是MySQL的分支葡公,但為了需要条霜,還是要在系統(tǒng)中安裝MySQL涵亏,而且安裝完成之后可以直接覆蓋掉MariaDB蒲凶。


1下載YUM源(http://dev.mysql.com/downloads/repo/yum/)


wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm


2安裝mysql源

yum localinstall mysql57-community-release-el7-8.noarch.rpm


3檢查mysql源是否安裝成功

yum repolist enabled | grep "mysql.*-community.*"



安裝MySQL

yum install mysql-community-server

啟動(dòng)Mysql服務(wù)

systemctl start mysqld


根據(jù)自己需求是否設(shè)置開機(jī)自啟動(dòng)

systemctl enable mysqld

systemctl daemon-reload

修改root本地登錄密碼拆内,mysql安裝完成之后,在/var/log/mysqld.log文件中給root生成了一個(gè)默認(rèn)

密碼麸恍。通過下面的方式找到root默認(rèn)密碼,然后登錄mysql進(jìn)行修改:

grep 'temporary password' /var/log/mysqld.log

mysql -uroot–p

ALTER USER 'root'@'localhost' IDENTIFIED BY '123';

tips:mysql5.7默認(rèn)安裝了密碼安全檢查插件(validate_password)刻肄,默認(rèn)密碼檢查策略要求密碼必須包含:

大小寫字母、數(shù)字和特殊符號(hào)敏弃,并且長(zhǎng)度不能少于8位噪馏。修改策略之后再執(zhí)行修改密碼

1 set global validate_password_policy=0;

2 set global validate_password_policy=LOW;

Sonar要求mysql必須是InnoDB存儲(chǔ)引擎

1查看mysql目前是什么存儲(chǔ)引擎

mysql ?-u root–p 先登錄mysql

????show engines; 查看mysql目前提供的存儲(chǔ)引擎

如果不是InnoDB麦到,設(shè)置為InnoDB欠肾,修改配置文件/etc/my.cnf

vi /etc/my.cnf

[mysqld]

default-storage-engine=INNODB

重啟mysql數(shù)據(jù)庫,再次登錄查看默認(rèn)存儲(chǔ)引擎設(shè)置是否生效

service mysqld restart

設(shè)置mysql緩存參數(shù)

a設(shè)置innodb_buffer_pool_size,參數(shù)值設(shè)置盡可能大一些刺桃,這個(gè)參數(shù)主要是緩存InnoDB表的索引,數(shù)據(jù)廓啊,插入數(shù)據(jù)時(shí)的緩沖

默認(rèn)值:128M,我們這里設(shè)置為256M

b設(shè)置mysql的查詢緩存quert_cache_size的開關(guān)為1谴轮,然后設(shè)置最少15M吹埠,重啟mysql數(shù)據(jù)庫

查看緩存設(shè)置是否生效

show variables like '%query_cache%';



1在mysql中新建一個(gè)sonarQube數(shù)據(jù)庫(UTF-8編碼)


2從官網(wǎng)下載最新LTS版本的sonarQuba安裝包(sonarqube-6.7.6.zip)

a linux命令行下執(zhí)行下載:

wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-6.7.6.zip注:網(wǎng)絡(luò)不是太好翻墻才下載下來

解壓安裝并更名

unzip sonarqube-6.7.6.zip

mv sonarqube-6.7.6 sonarQube


之前介紹組成的時(shí)候說sonarqube是sonar的服務(wù)端,相當(dāng)于一個(gè)web服務(wù)器缘琅,用來發(fā)布應(yīng)用,在線瀏覽翩隧、配置分析等。怎么樣堆生?有沒有很面熟的感覺专缠?是不是有點(diǎn)像tomcat呢淑仆?

bin:sonarqube運(yùn)行命令文件夾? ?

conf:sonarqube配置文件夾? ?

data:嵌入式數(shù)據(jù)庫的數(shù)據(jù)(H2數(shù)據(jù)庫引擎),建議只用于測(cè)試和演示? ?

elasticsearch:搜索引擎

extensions:sonarqube的插件等存放文件夾? ?

lib:sonarqube存放的運(yùn)行庫文件夾(jar)? ?

logs:sonarqube日志文件夾? ?

temp:sonarqube臨時(shí)文件夾? ?

web:sonarqube系統(tǒng)UI界面文件夾


編輯sonar配置

cd sonarQube/conf/

vi sonar.properties


Mysql數(shù)據(jù)用戶名

sonar.jdbc.username=root

sonar.jdbc.password=5462837zhu


配置mysql數(shù)據(jù)庫

sonar.jdbc.url=jdbc:mysql://localhost:3306/sonarQube?useUnicode=true&characterEncodixxxx

設(shè)置sonar服務(wù)

sonar.web.host=0.0.0.0

sonar.web.context=/sonarQube

sonar.web.port=9000



啟動(dòng)sonarQube web service墩弯,第一次啟動(dòng)會(huì)自動(dòng)在數(shù)據(jù)庫生成所需的表,可進(jìn)入數(shù)據(jù)庫查看下


sh sonar.sh start

瀏覽器中輸入:http://192.168.1.149:9000/sonarQube



Sonar安裝注意的坑

由于6.6版本加入了elasticsearch渔工,不能以root用戶啟動(dòng)怠惶,因?yàn)榘踩珕栴}elasticsearch

不讓用root用戶直接運(yùn)行,所以要?jiǎng)?chuàng)建新用戶策治,用新用戶啟動(dòng)


//創(chuàng)建esuser用戶

//目錄組和用戶都是esuser

//sonarqube文件設(shè)置777 //編寫配置文件

# useradd esuser

# chown -R esuser.esuser sonar6.7.6

# chmod 777 -R sonarqube-6.7.5

# vi sonar6.7.6/sonarQube/elasticsearch/config/elasticsearch.yml


//開啟端口和指定服務(wù)

network.host: 192.168.1.149(請(qǐng)?zhí)顚懽约悍?wù)器的ip)

http.port: 9200


如果啟動(dòng)中出現(xiàn)錯(cuò)誤:如:

max file descriptors [4096] for elasticsearch process likely too low, increase to at least [65536]

max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144]


解決65536:

切換到root用戶,進(jìn)入limits.d目錄下修改配置文件茂翔。

vi /etc/security/limits.conf?

添加如下內(nèi)容:

* soft nofile 65536

* hard nofile 131072

* soft nproc 2048

* hard nproc 4096


解決262144:

切換到root用戶修改配置sysctl.conf

vi /etc/sysctl.conf?

添加下面配置:

vm.max_map_count=655360

并執(zhí)行命令:

sysctl–p


Sonar web下載漢化包

帳號(hào)密碼默認(rèn)都為:admin,登錄之后下載中文漢化包珊燎,然后重啟sonarQube:sh sonar.sh restart



大家現(xiàn)在常用的都是谷歌瀏覽器可以直接翻譯不需要漢化也可以


使用SonarQube Scanner分析代碼


1從官網(wǎng)下載scanner對(duì)應(yīng)的版本后直接解壓 :

??????https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner


2通過編輯xxxx/conf/sonar-scanner.properties更新全局設(shè)置以指向SonarQube服務(wù)器??:


sonar.host.url = http://192.168.1.149:9000/sonarQube

將xxxx/bin設(shè)置到環(huán)境變量PATH中

在命令行輸入sonar-scanner –h遵湖,驗(yàn)證安裝結(jié)果

INFO:

INFO: usage: sonar-scanner [options]

INFO:

INFO: Options:

INFO: ?-D,--define <arg> ????Define property

INFO: ?-h,--help ????????????Display help information

INFO: ?-v,--version ?????????Display version information

INFO: ?-X,--debug ???????????Produce execution debug


使用SonarQube Scanner分析代碼


在需要分析的項(xiàng)目根目錄中創(chuàng)建配置文件:sonar-project.properties


#當(dāng)前項(xiàng)目實(shí)例的唯一表示

sonar.projectKey=kafka

#顯示在sonarqube 界面上的項(xiàng)目名稱

sonar.projectName=kafka

sonar.projectVersion=1.0


#相對(duì)于當(dāng)前配置文件目錄 下的源代碼目錄 不管什么平臺(tái)路徑分隔符只能有 ?/ 不能使用\

sonar.sources=src/main/java


#源代碼的字符集

#sonar.sourceEncoding=UTF-8


從需要分析的項(xiàng)目根目錄運(yùn)行以下命令以啟動(dòng)分析,出現(xiàn)執(zhí)行EXECUTION SUCCESS表示成功

…………………….

INFO: Task total time: 9.250

INFO: -----------------------

INFO: EXECUTION SUCCESS

INFO: -----------------------

INFO: Total time: 15.389s

INFO: Final Memory: 17M/326M

登錄sonarQube Web查看結(jié)果


使用SonarQube Maven插件分析代碼


編輯位于$MAVEN_HOME/conf或?/ .m2中的settings.xml文件延旧,設(shè)置SonarQube服務(wù)器URL。

<profile>

????????????<id>sonar</id>

????????????<activation>

<activeByDefault>true</activeByDefault>

????????????</activation>

????????????<properties>

<sonar.host.url>http://192.168.1.149:9000/sonarQube</sonar.host.url>

</properties>

</profile>

分析Maven項(xiàng)目芦瘾,運(yùn)行Maven目標(biāo):sonar:sonar在pom.xml文件所在的目錄中

mvn sonar:sonar




登錄sonarQube Web查看結(jié)果








可以詳細(xì)查看每個(gè)bug的具體問題描述 以及在stackoverflow中存在并推薦的標(biāo)準(zhǔn)解決方案,可以分配給具體用戶進(jìn)行跟進(jìn)解決



簡(jiǎn)介SonarQube Web使用



1質(zhì)量閥

SonarQube Web管理者通過配置和設(shè)置以下參數(shù)值對(duì)項(xiàng)目源代碼進(jìn)行:

復(fù)雜度近弟、覆蓋率挺智、文檔祷愉、重復(fù)、問題谣辞、可維護(hù)性、可靠性、安全性沪摄、大小等約束和規(guī)范。

2配置

系統(tǒng):系統(tǒng)信息

應(yīng)用市場(chǎng):下載杨拐,更新,卸載插件

項(xiàng)目:創(chuàng)建哄陶、編輯、修改屋吨、刪除(批量)SonarQube項(xiàng)目,查看分析記錄

權(quán)限:新建用戶組至扰,用戶,角色敢课,設(shè)置角色到項(xiàng)目,以及提供一些默認(rèn)的角色模版

配置:Java:配置檢查的java源文件及靜態(tài)代碼檢查規(guī)范檢查?

SCM:配置軟件控制器濒募。上文已經(jīng)提到的配置項(xiàng)。比如:svn瑰剃、git等等?

設(shè)置數(shù)據(jù)庫清理疫稿,界面等等

3質(zhì)量配置

查看目前支持的語言插件宁赤,查看插件配置的規(guī)則,新建規(guī)則配置項(xiàng)


4代碼規(guī)則

查看各個(gè)語言提供的規(guī)則扼仲,分配規(guī)則到配置項(xiàng)等

5問題

查看每個(gè)項(xiàng)目分析出來的問題,查看問題等

6項(xiàng)目

查看各個(gè)項(xiàng)目的問題總數(shù)等




?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子梯醒,更是在濱河造成了極大的恐慌,老刑警劉巖茸习,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件壁肋,死亡現(xiàn)場(chǎng)離奇詭異号胚,居然都是意外死亡浸遗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門跛锌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人髓帽,你說我怎么就攤上這事∏饪ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵峡捡,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我们拙,道長(zhǎng),這世上最難降的妖魔是什么砚婆? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任突勇,我火速辦了婚禮装盯,結(jié)果婚禮上甲馋,老公的妹妹穿的比我還像新娘。我一直安慰自己定躏,他們只是感情好芹敌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布垮抗。 她就那樣靜靜地躺著氏捞,像睡著了一般冒版。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辞嗡,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音欲间,去河邊找鬼断部。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蝴光,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蔑祟,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼苛败!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起径簿,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缠捌,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體曼月,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柔昼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了岳锁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹦魔。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡咳燕,死狀恐怖勿决,靈堂內(nèi)的尸體忽然破棺而出招盲,到底是詐尸還是另有隱情,我是刑警寧澤曹货,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站顶籽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏礼饱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一镊绪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蝴韭,春花似錦、人聲如沸榄鉴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至减余,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間位岔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工杨刨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人妖胀。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓芥颈,卻偏偏與公主長(zhǎng)得像赚抡,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子涂臣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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