傳統企業核心系統架構最佳化行動指南

danny_2018發表於2022-09-21

很多企業的核心繫統隨著業務的快速發展,一段時間後會出現執行緩慢、執行卡頓等非正常情況。對於這類效能問題的解決大多受系統本身架構限制,除了對資源進行最佳化外,大多處於被動狀態。資金和技術雄厚的傳統企業可以採取比較激進的做法,進行服務化重構,或升級系統的當前版本,但激進的做法往往面臨的高風險,本文將結合實際最佳化過案例,從整體解決方案的角度剖析該類問題的最佳化經驗及技巧。

【作者】zhanxuechao,系統架構師

很多傳統企業的核心應用系統大多是單體應用:1-2臺APP應用,後端1個資料庫例項,如下圖:

稍微好一點的可能會有一臺單獨的伺服器用來部署報表類應用(報表業務與應用實現應用層面的解耦),但資料方面大多還是與APP共用統一資料庫,如下圖:

這實際上是由於企業的業務實際情況和行業屬性導致的,該類核心應用系統大多為外採的、成熟的商業產品(迭代較慢,1~2年可能才有新版本推出),可以滿足企業的正常業務系統,但大多會隨著企業自身業務的快速發展,一段時間後會出現系統執行緩慢、執行卡頓等非正常情況。相信很多傳統企業的IT工程師都會面臨該類問題(就我本人隨機與幾家不同區域的傳統企業資訊負責人溝通後,全部面臨或是曾經面臨過),對於這類效能問題的解決大多受系統本身架構限制,除了對資源進行最佳化外,大多處於被動狀態。另外對該類應用系統的效能問題進行分析後,大多的問題點也都集中在了資料庫層面,誠然,即使中大型傳統企業的核心繫統其使用人數和併發量也基本上處於一個較低的值,單體應用、一臺Tomcat可以滿足應用層面的併發(有一些情況除外,另外,據簡單訪談,使用Tomcat的也相對少一點)。當然,資金和技術雄厚的傳統企業可以採取比較激進的做法,即對現有核心繫統進行服務化重構,或是冒高風險、花大價錢升級系統的當前版本(因為傳統企業資訊化建設相對閉塞滯後,同時也處於求穩的出發點,系統版本幾年不更新很常見),激進的做法往往面臨的高風險,也見過太多傳統企業在所謂網際網路轉型和核心繫統重構方面全面失敗的案例。

結合實際最佳化過的幾個企業案例,從整體解決方案的角度剖析一下該類問題的最佳化經驗及技巧。總的來說,可以分為技術最佳化和業務最佳化。其中技術最佳化包括硬體升級、引數類最佳化;業務最佳化是指結合業務細節,對資料庫的sql、程式程式碼以及架構等方面進行最佳化工作,具體如下。

一、技術最佳化

技術最佳化可以分為對硬體進行升級和對各類作業系統、中介軟體等進行引數最佳化兩類。其中在系統部署上線前,就應該對系統響應的使用者量、併發量、資料量等進行評估,選擇適合的硬體配置、作業系統、中介軟體等並對其進行相應的安全加固和引數最佳化。

實際上當系統出現效能問題時,大多第一時間想到的是對硬體進行升級,如:增加記憶體、升級儲存(如HDD升級到SSD等)、升級網路交換機擴大頻寬、升級伺服器等。這是一種簡單有效但不治本的方法,甚至在治標方面也難以得到持久,因為系統的效能問題在硬體和應用之間,還有作業系統、中介軟體等,需要與之相互配套,之前也遇到過32位作業系統跑64G記憶體的情況(實則真的有一些老舊的應用真實地執行在32位作業系統上)。

在對硬體資源進行升級的同時,還應配套對作業系統、中介軟體、資料庫等的引數進行最佳化,確保最大化、最合理地使用硬體資源,從而做到在吞吐量、併發量以及響應速度、處理速度等方面得到顯著的提升。引數類最佳化整體可以分為如下:

(1)OS級別的最佳化:包括作業系統型別選擇(Windows/Linux)、核心更新升級(如需)、核心引數、網路引數、安全引數等(如:系統開啟檔案最大數、最大程式數、關閉路由包轉發、處理無源路由包、最佳化訊息佇列長度、設定最大記憶體共享大小、Timewait數量、最佳化swap、最小化安裝作業系統關閉無用軟體服務和埠等),另外OS級別的最佳化還可以根據業務型別將日誌類、備份類的儲存硬碟與業務盤隔離劃分,降低讀寫壓力,提高儲存的IOPS。

(2)中介軟體引數最佳化:主要是應用系統所執行的中介軟體環境,如Weblogic、Tomcat等。選型方面在這裡不對Weblogic和Tomcat進行詳細對比,但大多情況下,可以使用Tomcat對Weblogic進行替代(切身經驗,一般更換起來不難),省錢,維護且方便。以Tomcat為例,主要引數最佳化有:對執行緒池、最大執行緒數、JVM、聯結器方式(bio、nio 和 apr,三種方式效能有差別,一般來說apr 的效能相對最優)、日誌最佳化(減少debug日誌輸出等)、日誌切割(日誌如未最佳化切割,單檔案較大,超過10幾G時,寫入讀取會降低)等。

(3)資料庫引數最佳化:在OS引數最佳化的前提下,對資料庫引數進行最佳化,主要包括(以Oracle為例)sga、pga、shared_pool_size、db_cache_size、sort_area_size、processes、session等。另外還需要對密碼大小寫、密碼失效次數、動靜態監聽、資料庫備份等方面進行相應的最佳化設定。

實際上,技術方面的最佳化多在系統部署上線前進行的,與業務方面關係不是很大,切多為通用的最佳實踐,按照相應的官方手冊文件結合自身實際經驗,大多可以調整最佳化為一個相對不錯的環境。但在日常工作中,當出現效能問題的時候,很多人會選擇最佳化硬體升級而忽略引數方面最佳化,導致硬體升級的成效不大,這一點是要額外注意的,需要透過作業系統、中介軟體和資料庫等方面的引數最佳化,最大化、最合理的挖掘和使用硬體資源,為應用系統和資料提供最佳、最優執行環境。

二、業務最佳化

業務最佳化是指在業務人員和業務場景的配合下,提供相關技術手段對應用系統、資料庫等進行最佳化,整個最佳化過程與業務邏輯規則聯絡密不可分。大致可以有:sql最佳化、程式碼最佳化、架構最佳化等幾個方面。

1、sql最佳化

sql方面的最佳化除了監控資料庫執行緩慢的sql對其進行索引最佳化外,還包括sql改寫、hint函式等方面的最佳化。對sql進行監控(慢查詢、AWR等)和最佳化索引(索引的新增、重建或刪除等,索引的型別選擇等)可以獨立持續進行,但也要避免單表索引太多(單標超過5個)、索引型別濫用(B-tree索引和點陣圖索引)、索引失效未及時重建等情況。另外可以在開發的配合下,對慢sql進行最佳化改寫、拆分以及hint函式(特別是併發函式/*+parallel(t,4)*/,但也注意不要濫用)的除錯,這一塊實際上在執行時間較久的傳統企業核心系統上比較難以實現,正如對於執行的系統,對資料庫的庫、表設計方面的最佳化設計已難以實現。所以,大多sql層面的最佳化在索引最佳化處即截停。

2、程式碼最佳化

程式碼最佳化主要指在系統研發人員的主導配合下進行,包括兩個方面的最佳化:一個是配合上述sql最佳化對程式碼中的sql進行最佳化改寫,提高sql執行的效率,獲得最佳化收益;另外一個是對程式碼中的邏輯架構進行最佳化,包括複雜邏輯架構拆分、序列業務並行執行、程式碼型別簡潔等等。程式碼層面的最佳化如資料庫的庫表設計最佳化一樣,就多數傳統企業來說,在系統產品進行部署上線後,改變較難。

3、架構最佳化

架構最佳化包括兩方面:業務架構最佳化和系統架構最佳化,是標本兼治的方法,但也正如前面所言,對於業務量和業務方向變化不大、且無明顯可帶來贏利創新的大多傳統企業而言,架構最佳化應該是一種較為激進的做法,激進之處在於對傳統企業的業務架構和系統架構進行了全面的推翻重構,尤其是在業務人員尚能接受系統緩慢、卡頓的前提下,對業務和系統進行大規模的最佳化和重構,大多會帶來不穩定的因素。

如果剝離業務最佳化只是對系統架構方面進行最佳化,特別是盲目推崇微服務對傳統企業進行重構變革的,大多可能會以失敗告終。可能是由於自身幾次工作經驗和所處行業有關,對系統的架構最佳化、重構和升級多以保守、謹慎的態度,見過太多傳統企業欲憑藉IT進行業務重構,最終業務和技術雙失敗的案例。業務和系統是圍繞企業健康發展相輔相成的兩個緊密元素,任何一個方面的超速發展,都將對另一個方面造成重大的影響。

本著嚴謹的態度,如果要對架構(包括業務架構和系統架構)進行最佳化,那麼有如下幾個問題建議優先考慮清楚:

(1)此次架構最佳化或重構的目的是什麼,要獲得一個什麼樣的收益。即建議結果為導向,結果指導思路和方法。

(2)為完成此次架構的最佳化或重構,達到預定目標,最佳化或重構的方案是什麼,需要投入的成本是多少,時間成本、人力成本、學習成本等。

(3)結合IT發展規律和生命週期,此次架構的最佳化或是重構,可以滿足企業多久的發展需要。

(4)結合投入成本和預定目標,是否有一個科學、合理,對企業有益的投入產出比。

其實架構的最佳化重構也不是很難,在牛逼的業務專家配合下,理清各個業務邏輯和相互之間關係,再由研發工程師根據積木式的業務塊進行服務化改造,為進一步降耦、提高系統併發,輔之以快取、訊息佇列、前後端分離和動靜分離等常規手段進行,一套分散式、服務化的架構也就基本完成了對經典單體應用的重構,如果後續業務變化較頻繁,系統更新發布頻率較高,還可以進一步完善微服務基礎設施,如:配置中心、鏈路監控、基於Jenkins的持續釋出以及容器化等。

綜上所述,就大多傳統企業核心系統最佳化的業務最佳化方面而言,除了在慢sql上加加索引外,其程式碼最佳化、架構最佳化等相對較為複雜、可執行性較低,且存在一定風險。實則,還有一種基於資料庫方面的最佳化辦法,該方法是在一定業務規則條件下,持續地保持生產資料“瘦身”,不斷壓縮生產資料庫的資料量,達到在小資料量下的快速查詢響應,具體如下:

對資料庫進行兩步拆分,第一步實現資料庫的主備同步(Oracle可使用DG,Mysql可使用Replication),主庫實現讀寫(R+W)功能,備庫或從庫主要實現讀的功能;第二步透過ETL的方式,將主庫中的歷史資料、可按時間或按業務規則進行歸檔的資料抽取至資料歷史庫中。透過兩步實現資料庫的讀寫分離和資料歸檔,將主庫的資料量減少降低,實現資料“瘦身”,兩個方面來有效地提升資料庫的響應速度。

在落地實施方面,正如前面介紹的,第一步搭建資料庫的同步備庫,相應搭建部署方式可以參考附件;第二步實施需要分為三步:ETL的部署,抽取規則執行,ETL定時執行。相信在業務規則配合下,可以快速的完成資料的抽取和資料處理,將原來龐大的主庫在較短時間內瘦身成敏捷的小庫,在業務量發展較為穩定的情況下,可以使得系統快速執行2-3年。

在上述基礎上,還可以對資料庫方面在做文章,如將主庫改造為Cluster叢集(Oracle為RAC,MySQL為Cluster)的方式,實現讀寫負載均衡,在叢集的基礎上搭建同步備庫,實現讀寫分離,特別是mysql的情況下,可以充分利用資料庫中介軟體進行讀寫分離、負載均衡等,同時也可以在資料庫層面進行分庫分表。歷史庫也可以再次剝離歷史資料,形成歷史庫的歷史庫。具體架構可參考如下:

基於資料瘦身的最佳化思路,其最佳化演進路線可參考如下:

該最佳化思路主要在一定業務規則下,對主資料庫的資料進行持續的資料瘦身,同時結合資料庫的主備同步實現資料的讀寫分離,有效地減緩主庫的讀寫壓力,進而達到系統最佳化的目標。嚴格來說,這也不是一種治根的方法,但就最佳化過的幾起案例來看,行之有效,其實一家傳統企業基於該模式,系統正常執行已經超過3年(前提是其業務未有大的增長)。

三、總結

系統最佳化從來都是一個持續漸進的過程,而且往往難以衡量,有的時候一個sql索引的新增,系統就變得飛速,也有的時候用盡一些列最佳化套路,系統終究沒有明顯改觀,這是一個痛苦的過程,大家應該平常心對待,持續最佳化、持續總結,逐漸形成自己的最佳化思路。當然,對業務和系統進行重構是一個大招,但也並不是標本兼治的絕招,服務化的系統相對傳統的、變化不大的業務來說會增加維護的複雜度,因此需要在回答了上述3架構最佳化的4個問題後在進行架構的重構工作,可能收效會好一些。

除了上述最佳化方法外,實際上還有一些其他的路數,如增加資料庫的鎖等待監控、定時清除inactive的連結、將虛擬化部署改為物理機部署、最佳化備份方式等等。

來自 “ twt企業IT社群 ”, 原文作者:zhanxuechao;原文連結:https://mp.weixin.qq.com/s/Cu2sleGRkJM5xgXQlU89uw,如有侵權,請聯絡管理員刪除。

相關文章