關(guān)于微服務(wù)(Micro Services)

1禾蚕、什么是微服務(wù)?

微服務(wù)真沒那么神秘获诈, 其實(shí)它也就是一種SOA的演化形式, 而且他更加側(cè)重于在服務(wù)的物理結(jié)構(gòu)層面進(jìn)行細(xì)分演化心褐, 你可以理解為舔涎,微服務(wù)其實(shí)是指引服務(wù)的具體落地方案層面的一種實(shí)踐方式, 而SOA實(shí)際上更側(cè)重于相關(guān)的原則(Principle)或者理念逗爹。

SOA的概念大家都知道亡嫌, SOA的思想大家或許也都會認(rèn)為自己領(lǐng)會的很好, 可是桶至, 自己認(rèn)為領(lǐng)會了昼伴,跟你領(lǐng)會的SOA思想最終能否指導(dǎo)你以比較好的方式來實(shí)踐,這之間可能還有很長的一段距離镣屹。

一般項(xiàng)目構(gòu)建是介個(gè)樣子的圃郊,需要幫助業(yè)務(wù)線技術(shù)團(tuán)隊(duì)梳理各方面的關(guān)注點(diǎn)并解決相應(yīng)的問題和瓶頸, 其中一個(gè)場景是女蜈, 團(tuán)隊(duì)發(fā)布經(jīng)常延期持舆,而且很容易出事故, 一開始以為只是SCM之類實(shí)踐方式有待改進(jìn)伪窖,真的鉆下去看工程和代碼才發(fā)現(xiàn)真正的問題之所在逸寓。

我發(fā)現(xiàn), 業(yè)務(wù)線的projects是根據(jù)邏輯層來設(shè)置的覆山, 類似于:

* func-web(project)

* func-serivces(project)

* func-dao(project)

* func-utils(project)

* ...

有沒有覺得很匪夷所思竹伸?! 其實(shí)一點(diǎn)兒也不用匪夷所思簇宽,我想在很多團(tuán)隊(duì)中也有可能存在這種現(xiàn)象(那些悶聲發(fā)大財(cái)使用SOA很多年的公司現(xiàn)在是不是對此很不屑勋篓?), 為什么那魏割? 因?yàn)槿绻銢]有真正理解SOA的理念譬嚣,或者你缺少一些正確的指引,只能自己摸著石頭過河钞它,那么你就是會做出這樣的實(shí)踐方式拜银,要知道SOA更多強(qiáng)調(diào)的是邏輯上的理念, 而分層架構(gòu)恰好又是提到的最多的架構(gòu)邏輯上的典范遭垛, 自然而然的尼桶,按照分層(layers)將項(xiàng)目劃分為如上結(jié)構(gòu),也就很是“自然”了耻卡!

但是疯汁,這樣設(shè)置項(xiàng)目結(jié)構(gòu)所帶來的影響卻是:

開發(fā)一個(gè)功能,我不得不在多個(gè)project之間“輾轉(zhuǎn)騰挪”卵酪;

要發(fā)布和部署幌蚊, 我首先需要等待并確認(rèn)所有功能代碼都測試通過待發(fā)布,然后再將包括了所有待發(fā)布功能的這些project一起打包發(fā)布溃卡, 如果有一個(gè)功能沒有測試通過溢豆,不好意思,你就得等瘸羡,這其實(shí)也就是早年淘寶架構(gòu)師略顯自豪提的“火車模型”漩仙,你得等所有車廂都裝上才可以發(fā)車/發(fā)布;另外犹赖, 一旦我沒有對當(dāng)前發(fā)布基線要發(fā)布的所有功能進(jìn)行確認(rèn)就發(fā)布队他,只要有一個(gè)功能代碼沒提交完全,你發(fā)布就會失敗峻村,甚至發(fā)布了麸折,上線就出問題;

那么粘昨,我們要怎么打破這種窘境那垢啼?其實(shí)也很簡單, 以功能為劃分關(guān)注點(diǎn)的緯度進(jìn)行服務(wù)和項(xiàng)目的劃分张肾, 而各個(gè)服務(wù)在實(shí)現(xiàn)的時(shí)候要用到的各邏輯層的功能則納入服務(wù)自己的project中芭析, 現(xiàn)在的project結(jié)構(gòu)就變成了:

* func1(project)

- com.xxx.func1.controllers

- com.xxx.func1.services

- com.xxx.func1.dao

- com.xxx.func1.utils

- ...

* func2(project)

- com.xxx.func2.controllers

- com.xxx.func2.services

- com.xxx.func2.dao

- com.xxx.func2.utils

- ...

* func3(project)

- ...

* ...

現(xiàn)在這種落地方式(into the ground)帶來了哪些好的轉(zhuǎn)變那?

功能獨(dú)立開發(fā)和測試吞瞪,開發(fā)一個(gè)功能不要在多個(gè)project之間“輾轉(zhuǎn)騰挪”馁启,團(tuán)隊(duì)成員分工有明確分配的目標(biāo)指向,工作的目的project明確而單一芍秆,而原來你開發(fā)一個(gè)功能要同時(shí)面對多個(gè)project惯疙;

項(xiàng)目所關(guān)注的功能只要測試通過就可以直接發(fā)布,不需要等其它人(當(dāng)然浪听,并非絕對)螟碎,耦合更松散,大家可以獨(dú)立快跑迹栓;

但是掉分,到目前為止, 我們其實(shí)說的還是沒有跳出SOA的范疇克伊, 而且酥郭, 你的項(xiàng)目治理也不一定非要用我上面提到的這種方式, 說白了愿吹,我也只是給出了SOA的落地實(shí)踐方式之一不从, 有沒有其它方式那? SOA是核心犁跪, 但它的延伸卻可以很廣椿息, 這就帶來一個(gè)問題歹袁, 有些時(shí)候,選擇多了不一定就是好事寝优, 只有一種選擇有些時(shí)候反而會成為最有效的選擇条舔。

微服務(wù)是SOA的實(shí)踐方式之一, 如果你把它當(dāng)做你的唯一選擇乏矾,或許就成了當(dāng)下大部分的最佳選擇了孟抗。

為什么叫微服務(wù)? 一定是服務(wù)的粒度更細(xì)了钻心, 那么粒度更細(xì)是通過什么體現(xiàn)的那凄硼? 最直觀上的就是功能的物理結(jié)構(gòu), 比如具體到功能代碼組織的物理結(jié)構(gòu)捷沸,即project摊沉, 如果說原來你會把很多功能都放到一個(gè)project中進(jìn)行組織和開發(fā),那么亿胸,現(xiàn)在這些功能就應(yīng)該被進(jìn)一步打散到各自的project中進(jìn)行管理坯钦,每個(gè)功能作為微服務(wù)獨(dú)立被開發(fā), 測試侈玄, 發(fā)布婉刀,部署,使用和運(yùn)維序仙, 在整個(gè)軟件的交付鏈路上突颊, 一個(gè)個(gè)的微服務(wù)都是獨(dú)立的, 這其實(shí)就是微服務(wù)的本質(zhì)潘悼。

2律秃、為什么選擇微服務(wù)化?

選擇微服務(wù)化治唤,意味著你一定是要先接納SOA棒动,而選擇SOA,最根本的一個(gè)原因是你需要一種方式來管理整體的復(fù)雜度宾添, 請不要因果反調(diào)船惨, 因?yàn)橄窀鶕?jù)SOA的理念做了服務(wù)化之后,你的整體安全性更好了這樣的事情缕陕,其實(shí)是你選擇了服務(wù)化后所帶來的效果之一粱锐,而不是你為了加強(qiáng)系統(tǒng)的整體安全性才去選擇的SOA(當(dāng)然,排除少部分可能真的因?yàn)檫@種非核心功能因素而選擇走SOA)扛邑。

接納了SOA之后怜浅,進(jìn)而再選擇微服務(wù)化, 我認(rèn)為更多是為了提高軟件交付鏈路的整體效率蔬崩,為什么這么說那恶座?

其實(shí)選擇了微服務(wù)化搀暑,就意味著你發(fā)動了一場服務(wù)化大背景下的獨(dú)立戰(zhàn)爭, 每個(gè)服務(wù)都將獨(dú)立開發(fā)奥裸,獨(dú)立測試险掀,獨(dú)立發(fā)布沪袭,獨(dú)立部署湾宙,獨(dú)立運(yùn)維, 所帶來的好處就是冈绊,你可以直接而明確地分配團(tuán)隊(duì)或者個(gè)人對接一個(gè)個(gè)獨(dú)立的服務(wù)侠鳄,然后讓其負(fù)責(zé)這些服務(wù)的整個(gè)生命周期管理。

團(tuán)隊(duì)與團(tuán)隊(duì)之間死宣,成員與成員之間伟恶, 相互溝通和糾纏造成的損耗降低, 各自并行而異步的快速迭代毅该, 好一派熱火朝天的“創(chuàng)業(yè)浪潮”博秫, 處處迸射出活力與激情, 這或許就是大家選擇微服務(wù)的原因吧眶掌!

3挡育、微服務(wù)所帶來的挑戰(zhàn)

選擇了微服務(wù)化,確實(shí)可以帶來一系列的好處朴爬,但是即寒,也會對整個(gè)軟件交付鏈路造成一系列的沖擊!

3.1召噩、開發(fā)與測試

我們說母赵,微服務(wù)之后, 服務(wù)可以獨(dú)立開發(fā)和測試具滴, 團(tuán)隊(duì)或者成員之間可以并行快跑凹嘲, 這極大提高了系統(tǒng)的研發(fā)效率,但這也只是更多地關(guān)注了微服務(wù)個(gè)體內(nèi)部的好處构韵,可是微服務(wù)不是一個(gè)個(gè)的孤島周蹭,它依然需要跟外部的其它系統(tǒng)或者微服務(wù)打交道,這個(gè)時(shí)候贞绳,你就會發(fā)現(xiàn)戰(zhàn)場形勢變了...

首先谷醉,微服務(wù)化之后,微服務(wù)的數(shù)量極大增多了冈闭,原來一個(gè)monolith應(yīng)用俱尼,可能開發(fā)或者測試在自己的本機(jī)搭建一套環(huán)境就能進(jìn)行工作了, 可是現(xiàn)在萎攒, 如果你的一個(gè)微服務(wù)或者多個(gè)微服務(wù)依賴了n個(gè)其它微服務(wù)遇八,那么矛绘, 為了不影響開發(fā)和測試效率,你需要為開發(fā)和測試分別提供一套運(yùn)行環(huán)境刃永,在各自獨(dú)立的開發(fā)和測試環(huán)境中货矮,成百上千的微服務(wù)將持續(xù)運(yùn)行,以保障開發(fā)和測試工作的快速迭代斯够;

其次囚玫, 微服務(wù)雖然可以支持系統(tǒng)的多樣性(比如不同語言,不同架構(gòu))读规,但不意味著你一定要這樣做抓督,因?yàn)橐朐蕉嗟牟町愋砸蛩兀愕恼w交付鏈路上的復(fù)雜度就會呈指數(shù)級上升(微服務(wù)的數(shù)量 * 差異因素1 * 差異因素2 * ...差異因素n)束亏, 敢于發(fā)動微服務(wù)的獨(dú)立戰(zhàn)爭意味著你有足夠的資源和后勤保障铃在,但你還是要掂量一下在開戰(zhàn)之后這些資源保障是否經(jīng)得起進(jìn)一步的折騰?碍遍! 實(shí)際上定铜, 選擇了微服務(wù),就相當(dāng)于你選擇了企業(yè)戰(zhàn)略中的“成本優(yōu)先戰(zhàn)略”怕敬, 你在拼成本和產(chǎn)量揣炕,為了能夠批量生產(chǎn)又有盈利, 一個(gè)比較好的做法是標(biāo)準(zhǔn)化生產(chǎn)赖捌,即固定生產(chǎn)線祝沸,只提供標(biāo)品生產(chǎn), 只有少量的定制化生產(chǎn)越庇。 這種思路落到軟件研發(fā)的微服務(wù)戰(zhàn)略里就是罩锐, 標(biāo)準(zhǔn)化一個(gè)主要的技術(shù)棧(解決80%的主要問題), 只在特殊情況下允許少量的差異化生產(chǎn)(20%的特殊情況)卤唉。

最后涩惑, 我們講了,微服務(wù)不是一個(gè)個(gè)孤立的個(gè)體桑驱,他們之間依然需要通信從而形成一個(gè)整體的信息系統(tǒng)才會發(fā)揮其本身甚至更大的作用竭恬。 一般情況下,我們鼓勵(lì)使用HTTP熬的,但并非唯一的方式痊硕, 如果你的微服務(wù)真的沒有對性能有那么變態(tài)的需求, 選擇HTTP足夠了押框,而且多語言系統(tǒng)之間的互通也更容易岔绸, 只有那些對性能要求相對苛刻的服務(wù),才有必要考慮特定的方案和優(yōu)化方向。

3.2盒揉、發(fā)布和部署

微服務(wù)開發(fā)和測試之后接著就進(jìn)入了發(fā)布和部署晋被, 依然源于微服務(wù)的數(shù)量特征, 在發(fā)布和部署的時(shí)候刚盈, 有兩種可能的選擇:

一般的微服務(wù)都是標(biāo)準(zhǔn)化的打包發(fā)布和部署羡洛,所以, 即使沒有任何平臺性的支持藕漱, 開發(fā)或者對應(yīng)的應(yīng)用運(yùn)維團(tuán)隊(duì)依然可以根據(jù)自己負(fù)責(zé)的項(xiàng)目欲侮,采用各種手工或者自動化腳本的方式完成微服務(wù)的發(fā)布和部署;這種方式的好處是靈活谴分,壞處也很明顯锈麸, 很多東西可能無法復(fù)用,服務(wù)的注冊和治理沒有管控牺蹄;

為了管理海量的微服務(wù)的發(fā)布和部署,構(gòu)建發(fā)布和部署平臺薄翅, 完成微服務(wù)與整條鏈路上各系統(tǒng)和資源的映射管理和對接沙兰, 好處是即使微服務(wù)數(shù)量再多,我們也有一個(gè)集中管控的地方翘魄,壞處嘛鼎天, 發(fā)布和部署平臺可能成為瓶頸, 需要更強(qiáng)的質(zhì)量保障暑竟。

實(shí)際上斋射,如果你的公司或者研發(fā)團(tuán)隊(duì)不是很大的話,原則上你也不會選擇微服務(wù)戰(zhàn)略但荤,否則就是自討苦吃(為啥自己去想)罗岖; 一般都是成長型或者成熟的公司/團(tuán)隊(duì)才會選擇微服務(wù)化, 而成長型公司或者團(tuán)隊(duì)很多東西可能并沒有形成成熟的流程和規(guī)范腹躁,存在野蠻生長的特征桑包,這個(gè)時(shí)候, 往往他們會走在第一種選擇的路上纺非, 而成熟的公司或者團(tuán)隊(duì)如果第二種選擇還沒有達(dá)到哑了,那就太不應(yīng)該了。

總的來說烧颖,選擇了微服務(wù)化弱左, 就意味著不光研發(fā),整條鏈路上的基礎(chǔ)設(shè)施建設(shè)都需要跟上炕淮,而這就意味著要投入更多的資源保障拆火,瞧,打仗是需要底氣的!

我們說榜掌, 為了微服務(wù)的快速交付和迭代优妙,我們在開發(fā)階段選擇了標(biāo)準(zhǔn)化生產(chǎn), 到了發(fā)布和部署階段憎账, 標(biāo)準(zhǔn)化的發(fā)布和部署形式依然必要套硼!

最主要的,你要選擇一種適合公司內(nèi)部標(biāo)準(zhǔn)的發(fā)布和部署形式胞皱,至于具體采用哪一種邪意,it depends。

3.3反砌、運(yùn)維

JavaEE/J2EE的規(guī)范統(tǒng)治了Java界多年之后雾鬼, 服務(wù)化和微服務(wù)化吹響了獨(dú)立戰(zhàn)爭的解放號角...

原來Java界的web應(yīng)用或者web服務(wù)都是需要跑在Web Container里的, Web Container為他們提供基本的“生活環(huán)境”宴树,包括但不限于電話費(fèi)(網(wǎng)絡(luò)通信)策菜, 安保(監(jiān)控)等橫向關(guān)注點(diǎn), 但是這些應(yīng)用同時(shí)也失去了獨(dú)立生存的能力酒贬, 如果某個(gè)應(yīng)用“鬧事”又憨,其它生活在同一環(huán)境下的應(yīng)用多少都會受影響, 公共交通大家都坐過锭吨, 停車開車你是說了不算的蠢莺, 但是tmd車費(fèi)便宜啊零如!

微服務(wù)化之后躏将, 每個(gè)應(yīng)用跳出了Web Container的懷抱, 選擇勇敢的獨(dú)立生存考蕾, 他們自己搞私家車祸憋, 自己賺電話費(fèi),自己尋求安全保障辕翰,就算是出了事兒夺衍, 基本也不會影響其他人,除非撞車(依賴故障)喜命。

這其實(shí)也是一種IoC沟沙, 原來控制權(quán)更多在Web Container手里,現(xiàn)在控制權(quán)掌握在了微服務(wù)自己的手中壁榕。

好處當(dāng)然很明顯矛紫, 故障隔離的更徹底, 資源分配和使用更明確等等牌里, 但是壞處也有颊咬, 邏輯上的網(wǎng)絡(luò)通信啦务甥, 安全管控啦,現(xiàn)在都需要微服務(wù)在實(shí)現(xiàn)和運(yùn)行的時(shí)候喳篇,采用同一種方案敞临,但運(yùn)行在多個(gè)實(shí)例中,假設(shè)某個(gè)這種橫切關(guān)注點(diǎn)邏輯的實(shí)現(xiàn)模塊或者組件存在問題麸澜,那么挺尿, 所有的微服務(wù)都需要升級, 這恐怕就會引發(fā)一系列的發(fā)布和部署風(fēng)暴炊邦, 所以编矾, 對這些技術(shù)的選型上要更加慎重,盡量選擇成熟合適的方案馁害,不要閑得蛋疼或者搞技術(shù)炫耀窄俏,否則,到時(shí)候可就不光是蛋疼了碘菜。

微服務(wù)運(yùn)行之后的管理也會對團(tuán)隊(duì)存在一些挑戰(zhàn)凹蜈,比如:

系統(tǒng)監(jiān)控,應(yīng)用監(jiān)控和業(yè)務(wù)監(jiān)控的數(shù)量點(diǎn)更多了炉媒;

系統(tǒng)分布的更多了踪区, 對系統(tǒng)故障的定位和分析更復(fù)雜了(分布式的tracing方案和工具要跟上);

單機(jī)工具不足以支撐海量服務(wù)的管理了吊骤, 登錄某臺服務(wù)器上去tail -f xx.log或者dump堆棧之類的操作已經(jīng)無法解決整體上的問題了;

所以静尼,我們就不得不構(gòu)建一整套新的支撐平臺白粉, 從日志采集分析, 到運(yùn)維監(jiān)控鼠渺,再到整體系統(tǒng)的tracing等等一系列的功能鸭巴,都要跳出單機(jī)思維去重新思考,等所有這些都做完了之后拦盹,你或許才能長舒一口氣鹃祖, 在此之前, 只要上了微服務(wù)而且服務(wù)數(shù)量持續(xù)增長普舆,你就一定會提心吊膽恬口,如履薄冰。

另外沼侣, 系統(tǒng)彈性層面你也同樣需要投入更多的人力和資源:

強(qiáng)弱依賴管理

限流

負(fù)載均衡與服務(wù)調(diào)度等等

總的來說祖能, 微服務(wù)對持續(xù)交付的要求更高了,相應(yīng)的建設(shè)需要快速跟進(jìn)蛾洛, 才能保障獨(dú)立戰(zhàn)爭的順利進(jìn)行养铸。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子钞螟,更是在濱河造成了極大的恐慌兔甘,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鳞滨,死亡現(xiàn)場離奇詭異洞焙,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)太援,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門闽晦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人提岔,你說我怎么就攤上這事仙蛉。” “怎么了碱蒙?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵荠瘪,是天一觀的道長。 經(jīng)常有香客問我赛惩,道長哀墓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任喷兼,我火速辦了婚禮篮绰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘季惯。我一直安慰自己吠各,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布勉抓。 她就那樣靜靜地躺著贾漏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪藕筋。 梳的紋絲不亂的頭發(fā)上纵散,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機(jī)與錄音隐圾,去河邊找鬼伍掀。 笑死,一個(gè)胖子當(dāng)著我的面吹牛翎承,可吹牛的內(nèi)容都是我干的硕盹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼叨咖,長吁一口氣:“原來是場噩夢啊……” “哼瘩例!你這毒婦竟也來了啊胶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤垛贤,失蹤者是張志新(化名)和其女友劉穎焰坪,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體聘惦,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡某饰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了善绎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片黔漂。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖禀酱,靈堂內(nèi)的尸體忽然破棺而出炬守,到底是詐尸還是另有隱情,我是刑警寧澤剂跟,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布减途,位于F島的核電站,受9級特大地震影響曹洽,放射性物質(zhì)發(fā)生泄漏鳍置。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一送淆、第九天 我趴在偏房一處隱蔽的房頂上張望税产。 院中可真熱鬧,春花似錦偷崩、人聲如沸砖第。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至放吩,卻和暖如春智听,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背渡紫。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工到推, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人惕澎。 一個(gè)月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓莉测,卻偏偏與公主長得像,于是被迫代替她去往敵國和親唧喉。 傳聞我的和親對象是個(gè)殘疾皇子捣卤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

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