自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

對(duì)SSH框架系統(tǒng)進(jìn)行微服務(wù)改進(jìn)

開(kāi)發(fā) 開(kāi)發(fā)工具
這篇文章從縱向詳細(xì)介紹如何對(duì)SSH框架的支付系統(tǒng)實(shí)施具體的技改。這里不涉及具體代碼寫(xiě)法,重點(diǎn)在于說(shuō)明方法論。雖然以SSH(Apache Struts + Springframework + Hibernate) 框架為例,也適合各種常用的web架構(gòu) (Apache Struts/Spring MVC / Apache Velocity + Springframework + Mybatis/Hibernate) 。

本文假定你已經(jīng)閱讀過(guò)之前的文章:

  • 為什么要重構(gòu)到微服務(wù)
  • 重構(gòu)中的外部準(zhǔn)備工作
  • 重構(gòu)中的內(nèi)部準(zhǔn)備工作
  • 使用微服務(wù)架構(gòu)重構(gòu)支付網(wǎng)關(guān)

上一篇文章使用微服務(wù)架構(gòu)重構(gòu)支付網(wǎng)關(guān)是從橫向的角度來(lái)分析如何分解服務(wù)以及建立微服務(wù)之間的關(guān)系。這篇文章從縱向詳細(xì)介紹如何對(duì)SSH框架的支付系統(tǒng)實(shí)施具體的技改。這里不涉及具體代碼寫(xiě)法,重點(diǎn)在于說(shuō)明方法論。雖然以SSH(Apache Struts + Springframework + Hibernate) 框架為例,也適合各種常用的web架構(gòu) (Apache Struts/Spring MVC / Apache Velocity + Springframework + Mybatis/Hibernate) 。

選取入手模塊

如果遺留系統(tǒng)規(guī)模龐大,那應(yīng)該如何挑選入手點(diǎn)?以支付系統(tǒng)為例,如前文所述,支付系統(tǒng)一般包括賬戶,交易,訂單,優(yōu)惠券,錢(qián)包,支付渠道,清結(jié)算,支付網(wǎng)關(guān),運(yùn)營(yíng)系統(tǒng)等模塊。模塊很多,如何選擇突破點(diǎn)? 我們采取的方法是尋找對(duì)外依賴最小的模塊,由此開(kāi)始調(diào)整。 首先模塊依賴關(guān)系整理出來(lái)。

從上圖可以看出來(lái),賬戶系統(tǒng)在依賴樹(shù)中是處于樹(shù)根的位置,對(duì)它的調(diào)整相對(duì)容易。只要保持對(duì)外接口不變即可。

 

 

重構(gòu)策略

重構(gòu)如同飛行中更換引擎,必須非常小心,我們采取的策略是:小步快跑,積小勝為大勝。

  • 每一個(gè)改進(jìn)點(diǎn),需在1~3天內(nèi)完成,不能超過(guò)一個(gè)周。
  • 每次改進(jìn),均可直接上線運(yùn)行,不需要長(zhǎng)時(shí)間的AB測(cè)試。

在功能也就是對(duì)外接口不變的前提下,開(kāi)始進(jìn)行拆分工作。 在結(jié)構(gòu)上,原SSH系統(tǒng)是一個(gè)大項(xiàng)目,所有代碼分層分模塊堆在一起。微服務(wù)系統(tǒng)需要將它們拆分。直觀的拆分方法是按層,按模塊同構(gòu)的拆分成各個(gè)獨(dú)立運(yùn)行和維護(hù)的系統(tǒng)。由此帶來(lái)了一系列的調(diào)整。在SSH架構(gòu)下,重構(gòu)可以采用自上而下的方法進(jìn)行,這樣可以確保每一層的重構(gòu)都有明確的輸入輸出,并且是可測(cè)試的。

整體上,重構(gòu)分為三個(gè)步驟:

 

 

  1. 參考原有系統(tǒng)的DAO層和業(yè)務(wù)邏輯層,實(shí)現(xiàn)基礎(chǔ)服務(wù),一般是使用RPC來(lái)實(shí)現(xiàn).
  2. 將對(duì)外的接口層進(jìn)行重構(gòu),調(diào)整為調(diào)用RPC服務(wù)。
  3. 將原有服務(wù)切一部分流量到新服務(wù)上進(jìn)行試運(yùn)行。
  4. 試運(yùn)行成功,全部流量都切過(guò)來(lái)。 舊服務(wù)廢棄。

API網(wǎng)關(guān)

在SSH架構(gòu)下,對(duì)API網(wǎng)關(guān)一般是通過(guò)NGINX的rewtite模塊來(lái)實(shí)現(xiàn),邏輯簡(jiǎn)單,人工維護(hù)即可。而一旦接口層按照業(yè)務(wù)來(lái)拆分后,網(wǎng)關(guān)路由邏輯復(fù)雜多了,通過(guò)人工維護(hù)配置文件難度激增,需要調(diào)整成自動(dòng)注冊(cè)更新路由的方式。也就是每個(gè)服務(wù)需要將自己提供的服務(wù)和API注冊(cè)到API網(wǎng)關(guān)上, API網(wǎng)關(guān)需要自動(dòng)識(shí)別并加載新的路由。

針對(duì)這個(gè)需求,我們開(kāi)發(fā)了一個(gè)connector, 其工作原理如下:

  • 服務(wù)在啟動(dòng)完成后,注冊(cè)到zookeeper上。
  • connector監(jiān)聽(tīng) zookeeper,一旦有變更,則獲取服務(wù)列表,更新nginx.conf文件
  • connector在更新完成nginx.conf文件后,執(zhí)行nginx的reload命令,讓配置生效。
  • load balancer 將服務(wù)打到nginx上,nginx可以按照新配置來(lái)執(zhí)行服務(wù)路由。

在服務(wù)關(guān)閉時(shí),執(zhí)行類(lèi)似的操作。第一步是在服務(wù)關(guān)閉前,將服務(wù)從zookeeper上刪除。注意必須在服務(wù)關(guān)閉前刪除,否則會(huì)發(fā)生服務(wù)不可用的錯(cuò)誤。 服務(wù)注冊(cè)項(xiàng)從zookeeper上刪除,并且本地服務(wù)沒(méi)有流量后,才能關(guān)閉服務(wù)。connector可以和nginx部署在同一臺(tái)機(jī)器上。

服務(wù)接口調(diào)整

使用Spring MVC實(shí)現(xiàn)的Controller或者使用Apache Struts實(shí)現(xiàn)的Action,需要按照業(yè)務(wù)進(jìn)行組合,拆分到具體項(xiàng)目中,原則上,一個(gè)項(xiàng)目不應(yīng)該有超過(guò)5個(gè)接口,避免接口過(guò)于復(fù)雜。本次調(diào)整需要做的工作包括:

  • 增加服務(wù)注冊(cè)機(jī)制,在服務(wù)啟動(dòng)時(shí)將服務(wù)注冊(cè)到zookeeper上;
  • 增加服務(wù)退出機(jī)制,在服務(wù)關(guān)閉時(shí)將服務(wù)解除注冊(cè);
  • 將服務(wù)按照業(yè)務(wù)組合,建立對(duì)應(yīng)的項(xiàng)目;
  • 將服務(wù)依賴的業(yè)務(wù)邏輯層打包到同一個(gè)jar中,作為后續(xù)改進(jìn)的基礎(chǔ)。
  • 服務(wù)上線,替換掉現(xiàn)有的服務(wù)。

業(yè)務(wù)邏輯層調(diào)整

在springframework框架下,業(yè)務(wù)邏輯層被實(shí)現(xiàn)為服務(wù)層和DAO層之間的橋梁。 對(duì)于絕大多數(shù)應(yīng)用來(lái)說(shuō),業(yè)務(wù)邏輯層都是非常薄的一層封裝,調(diào)整為微服務(wù)架構(gòu)下,業(yè)務(wù)邏輯層有三種處理方式:

  • 抽象為獨(dú)立的RPC服務(wù),對(duì)于功能比較復(fù)雜業(yè)務(wù)邏輯,可以使用這種方式。
  • 下沉到DAO層,如果邏輯上涉及數(shù)據(jù)訪問(wèn)操作多,或者需要事務(wù)處理的,可以合并到DAO中,一同實(shí)現(xiàn)為RPC。
  • 上浮到接口層。如果業(yè)務(wù)邏輯比較簡(jiǎn)單,也可以上浮。

DAO層的重構(gòu)

DAO層的重構(gòu)的工作量比較大。 需要將原來(lái)訪問(wèn)數(shù)據(jù)庫(kù)的邏輯,調(diào)整為遠(yuǎn)程RPC調(diào)用:

針對(duì)DAO的接口,開(kāi)發(fā)RPC服務(wù),將數(shù)據(jù)訪問(wèn)邏輯通過(guò)RPC來(lái)隔離;

提供DAO的RPC接口客戶端,替換原DAO服務(wù)接口的實(shí)現(xiàn)。

這樣在業(yè)務(wù)邏輯層和服務(wù)層中調(diào)用的DAO,調(diào)整為RPC調(diào)用,將數(shù)據(jù)訪問(wèn)邏輯和業(yè)務(wù)邏輯分離。這樣在DAO層就可以根據(jù)業(yè)務(wù)需要選用合適的存儲(chǔ)數(shù)據(jù)庫(kù)。

性能優(yōu)化

1.完成上述調(diào)整,這才是萬(wàn)里長(zhǎng)征走完的第一步。接下來(lái)就是碼農(nóng)們最心愛(ài)的性能優(yōu)化了。 對(duì)于大部分線上應(yīng)用來(lái)說(shuō),性能優(yōu)化主要的工作是選擇合適的存儲(chǔ)介質(zhì)來(lái)滿足性能的需求。

2.數(shù)據(jù)可以直接寫(xiě)入MySQL或者其他的持久化存儲(chǔ)。這個(gè)庫(kù)也會(huì)被稱(chēng)之為主庫(kù)。但是如果寫(xiě)入性能要求高,可以調(diào)整為先寫(xiě)入內(nèi)存數(shù)據(jù)庫(kù),再同步到持久化存儲(chǔ)中。

3.線上數(shù)據(jù)訪問(wèn),指根據(jù)ID或者其他的某個(gè)屬性值來(lái)讀取1-2條數(shù)據(jù)。一般不要直接從MySQL等持久化存儲(chǔ)中出,需要采用couchbase,redis等內(nèi)存數(shù)據(jù)庫(kù)。

4.線上數(shù)據(jù)檢索,檢索和訪問(wèn)需要分開(kāi)。按照關(guān)鍵字、時(shí)間等條件的檢索,一般用Elastic來(lái)滿足。

線上數(shù)據(jù)列表,如最新、最熱、推薦等,都需要將數(shù)據(jù)預(yù)先計(jì)算好,放在couchbase或者redis等內(nèi)存數(shù)據(jù)庫(kù)中,讀取的時(shí)候直接從庫(kù)中出數(shù)據(jù),不能執(zhí)行實(shí)時(shí)計(jì)算。

通過(guò)這幾個(gè)步驟,就可以優(yōu)化線上服務(wù)的性能,最終呢,瓶頸應(yīng)該不是在數(shù)據(jù)庫(kù)或者CPU上,而是在帶寬上。 那這就是砸錢(qián)的商務(wù)行為了。 這樣處理,帶來(lái)的最大的問(wèn)題是空間浪費(fèi),是典型的以空間換時(shí)間的做法。 技術(shù)上的挑戰(zhàn),那就是數(shù)據(jù)一致性問(wèn)題。 對(duì)于一致性要求不強(qiáng)的需求,這個(gè)做法是沒(méi)問(wèn)題的。 那如何在不同存儲(chǔ)之間同步數(shù)據(jù)呢?主要的做法有:

5.使用數(shù)據(jù)庫(kù)本身自帶的同步機(jī)制。好處是一般不需要開(kāi)發(fā),問(wèn)題是數(shù)據(jù)庫(kù)的同步機(jī)制,如MysQL、HBase的replication機(jī)制,僅支持少數(shù)類(lèi)型的備庫(kù),對(duì)數(shù)據(jù)庫(kù)本身也有壓力。

6.使用公共同步工具,如阿里的canal。

7.使用消息中間件來(lái)實(shí)現(xiàn)數(shù)據(jù)同步。

采用消息中間件目前主流的做法,適合于對(duì)數(shù)據(jù)實(shí)時(shí)性要求不高的場(chǎng)景。 如下圖所示,在數(shù)據(jù)寫(xiě)入的服務(wù)中,完成寫(xiě)入后,拋出消息。其他數(shù)據(jù)庫(kù)通過(guò)接受消息來(lái)更新數(shù)據(jù)。 優(yōu)點(diǎn)是系統(tǒng)靈活,無(wú)論是同DC還是跨DC的情況都可以正常工作。 對(duì)數(shù)據(jù)同步的情況,可以通過(guò)MQ提供的監(jiān)控系統(tǒng)也能夠了解。 缺點(diǎn)是開(kāi)發(fā)工作量大,數(shù)據(jù)同步實(shí)時(shí)性不高。

如果時(shí)間不夠

上述重構(gòu)是非常理想的場(chǎng)景了,那如果時(shí)間不足,只能部分重構(gòu),應(yīng)該如何處理?一種方式是針對(duì)DAO層來(lái)改進(jìn)。 一般來(lái)說(shuō),重構(gòu)往往意味著數(shù)據(jù)結(jié)構(gòu)的變更。另一方面,由于數(shù)據(jù)寫(xiě)入的服務(wù)相對(duì)數(shù)據(jù)讀取服務(wù)要少得多,所以可以采用的策略是:

  1. 調(diào)整DAO服務(wù)中數(shù)據(jù)寫(xiě)入操作,將數(shù)據(jù)寫(xiě)入到新的庫(kù)表中;
  2. 采用MQ來(lái)實(shí)現(xiàn)新庫(kù)表和老庫(kù)表的數(shù)據(jù)同步。 參見(jiàn)上圖。
  3. 老的DAO服務(wù)中數(shù)據(jù)讀取的操作保持不變。

畢竟大部分的服務(wù)并不需要太高的性能需求。 只需要將性能要求高的服務(wù)進(jìn)行重構(gòu),實(shí)現(xiàn)讀寫(xiě)分離即可。重構(gòu)方式如上描述。

總之,技改的難度在于如何梳理出頭緒來(lái)。 本文算是拋磚引玉,歡迎大家熱烈討論。

【本文為51CTO專(zhuān)欄作者“鳳凰牌老熊”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過(guò)微信公眾號(hào)“鳳凰牌老熊”聯(lián)系作者本人】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來(lái)源: 51CTO專(zhuān)欄
相關(guān)推薦

2011-08-22 14:38:40

linux服務(wù)器分區(qū)

2021-04-14 09:43:57

微服務(wù)拆分業(yè)務(wù)

2023-03-24 16:18:08

微服務(wù)架構(gòu)

2021-02-06 17:55:41

微服務(wù)Maven版本控制

2020-11-27 10:50:06

微服務(wù)架構(gòu)框架

2021-03-02 16:25:52

微服務(wù)架構(gòu)技術(shù)

2023-02-17 18:06:33

微服務(wù)架構(gòu)

2022-11-09 16:23:17

Python微服務(wù)架構(gòu)

2024-11-29 13:37:56

2022-02-20 22:10:20

微服務(wù)框架gRPC

2019-07-12 08:45:07

開(kāi)源微服務(wù)框架

2021-12-02 16:20:17

開(kāi)源微服務(wù)框架

2009-12-07 14:51:57

WCF框架

2020-11-13 10:45:44

微服務(wù)架構(gòu)數(shù)據(jù)

2022-05-02 09:35:55

GNOME 42Linux

2018-08-01 14:20:11

微服務(wù)架構(gòu)人工智能

2009-12-08 18:08:43

WCF服務(wù)

2025-01-20 00:10:00

Go語(yǔ)言Kratos

2019-01-31 14:00:03

Java微服務(wù)框架

2023-02-07 07:43:27

微服務(wù)應(yīng)用框架
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)