我們什么時(shí)候應(yīng)該轉(zhuǎn)向微服務(wù)?
避免小型單體反模式。微服務(wù)在多大規(guī)模上才有意義?避免比問(wèn)題更糟糕的解決方案,并了解權(quán)衡取舍。
上個(gè)月,我寫(xiě)了一篇關(guān)于模塊化單體和現(xiàn)代單體架構(gòu)的價(jià)值的文章。該文章(和視頻)中出現(xiàn)的更有趣的討論之一是逆向討論:什么時(shí)候仍然選擇微服務(wù)是正確的?
與任何設(shè)計(jì)選擇一樣,答案是主觀的并且取決于很多因素。但是我們?nèi)匀豢梢允褂靡话愕慕?jīng)驗(yàn)法則和全球指標(biāo)。在我們進(jìn)入這些問(wèn)題之前,我們需要了解擁有微服務(wù)架構(gòu)意味著什么。然后我們可以衡量擁有這樣一個(gè)架構(gòu)的好處和代價(jià)。
一個(gè)常見(jiàn)的誤解是微服務(wù)只是簡(jiǎn)單地分解為單體。事實(shí)并非如此。我和很多仍然持有這種觀點(diǎn)的人談過(guò),公平地說(shuō),他們可能有道理。AWS 是這樣定義微服務(wù)的:
微服務(wù)是一種軟件開(kāi)發(fā)的架構(gòu)和組織方法,其中軟件由通過(guò)定義明確的 API 進(jìn)行通信的小型獨(dú)立服務(wù)組成。這些服務(wù)由獨(dú)立的小型團(tuán)隊(duì)擁有。
微服務(wù)架構(gòu)使應(yīng)用程序更易于擴(kuò)展和更快地開(kāi)發(fā),從而實(shí)現(xiàn)創(chuàng)新并加快新功能的上市時(shí)間。
較小的單體可能符合該定義,但如果您從字里行間中讀到,則它們不符合?!蔼?dú)立”和“更易于擴(kuò)展”這兩個(gè)詞暗示了這個(gè)問(wèn)題。單體的問(wèn)題(和優(yōu)勢(shì))是單點(diǎn)故障。通過(guò)一項(xiàng)服務(wù),我們通??梢愿菀椎匕l(fā)現(xiàn)問(wèn)題。架構(gòu)要簡(jiǎn)單得多。
如果我們將此服務(wù)分解成更小的部分,我們實(shí)際上會(huì)創(chuàng)建分布式故障點(diǎn)。如果鏈條上的一個(gè)部分出現(xiàn)故障,整個(gè)架構(gòu)就會(huì)崩潰。這不是獨(dú)立的,也不容易擴(kuò)展。微服務(wù)不是小單體,分解單體不僅僅是處理較小的項(xiàng)目。這是關(guān)于改變我們的工作方式。
是什么造就了微服務(wù)?
一個(gè)好的微服務(wù)需要遵循以下健壯性和規(guī)模原則:
- 按業(yè)務(wù)功能劃分:這是一個(gè)邏輯劃分。微服務(wù)是提供完整包的獨(dú)立“產(chǎn)品”。這意味著負(fù)責(zé)微服務(wù)的團(tuán)隊(duì)可以在沒(méi)有依賴(lài)關(guān)系的情況下進(jìn)行業(yè)務(wù)所需的所有更改。
- 通過(guò) CI/CD 實(shí)現(xiàn)自動(dòng)化:如果沒(méi)有持續(xù)交付,更新成本將消除微服務(wù)的所有優(yōu)勢(shì)。
- 獨(dú)立部署:這是隱含的,因?yàn)閷?duì)一個(gè)微服務(wù)的提交只會(huì)觸發(fā)該特定服務(wù)的 CD。我們可以通過(guò) Kubernetes 和基礎(chǔ)架構(gòu)即代碼 (IaC) 解決方案來(lái)實(shí)現(xiàn)這一點(diǎn)。
- 封裝:它應(yīng)該隱藏底層的實(shí)現(xiàn)細(xì)節(jié)。服務(wù)充當(dāng)獨(dú)立產(chǎn)品,為其他產(chǎn)品發(fā)布 API。我們通常通過(guò) REST 接口以及消息傳遞中間件來(lái)實(shí)現(xiàn)這一點(diǎn)。API 網(wǎng)關(guān)進(jìn)一步增強(qiáng)了這一點(diǎn)。
- 去中心化,沒(méi)有單點(diǎn)故障:否則,我們會(huì)分散故障。
- 故障應(yīng)該被隔離:否則,單個(gè)服務(wù)宕機(jī)可能會(huì)產(chǎn)生多米諾骨牌效應(yīng)。斷路器可能是隔離故障的最重要工具。為了滿(mǎn)足這種依賴(lài)性,每個(gè)微服務(wù)都處理自己的數(shù)據(jù)。這意味著很多數(shù)據(jù)庫(kù),有時(shí)可能具有挑戰(zhàn)性。
- 可觀察的:這是處理大規(guī)模故障所必需的。沒(méi)有適當(dāng)?shù)目捎^察性,我們實(shí)際上是盲目的,因?yàn)楦鱾€(gè)團(tuán)隊(duì)可以自動(dòng)部署。
這一切都很好,但實(shí)際上這意味著什么?
它的大部分意思是我們需要對(duì)我們處理一些重要想法的方式做出幾項(xiàng)重大改變。我們需要將更多的復(fù)雜性轉(zhuǎn)移給 DevOps 團(tuán)隊(duì)。我們需要以不同的方式處理跨微服務(wù)的事務(wù)狀態(tài)。這是處理微服務(wù)時(shí)最難掌握的概念之一。
在理想的世界中,我們所有的操作都將很簡(jiǎn)單,并包含在一個(gè)小型微服務(wù)中。圍繞我們的微服務(wù)的服務(wù)網(wǎng)格框架將處理所有全球復(fù)雜性并為我們管理我們的個(gè)人服務(wù)。但這不是真實(shí)的世界。實(shí)際上,我們的微服務(wù)可能具有在服務(wù)之間傳輸?shù)氖聞?wù)狀態(tài)。外部服務(wù)可能會(huì)失敗,為此,我們需要采取一些獨(dú)特的方法。
依賴(lài) DevOps 團(tuán)隊(duì)
如果您的公司沒(méi)有優(yōu)秀的 DevOps 和平臺(tái)工程團(tuán)隊(duì),微服務(wù)就不是一個(gè)選擇。由于遷移,我們可能會(huì)部署數(shù)百個(gè)應(yīng)用程序,而不是部署一個(gè)應(yīng)用程序。雖然單個(gè)部署簡(jiǎn)單且自動(dòng)化,但您仍然會(huì)在操作上投入大量工作。
當(dāng)某些東西不起作用或無(wú)法連接時(shí)。當(dāng)需要集成新服務(wù)或需要采用服務(wù)配置時(shí)。在使用微服務(wù)時(shí),運(yùn)營(yíng)會(huì)承擔(dān)更大的負(fù)擔(dān)。這需要良好的溝通和協(xié)作。這也意味著管理特定服務(wù)的團(tuán)隊(duì)需要重新承擔(dān)一些 OPS 負(fù)擔(dān)。這不是一項(xiàng)簡(jiǎn)單的任務(wù)。
作為開(kāi)發(fā)人員,我們需要了解許多用于將我們的單獨(dú)服務(wù)綁定回單個(gè)統(tǒng)一服務(wù)的工具:
- 服務(wù)網(wǎng)格:讓我們組合獨(dú)立的服務(wù),并有效地充當(dāng)它們之間的負(fù)載均衡器。它還提供安全、授權(quán)、流量控制等功能。
- API 網(wǎng)關(guān):應(yīng)該使用而不是直接調(diào)用 API。這有時(shí)會(huì)很尷尬,但通常對(duì)于避免成本、防止速率限制等來(lái)說(shuō)是必不可少的。
- 特征標(biāo)志和秘密:在單體中也很有用。但如果沒(méi)有專(zhuān)用工具,它們就不可能在微服務(wù)規(guī)模上進(jìn)行管理。
- 熔斷:讓我們終止斷開(kāi)的 Web 服務(wù)連接并優(yōu)雅地恢復(fù)。否則,單個(gè)損壞的服務(wù)可能會(huì)導(dǎo)致整個(gè)系統(tǒng)崩潰。
- 身份管理必須是獨(dú)立的:在處理微服務(wù)環(huán)境時(shí),您無(wú)法擺脫數(shù)據(jù)庫(kù)中的身份驗(yàn)證表。
我將跳過(guò)編排、CI/CD 等,但它們也需要針對(duì)出現(xiàn)的每項(xiàng)服務(wù)進(jìn)行調(diào)整。其中一些工具對(duì)開(kāi)發(fā)人員來(lái)說(shuō)是不透明的,但我們?cè)谒须A段都需要 DevOps 的幫助。
傳奇模式
無(wú)狀態(tài)服務(wù)將是理想的,承載狀態(tài)會(huì)使一切變得更加復(fù)雜。如果我們將狀態(tài)存儲(chǔ)在客戶(hù)端中,我們需要一直來(lái)回發(fā)送它。如果它在服務(wù)器上,我們將需要不斷獲取它、緩存它或?qū)⑵浔4嬖诒镜兀缓笏薪换ザ紝⑨槍?duì)當(dāng)前系統(tǒng)執(zhí)行。這消除了系統(tǒng)的可擴(kuò)展性。
典型的微服務(wù)將存儲(chǔ)在自己的數(shù)據(jù)庫(kù)中并使用本地?cái)?shù)據(jù)。需要遠(yuǎn)程信息的服務(wù)通常會(huì)緩存一些數(shù)據(jù)以避免往返于其他服務(wù)。這是微服務(wù)可以擴(kuò)展的最大原因之一。在單體中,數(shù)據(jù)庫(kù)應(yīng)該成為應(yīng)用程序的瓶頸,這意味著單體是高效的并且受限于我們存儲(chǔ)和檢索數(shù)據(jù)的速度。這有兩個(gè)主要缺點(diǎn):
- 大?。何覀儞碛械臄?shù)據(jù)越多;數(shù)據(jù)庫(kù)越大,性能會(huì)同時(shí)影響所有用戶(hù)。想象一下,查詢(xún)亞馬遜上每次購(gòu)買(mǎi)的 SQL 表只是為了找到您的特定購(gòu)買(mǎi)。
- 域:數(shù)據(jù)庫(kù)有不同的用例。一些數(shù)據(jù)庫(kù)針對(duì)一致性、寫(xiě)入速度、讀取速度、時(shí)間數(shù)據(jù)、空間數(shù)據(jù)等進(jìn)行了優(yōu)化。跟蹤用戶(hù)信息的微服務(wù)可能會(huì)使用時(shí)間序列數(shù)據(jù)庫(kù),該數(shù)據(jù)庫(kù)針對(duì)與時(shí)間相關(guān)的信息進(jìn)行了優(yōu)化,而購(gòu)買(mǎi)服務(wù)將專(zhuān)注于傳統(tǒng)的保守 ACID 數(shù)據(jù)庫(kù)。
- 注意:一個(gè)整體可以使用多個(gè)數(shù)據(jù)庫(kù)。這可以很好地工作并且非常有用。但這是例外。不是規(guī)則。
saga 模式通過(guò)使用補(bǔ)償事務(wù)來(lái)撤銷(xiāo) saga 失敗時(shí)的影響。當(dāng) saga 失敗時(shí),將執(zhí)行補(bǔ)償事務(wù)以撤消前一個(gè)事務(wù)所做的更改。這允許系統(tǒng)從故障中恢復(fù)并保持一致的狀態(tài)。我們可以使用 Apache Camel 等工具來(lái)完成此操作,但這并非易事,并且需要比現(xiàn)代系統(tǒng)中的典型事務(wù)更多的參與。這意味著對(duì)于每個(gè)主要的跨服務(wù)操作,您都需要執(zhí)行等效的撤消操作來(lái)恢復(fù)狀態(tài)。那是不平凡的。有多種用于 saga 編排的工具,但這是一個(gè)超出本文范圍的大主題,我仍然會(huì)從廣義上對(duì)其進(jìn)行解釋。
了解 saga 的重要之處在于它避免了經(jīng)典的 ACID 數(shù)據(jù)庫(kù)原則,而側(cè)重于“最終一致性”。這意味著操作會(huì)在某個(gè)時(shí)候使數(shù)據(jù)庫(kù)處于一致?tīng)顟B(tài)。那是一個(gè)非常艱難的過(guò)程。想象調(diào)試一個(gè)只有在系統(tǒng)處于不一致?tīng)顟B(tài)時(shí)才會(huì)出現(xiàn)的問(wèn)題。
下圖從廣義上展示了這個(gè)想法。假設(shè)我們有一個(gè)匯款流程:
對(duì)于匯款,我們需要先分配資金。
然后我們驗(yàn)證收件人是否有效且存在。
接下來(lái),我們需要從我們的賬戶(hù)中扣除資金。
最后,我們需要將錢(qián)添加到收款人的帳戶(hù)中。
那就是一筆成功的交易。對(duì)于常規(guī)數(shù)據(jù)庫(kù),這將是一個(gè)事務(wù),我們可以在下圖中左側(cè)的藍(lán)色列中看到它。但如果出現(xiàn)問(wèn)題,我們需要運(yùn)行相反的過(guò)程:
如果分配資金失敗,我們需要移除分配。我們需要?jiǎng)?chuàng)建一個(gè)單獨(dú)的代碼塊來(lái)執(zhí)行分配的逆操作。
如果驗(yàn)證收件人失敗,我們需要?jiǎng)h除該收件人。然后我們還需要?jiǎng)h除分配。
如果扣除資金失敗,我們需要恢復(fù)資金,移除接收者,移除分配。
最后,如果向收款人添加資金失敗,我們需要運(yùn)行所有的撤銷(xiāo)操作!
saga 中的另一個(gè)問(wèn)題在 CAP 定理中得到了說(shuō)明。CAP 代表一致性、可用性和分區(qū)容錯(cuò)性。問(wèn)題是我們需要選擇任意兩個(gè)……別誤會(huì)我的意思,你可能三個(gè)都選。但是,在失敗的情況下,你只能保證兩個(gè)。
可用性意味著請(qǐng)求收到響應(yīng)。但不能保證它們包含最新的寫(xiě)入。
一致性意味著每次讀取都會(huì)收到最近的錯(cuò)誤寫(xiě)入。
容忍意味著即使許多消息在途中被丟棄,一切都會(huì)繼續(xù)工作。
這與我們處理交易失敗的歷史方法大不相同。
我們應(yīng)該選擇微服務(wù)嗎?
希望您了解正確部署微服務(wù)有多么困難。我們需要做出一些重大妥協(xié)。這種新方式不一定更好,在某些方面,它更糟。但是微服務(wù)的支持者還是有道理的,我們可以通過(guò)微服務(wù)獲得很多,也應(yīng)該關(guān)注這些好處。
我們預(yù)先提到了第一個(gè)要求:DevOps。擁有一支優(yōu)秀的 DevOps 團(tuán)隊(duì)是考慮微服務(wù)的先決條件。我看到團(tuán)隊(duì)試圖在沒(méi)有 OPS 團(tuán)隊(duì)的情況下解決這個(gè)問(wèn)題,他們最終花在操作復(fù)雜性上的時(shí)間比編寫(xiě)代碼還多。這是不值得的努力。
微服務(wù)最大的好處是給團(tuán)隊(duì)的。這就是為什么擁有穩(wěn)定的團(tuán)隊(duì)和范圍至關(guān)重要的原因。將團(tuán)隊(duì)拆分成獨(dú)立工作的垂直團(tuán)隊(duì)是一個(gè)巨大的好處。世界上模塊化程度最高的單體無(wú)法與之抗衡。當(dāng)我們有數(shù)百名開(kāi)發(fā)人員單獨(dú)跟蹤 git 提交時(shí),跟蹤代碼的規(guī)模變化就變得站不住腳了。微服務(wù)的價(jià)值只有在大團(tuán)隊(duì)中才能體現(xiàn)出來(lái)。這聽(tīng)起來(lái)很合理,但在創(chuàng)業(yè)環(huán)境中,事情突然發(fā)生了變化。我的一位同事在一家雇傭了數(shù)十名開(kāi)發(fā)人員的初創(chuàng)公司工作。他們決定遵循微服務(wù)架構(gòu)并構(gòu)建了很多。然后是縮減和維護(hù)多種語(yǔ)言的數(shù)十種服務(wù)成為一個(gè)問(wèn)題。
拆分單體很難但可行。將微服務(wù)統(tǒng)一到一個(gè)整體可能更難,我不知道有誰(shuí)認(rèn)真嘗試過(guò)這樣做但很想聽(tīng)聽(tīng)故事。
不是一個(gè)尺寸
要遷移到微服務(wù)架構(gòu),我們需要進(jìn)行一些思維轉(zhuǎn)變。一個(gè)很好的例子是數(shù)據(jù)庫(kù)和用戶(hù)跟蹤微服務(wù)。在整體中,我們會(huì)將數(shù)據(jù)寫(xiě)入表并繼續(xù)我們的工作。但這是有問(wèn)題的。
隨著數(shù)據(jù)規(guī)模的擴(kuò)大,這個(gè)用戶(hù)跟蹤表最終可能包含大量數(shù)據(jù),這些數(shù)據(jù)很難在不影響操作系統(tǒng)其余部分的情況下進(jìn)行實(shí)時(shí)分析。通過(guò)微服務(wù),我們可以提供幾個(gè)優(yōu)勢(shì):
微服務(wù)的接口可以使用消息傳遞,這意味著發(fā)送跟蹤信息的成本將降至最低。
跟蹤數(shù)據(jù)可以使用時(shí)間序列數(shù)據(jù)庫(kù),這對(duì)于這個(gè)用例來(lái)說(shuō)會(huì)更有效。
我們可以流式傳輸數(shù)據(jù)并異步處理它以從該數(shù)據(jù)中獲取額外的價(jià)值。
存在復(fù)雜性,數(shù)據(jù)將不再本地化。因此,如果我們異步發(fā)送跟蹤數(shù)據(jù),我們需要發(fā)送所有必要的信息,因?yàn)楦櫡?wù)將無(wú)法返回到原始服務(wù)以獲取額外的元數(shù)據(jù)。但它具有位置優(yōu)勢(shì),如果有關(guān)跟蹤存儲(chǔ)的法規(guī)發(fā)生變化,則只有一個(gè)地方可以存儲(chǔ)它。
動(dòng)態(tài)控制和推出
您是否曾經(jīng)按下過(guò)發(fā)布按鈕導(dǎo)致生產(chǎn)中斷?
我做了不止一次(太多次了)。那是一種可怕的感覺(jué)。微服務(wù)在生產(chǎn)中仍然會(huì)失敗,并且仍然會(huì)發(fā)生災(zāi)難性的失敗,但是,它們的失敗通常是局部的。將它們推廣到系統(tǒng)的特定子集 (Canary) 并進(jìn)行驗(yàn)證也更容易。這些都是可以由實(shí)際掌握用戶(hù)脈搏的人深入控制的策略:OPS。
微服務(wù)的可觀察性是必不可少的、昂貴的,但也更強(qiáng)大。由于一切都發(fā)生在網(wǎng)絡(luò)層,因此都暴露給可觀察性工具。SRE 或 DevOps 可以更詳細(xì)地了解故障。這是以開(kāi)發(fā)人員為代價(jià)的,他們可能需要面對(duì)增加的復(fù)雜性和有限的工具。
應(yīng)用程序可能會(huì)變得太大而不能失敗。即使采用模塊化,一些最大的單體應(yīng)用也有如此多的代碼,運(yùn)行一個(gè)完整的 CI/CD 周期需要數(shù)小時(shí)。然后,如果部署失敗,恢復(fù)到上一個(gè)好的版本也可能需要一段時(shí)間。
分割
過(guò)去,我們?cè)?jīng)根據(jù)層級(jí)劃分團(tuán)隊(duì)??蛻?hù)端、服務(wù)器、數(shù)據(jù)庫(kù)等。這是有道理的,因?yàn)槊恳粋€(gè)都需要一套獨(dú)特的技能。今天,垂直團(tuán)隊(duì)更有意義,但我們?nèi)匀挥袑?zhuān)長(zhǎng)。
通常,移動(dòng)開(kāi)發(fā)人員不會(huì)在后端工作。但是假設(shè)我們有一個(gè)移動(dòng)團(tuán)隊(duì)想要使用 GraphQL 而不是 REST。對(duì)于單體,我們要么告訴他們“接受它”,要么我們必須完成這項(xiàng)工作。有了微服務(wù),我們可以用很少的代碼為他們創(chuàng)建一個(gè)簡(jiǎn)單的服務(wù)。核心服務(wù)的簡(jiǎn)單外觀。我們不需要擔(dān)心移動(dòng)團(tuán)隊(duì)編寫(xiě)服務(wù)器代碼,因?yàn)檫@相對(duì)孤立。我們可以對(duì)每個(gè)客戶(hù)層做同樣的事情,這樣更容易垂直整合一個(gè)團(tuán)隊(duì)。
太大
很難將手指放在使整體式應(yīng)用不切實(shí)際的尺寸上,但這是您應(yīng)該問(wèn)自己的問(wèn)題:
我們擁有或想要多少支球隊(duì)?
如果你有幾個(gè)團(tuán)隊(duì),那么單體應(yīng)用可能會(huì)很棒。如果您有十幾個(gè)團(tuán)隊(duì),那么您可能會(huì)在那里遇到問(wèn)題。
衡量拉取請(qǐng)求和問(wèn)題解決時(shí)間
隨著項(xiàng)目的增長(zhǎng),您的拉取請(qǐng)求將花費(fèi)更多時(shí)間等待合并,并且問(wèn)題將需要更長(zhǎng)的時(shí)間來(lái)解決。這是不可避免的,因?yàn)轫?xiàng)目的復(fù)雜性趨于增加。請(qǐng)注意,新項(xiàng)目將具有更大的功能,一旦您在項(xiàng)目統(tǒng)計(jì)中考慮到生產(chǎn)力的下降應(yīng)該是可衡量的,這可能會(huì)影響結(jié)果。
請(qǐng)注意,這是一個(gè)指標(biāo)。在許多情況下,它可以指示其他事情,例如需要優(yōu)化測(cè)試管道、審查流程、模塊化等。
我們有知道代碼的專(zhuān)家嗎?
在某個(gè)時(shí)候,一個(gè)龐大的項(xiàng)目變得如此之大,以至于專(zhuān)家們開(kāi)始忘記細(xì)節(jié)。當(dāng)錯(cuò)誤變得難以為繼并且沒(méi)有權(quán)威人物可以不經(jīng)咨詢(xún)就做出決定時(shí),這就成為一個(gè)問(wèn)題。
你愿意花錢(qián)嗎?
微服務(wù)將花費(fèi)更多。沒(méi)有辦法解決這個(gè)問(wèn)題。在某些特殊情況下,我們可以調(diào)整規(guī)模,但最終,可觀察性和管理成本將消除任何潛在的成本節(jié)約。由于人員成本通常超過(guò)云托管成本,因此總成本可能仍對(duì)您有利,因?yàn)槿绻?guī)模足夠大,這些成本可能會(huì)降低。
取舍
下面的雷達(dá)圖很好地說(shuō)明了單體與微服務(wù)的權(quán)衡。請(qǐng)注意,此圖表是為大型項(xiàng)目設(shè)計(jì)的。項(xiàng)目越小,單體應(yīng)用的前景就越好。
請(qǐng)注意,微服務(wù)在容錯(cuò)和團(tuán)隊(duì)獨(dú)立性方面為大型項(xiàng)目帶來(lái)了好處。但他們付出了代價(jià)。他們可以減少研發(fā)支出,但他們主要將其轉(zhuǎn)移到 DevOps,因此這并不是一個(gè)主要的好處。
最后一句話
微服務(wù)的復(fù)雜性是巨大的,有時(shí)會(huì)被實(shí)施團(tuán)隊(duì)忽略。開(kāi)發(fā)人員使用微服務(wù)作為一個(gè)大棒來(lái)拋棄他們不想維護(hù)的系統(tǒng)部分,而不是構(gòu)建一個(gè)可持續(xù)的、可擴(kuò)展的架構(gòu)來(lái)取代單體。
我堅(jiān)信項(xiàng)目應(yīng)該從單體開(kāi)始。微服務(wù)是擴(kuò)展團(tuán)隊(duì)的優(yōu)化,過(guò)早優(yōu)化是萬(wàn)惡之源。問(wèn)題是,什么時(shí)候做這樣的優(yōu)化合適?
我們可以使用一些指標(biāo)來(lái)簡(jiǎn)化決策。最終,這種變化不僅僅是拆分單體。這意味著重新思考交易和核心概念。從單體開(kāi)始,我們就有了一個(gè)藍(lán)圖,我們可以使用它來(lái)調(diào)整我們的新實(shí)現(xiàn),因?yàn)樗鼤?huì)加強(qiáng)。