国产精品久久国产精麻豆99网站,激烈18禁高潮视频免费,老师含紧一点h边做边走视频动漫,双乳被一左一右的吸着

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

作者介紹

馬陽陽:去哪兒網(wǎng)基礎(chǔ)架構(gòu)組資深開發(fā)工程師、公司云原生 SIG 成員,專注于云原生、效能領(lǐng)域。負責(zé)組件市場、測試環(huán)境治理平臺 Noah、代碼瘦身平臺。優(yōu)化過 Noah,使環(huán)境構(gòu)建成功率提升 35%、耗時降低 30%。22 年深度參與的“線上服務(wù)瘦身50%”項目獲得公司級技術(shù)型一等獎,指導(dǎo)多個團隊完成系統(tǒng)精簡,積累了大量經(jīng)驗。畢業(yè)后曾就職于 BES,從事 PaaS 云、DevOps 平臺開發(fā)工作。

一、背景

去哪兒早在 05 年就開始做機票相關(guān)業(yè)務(wù),在這十幾年間業(yè)務(wù)快速發(fā)展,后端系統(tǒng)也在不斷迭代,目前公司內(nèi)擁有大量五年以上的系統(tǒng)。為適應(yīng)快速變化,公司的組織架構(gòu)調(diào)整和人員流動較多,導(dǎo)致目前開發(fā)者們維護的系統(tǒng),大部分都是交接過來的,對系統(tǒng)全貌掌控力有限。

另一方面,公司的很多業(yè)務(wù)具備短周期特征,比如臨近五一假期了,我們會在去哪兒旅行 App 上增加五一相關(guān)的活動業(yè)務(wù)。一旦五一假期結(jié)束后,這些業(yè)務(wù)會立刻被下掉,不再產(chǎn)生實際價值。而對應(yīng)的后端代碼并不會清理,這就產(chǎn)生了一個有趣的現(xiàn)象,我們的代碼只增不減、系統(tǒng)復(fù)雜度單調(diào)遞增。

隨著時間的推移,維護和優(yōu)化現(xiàn)有代碼的耗時會越來越多,導(dǎo)致開發(fā)新業(yè)務(wù)的時間減少,業(yè)務(wù)開發(fā)越來越慢,跟不上業(yè)務(wù)發(fā)展的速度,急需解決!

從數(shù)據(jù)上看,公司有數(shù)千個常用應(yīng)用,數(shù)千萬行代碼,平分到每個開發(fā)者頭上,人均要維護多個應(yīng)用、十幾萬行代碼,可以感受到這個維護負擔是比較重的。

如何解決維護成本高、業(yè)務(wù)迭代慢的痛點呢?我們在去年全年開展了系統(tǒng)瘦身項目,制定了兩個目標指標,對全司代碼、全司應(yīng)用均精簡 50%,也就是都砍掉一半。要完成這個目標,有三個很大的挑戰(zhàn):

  • 目標定的非常高,需要在一年內(nèi)刪除掉千萬余行代碼;
  • 這是全司級別的項目,牽扯幾十個業(yè)務(wù)團隊、幾千個線上應(yīng)用,如何在這么廣的影響范圍下,高效、低風(fēng)險地達成目標,將是個挑戰(zhàn);
  • 網(wǎng)上找不到可以參考的案例,這就要求我們要有很強的創(chuàng)造力和技術(shù)實力。

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

要實現(xiàn)這個目標,我們做了兩個規(guī)劃:

  1. 時間上,分兩階段,從 5 月份到 6 月底進行服務(wù)精簡,從 7 月初到 11 月底進行代碼精簡。之所以服務(wù)放在前面,是因為服務(wù)精簡的同時也會帶來代碼的精簡;
  2. 架構(gòu)上,將整個目標分配到各個業(yè)務(wù)線,每個業(yè)務(wù)線完成 50% 精簡的目標,分而治之。另外,創(chuàng)建了一個虛擬組織“瘦身技術(shù)支撐團隊”,提供通用瘦身工具和技術(shù)支持,加速業(yè)務(wù)線的瘦身效率。本人也是該虛擬組織中的一員。

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

接下來依次對服務(wù)精簡、代碼精簡做詳細介紹,會先分析可以被精簡的資源有什么通用特征,然后利用這些通用特征批量、自動化地找到可能能被精簡的資源全集,這個過程稱之為 “找得到”;有了目標全集之后,進行正真的精簡,也就是要 “刪得好”。

二、服務(wù)精簡實戰(zhàn)

1、可精簡服務(wù)特征分析

在進行服務(wù)精簡實戰(zhàn)之前,需要先分析出可精簡服務(wù)所具備的特征,有了一些通用的特征后,就能根據(jù)特征批量找到全部的目標服務(wù)。

服務(wù)精簡的手段有兩種,合并服務(wù)和刪除服務(wù),這兩種手段所處理的服務(wù)特征不一樣,因此分開進行分析。

合并服務(wù)

哪些服務(wù)能進行合并?想直接回答這一問題并不容易,可以反過來思考,哪些服務(wù)要進行拆分?開發(fā)同學(xué)對微服務(wù)拆分都很熟悉,常見拆分原則有單一職責(zé)、界限上下文、復(fù)用性、自治性等等,常見服務(wù)拆分維度有 “業(yè)務(wù)” 和 “質(zhì)量”,根據(jù)業(yè)務(wù)拆分的常見手段包括:

  • 按業(yè)務(wù)域:賣票和售后屬于不同業(yè)務(wù),在微服務(wù)架構(gòu)中考慮拆分成兩個微服務(wù)
  • 按業(yè)務(wù)流程:對于訂單業(yè)務(wù),按流程可以拆分成 生單、計費、支付、物流、通知 等多個子服務(wù)
  • 按業(yè)務(wù)重要性:訂單業(yè)務(wù)一般是核心業(yè)務(wù);評價業(yè)務(wù)則沒那么重要,所以訂單和評價通常是兩個微服務(wù)

根據(jù)質(zhì)量拆分的常見手段包括:性能、穩(wěn)定性、可用性、安全邊界、異構(gòu)等。

理論上,規(guī)避了上述服務(wù)拆分特征的服務(wù)就允許進行合并。

判斷當前服務(wù)是否符合服務(wù)合并的特征,需要對服務(wù)所提供的業(yè)務(wù)有深刻理解才能進行判斷,難以通過已有的數(shù)據(jù)資產(chǎn)分析得出,只能是系統(tǒng)開發(fā)者進行判斷,因此服務(wù)合并主要由各業(yè)務(wù)線自行推進。

刪除服務(wù)

哪些服務(wù)能被直接刪除?從業(yè)務(wù)價值角度很容易得出結(jié)論,無價值甚至低價值服務(wù)可以進行刪除,更為具體的表現(xiàn)有三種,滿足其中一種就可能是低價值服務(wù),注意是 “可能而非一定”

  • 沒流量:服務(wù)雖然在線上,但沒有業(yè)務(wù)流量,業(yè)務(wù)價值自然是低的
  • 不迭代:這個特征不好理解,可以通過價值模型加深理解。價值分為 “存量價值” 和 “增量價值”,服務(wù)一旦沒有迭代,就沒有了增量價值。先利用這個特征將服務(wù)掃出來,再人工判斷一下其存量價值,如果存量價值較高那么就不做刪除,反之則反
  • 已下線:服務(wù)已經(jīng)下線了,但沒有被刪除

判斷當前服務(wù)是否可被刪除,是可以通過已有數(shù)據(jù)分析得出的,因此作為瘦身基礎(chǔ)支撐團隊,提供了兩個通用工具,第一個工具的作用是 “找得到”,即找出符合特征的服務(wù)全集;第二個工具的作用是“刪得好”,自動化將服務(wù)進行刪除。最終達到快速刪除服務(wù)的作用,下面對 “找得到”、“刪得好” 進行介紹。

2、找得到

現(xiàn)在需要按照之前分析得出的特征,通過已有數(shù)據(jù)資產(chǎn),批量找到符合特征的服務(wù),這些服務(wù)就是最終要刪除的備選目標。

沒流量

將流量全集分為三類:

  • 南北方向流量:南北方向流量通常是指從客戶端到服務(wù)器端的流量,也就是來自于外部用戶或者應(yīng)用的請求流量,它通過負載均衡器或API網(wǎng)關(guān)被路由到不同的微服務(wù)實例上
  • 東西方向流量:東西方向流量通常是指微服務(wù)之間的內(nèi)部通信流量,也就是微服務(wù)之間的請求和響應(yīng)流量,這種流量通常發(fā)生在內(nèi)部微服務(wù)的調(diào)用或者微服務(wù)之間的數(shù)據(jù)交換過程中。這里我將東西間流量進一步細分,拆成兩類:
    • 東西方向 – 服務(wù)之間流量
    • 東西方向 – 單服務(wù)內(nèi)流量

三類都沒有流量則可以認為服務(wù)是完全沒有流量的,盡可能保證判斷的全面性。

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

針對每種類型,可以通過分析現(xiàn)有數(shù)據(jù)資產(chǎn),來得出是否有特定類型的流量。

  1. 根據(jù)網(wǎng)關(guān)的歷史訪問日志,可以找出一段時間內(nèi),沒有南北向流量的服務(wù)集
  2. 根據(jù)歷史 Trace 的拓撲信息,可以分析出一段時間內(nèi),沒有東西向服務(wù)間流量的服務(wù)集
  3. 最后,根據(jù)服務(wù)是否有生效的定時任務(wù),可以找出沒有服務(wù)內(nèi)流量的服務(wù)集

最終對這三個集合取交集,即為全部 “沒流量” 的服務(wù)。

不迭代

從業(yè)務(wù)上看,不進行服務(wù)迭代有兩種可能,業(yè)務(wù)非常穩(wěn)定了不需要迭代、業(yè)務(wù)不值得再花時間迭代。無論哪種情況,不迭代的具體表現(xiàn)是沒有變更,同時滿足下面兩種情況我們就認定服務(wù)是無變更的:

  1. 代碼無變更:根據(jù)發(fā)布系統(tǒng)中的發(fā)布記錄,找到一段時間內(nèi)沒有代碼發(fā)布、或發(fā)布次數(shù)很少的服務(wù)
  2. 配置無變更:根據(jù)分布式配置中心的變更記錄,找到一段時間內(nèi)沒有配置發(fā)布、或發(fā)布次數(shù)很少的服務(wù)

已下線

服務(wù)是否已下線 很好判斷,只需要取一下當前全部服務(wù)的狀態(tài),篩選出下線的服務(wù)。為了更精準,可以取兩個時間點的狀態(tài),這兩個時間點要有一定的跨度,當兩個時間點服務(wù)都是下線狀態(tài),則判定服務(wù) “已下線”。

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

3、刪得好

找到了全部可能可以被刪除的服務(wù)后,接下來就是刪服務(wù)了,刪服務(wù)要保證三個點:

  • 刪得準:禁止誤刪
  • 刪得全:刪除服務(wù)時,要把服務(wù)相關(guān)資源都清理掉,比如服務(wù)的域名、機器等
  • 刪得快:刪除服務(wù)的效率要高

為此,我們制定了服務(wù)刪除標準流程,搭建了 “應(yīng)用瘦身平臺”。

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

在流程中增加人工確認步驟,保證 “刪得準”;整理服務(wù)刪除所牽扯的相關(guān)資源清理過程,沉淀到瘦身平臺中,通過設(shè)計服務(wù)刪除全流程 與 自動化刪除能力,保證 “刪得全” 和 “刪得快”。

平臺的關(guān)鍵設(shè)計點是服務(wù)刪除的流程標準化,我們將服務(wù)刪除分為了四個周期、十個步驟,全流程如下圖:

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

三、代碼精簡實戰(zhàn)

1、可精簡代碼特征分析

精簡代碼的思路和精簡服務(wù)一樣,從已知的、具體的操作入手,分析出可精簡代碼的通用特征,然后基于特征、利用工具批量找到可精簡代碼全集,最后執(zhí)行精簡代碼的操作。

常見的可精簡代碼方法有三個:

  • 靜態(tài)代碼分析,刪掉未被調(diào)用的方法。在 IDEA 里對這類方法是直接能提示出來的
  • 重構(gòu)代碼,包括簡化代碼寫法、精簡邏輯、減少重復(fù)代碼等
  • 想辦法找出 長期沒有線上流量的代碼,這些代碼大概率是能被刪除的

這三個手段都能精簡掉代碼,但效果并不一樣,因此我抽象了兩個指標,從 ”量大“ 和 ”通用性“ 上來評估每個手段的優(yōu)劣。為什么是這兩個指標,意義何在?“量大” 決定了能刪除的代碼數(shù)量,“通用性” 影響的是能否自動化進行,決定了刪除代碼的效率,最終會先選擇同時具備這倆指標的手段,這樣能最快的刪除最多的代碼,具體的評估數(shù)據(jù)如下圖:

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

通過對已有代碼的全量度量,我們發(fā)現(xiàn) “靜態(tài)未被調(diào)用的方法” 占比是很少的,因此量不大

重構(gòu)是件復(fù)雜的事情,有時涉及到架構(gòu)重構(gòu),牽扯多個微服務(wù),需要對業(yè)務(wù)很熟悉,所以只能由業(yè)務(wù)線同學(xué)自行推進,難以找到通用的手段 自動完成重構(gòu);重構(gòu)能減少的代碼行數(shù)是很多的,因此這也是達到最終目標的抓手之一

經(jīng)過實際的代碼分析,發(fā)現(xiàn)沒有流量經(jīng)過的代碼是很多的,尤其對于歷史悠久的系統(tǒng),以及活動類的系統(tǒng),業(yè)務(wù)沒了但代碼通常不會刪掉,這就產(chǎn)生了大量無流量的廢棄代碼。對于如何找到這些無流量的代碼,并進行刪除,都具有通用性,因此作為工具平臺組,我們在這個方面做了大量工作,也是分為 “找得到” 和 “刪得好”,下面依次進行介紹

2、“找得到” 方案選型

常規(guī)方案

需要通過技術(shù)手段找到?jīng)]有線上流量的代碼,比較容易想到的方案有兩個:

1、AOP

利用 Java 中的 AOP 技術(shù),動態(tài)增強每個方法,在其中增加訪問計數(shù)邏輯,將源碼中的方法全集減去有計數(shù)的方法,得到?jīng)]有線上流量的方法,示例代碼如下:

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

2、Agent 字節(jié)碼插樁:

通過自實現(xiàn) Agent,對源碼進行字節(jié)碼插樁,增加記錄訪問日志的邏輯,并在 JVM 啟動時設(shè)置 -javaagent 參數(shù)來加載 Agent,剩下 “計算沒有線上流量的方法” 和 AOP 方案類似,不再贅述。流程圖如下:

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

上面兩個方案比較容易想到,除此之外,我們找到了第 3 個方案,基于 SA 工具

3、SA 方案

先不著急介紹 SA 是什么,而從我們熟悉的入手,一步步推理、引出 SA。

在 JVM 中,Java 代碼可以通過解釋執(zhí)行(Interpreted Mode)和編譯執(zhí)行(Compiled Mode)兩種方式來運行,默認情況下使用混合模式(Mixed Mode)來運行應(yīng)用程序,即 將解釋執(zhí)行和編譯執(zhí)行相結(jié)合。JVM 在應(yīng)用程序啟動時會先進行解釋執(zhí)行,同時使用即時編譯器來編譯熱點代碼。當熱點代碼被編譯執(zhí)行后,就可以使用本地代碼來代替解釋執(zhí)行,從而提高應(yīng)用程序的性能。如果有新的熱點代碼出現(xiàn),即時編譯器會對其進行編譯執(zhí)行。

那么 JVM 如何判斷出熱點代碼?猜測一下,有一個方法粒度的計數(shù)器,統(tǒng)計了方法執(zhí)行次數(shù),當這個次數(shù)超過閾值時觸發(fā)編譯。

通過查看 hotspot 源碼完成了驗證,在 Method 類中確實有方法計數(shù)相關(guān)的字段。

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

有辦法通過 java 代碼讀取到 JVM 中方法計數(shù)相關(guān)的字段嗎?我們找到了一個工具 Serviceability Agent,這是 JVM 開發(fā)者為了調(diào)試 JVM 而制作的工具 Agent,主要功能是暴露運行時 JVM 中的 Java 對象和數(shù)據(jù)結(jié)構(gòu),因此它能把 JVM 中 Method 對象的全部字段都暴露出來,使用 Java 代碼進行讀取。

SA 官方介紹地址:https://openjdk.org/groups/hotspot/docs/Serviceability.html

SA 并不高深,常見的 JVM 工具 如 jstack、jmap,底層也是用了 SA

方案選型

對于上面三個方案的選型,從三個維度進行評估:

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

對于方法執(zhí)行的計數(shù),SA 方案利用 JVM 已有機制就記下來了,因此該方案可以達到 對業(yè)務(wù)服務(wù)沒有任何性能損耗的效果,零風(fēng)險。并且拿到的直接是方法執(zhí)行次數(shù),不需要額外的計算和聚合,實現(xiàn)復(fù)雜度低,因此最終選用了 SA 方案。

從結(jié)果上看,SA 方案確實非常好,最大優(yōu)點就是零風(fēng)險,整個項目推進過程中,沒有產(chǎn)生過任何故障。

3、SA 方案詳細設(shè)計

本節(jié)將對 SA 方案中的幾個關(guān)鍵設(shè)計點進行詳細介紹。

性能無損跑數(shù)

使用 SA 對運行中的 JVM 進行方法計數(shù)探測,這個過程稱之為 “跑數(shù)”。直接使用 SA 觀測線上的 JVM 是會對性能有影響的,因為在探測期間,用戶線程處于 STW 狀態(tài),內(nèi)存占用也會適當增加,想要做到完全的性能無損跑數(shù),需要利用好服務(wù)上下線,具體過程如下圖:

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

首先隨機挑選一個線上的實例,進行實例下線,下線只會讓線上流量不再打到該實例上,JVM 還是跑著的。然后對下線后實例,使用 SA 進行跑數(shù),完成跑數(shù)后等待幾分鐘,對實例進行上線,這樣就不會因為跑數(shù),而對線上流量有性能影響了。

跑數(shù)有三個避坑點需要注意:

SA 跑數(shù)時會消耗一定內(nèi)存,因此在跑數(shù)前 JVM 必須留有足夠的剩余內(nèi)存(通常 大于 500M),這樣才能成功跑出數(shù),否則 JVM 會發(fā)生 OOM 甚至長時間卡住的問題

服務(wù)必須是多實例的,對于單實例服務(wù)直接跑數(shù)會導(dǎo)致服務(wù)全部下線,影響業(yè)務(wù)。這種情況建議擴容到多個實例,或者放棄跑數(shù)

有時 prod 類型的環(huán)境會有多個,它們使用的是同一份代碼,此時需要對每個環(huán)境都挑實例進行跑數(shù)

跑數(shù)代碼實現(xiàn)

SA 就是一個 jar 包,提供了觀測 JVM 的 API,本節(jié)主要介紹跑數(shù)的代碼實現(xiàn)。

JVM 對于解釋執(zhí)行和編譯執(zhí)行,方法的結(jié)構(gòu)是不一樣的,因此需要區(qū)分處理,代碼如下:

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

代碼中的 API 運用了觀察者模式,其中 InvocationCounterVisitor 和 CompiledMethodVisitor 是我們自定義的觀察者,兩者的邏輯類似:

  1. 實現(xiàn)觀察者的接口,實現(xiàn)核心的觀察(visit)方法
  2. 通過方法入?yún)?,獲取到 Method 對象
  3. 從 Method 對象中取出方法計數(shù)器值,保存到結(jié)果集中

核心代碼如下圖:

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

計算可精簡方法集

跑一次數(shù),能探測到 “從 JVM 啟動到跑數(shù)時刻” 這段時間內(nèi),每個方法的執(zhí)行次數(shù)。跑完數(shù)之后,得到了一個方法集合,包含方法標識、執(zhí)行次數(shù)等信息:

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

但是僅跑一次數(shù)是不夠的,可能在 “從 JVM 啟動到跑數(shù)時刻” 這段時間之后,有方法被第一次執(zhí)行了,此時就會產(chǎn)生遺漏。因此要多次、有時間跨度地跑數(shù),比如每天跑一次,持續(xù)跑一個月,這樣才能獲取到更準確的數(shù)據(jù),減少遺漏概率。

有了多次跑數(shù)結(jié)果后,現(xiàn)在開始計算 “可精簡方法集”。首先,要對多次的跑數(shù)結(jié)果取并集,獲得全部 “有流量的方法集”;然后,分析工程源碼,利用開源工具(如 Spoon)獲取 “工程方法全集”;最后,在 “工程方法全集” 中排除掉 “有流量的方法集”,得到最終的 “可精簡方法集”,過程如下圖:

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

校準可精簡方法集

如之前所述,采用了隨機抽取實例進行跑數(shù)的方式,這就可能產(chǎn)生遺漏問題,例如:某服務(wù)線上實例個數(shù)為 600 個,有一個定時任務(wù)定向的分發(fā)到指定的一臺機器上,此時理想情況下,隨機跑數(shù) 600 次后就會命中一次定時任務(wù)所在的實例,抓取到定時任務(wù)方法的執(zhí)行記錄。但很有可能,跑了 600 次也沒跑到定時任務(wù)所在的機器,這就產(chǎn)生了有流量方法集的遺漏,最終導(dǎo)致計算出來的可精簡方法集有誤判。

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

要解決這個問題,第一反應(yīng)是能不能對所有實例都跑數(shù)?這樣一定能避免遺漏,但根據(jù)實際經(jīng)驗,這種方式風(fēng)險過高,試想一下,每天跑一次數(shù),每次都需要把服務(wù)的全部實例輪著下線、上線一遍,操作之繁瑣、風(fēng)險之大可想而知。

我們最終使用的方案是,對于 SA 跑出來的可精簡方法集,在源碼層面、通過 IDEA 批量加上打點(具體如何增加,下文會介紹),發(fā)布到線上后再跑一段時間,根據(jù)打出的點校準可精簡方法集,這樣就能確保百分百的準確性了,在代碼中增加的打點如下圖:

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

源碼中加打點,不會帶來性能損耗嗎?確實存在損耗,但基本可以忽略不計,因為這些要加打點的方法,是 SA 長期跑出來的可精簡方法集,代表方法執(zhí)行頻率極低甚至沒有,因此對這些方法增加打點,能產(chǎn)生的性能影響極少。

4、整體方案

最后,將上面的點串聯(lián)起來看一下整體的方案,業(yè)務(wù)流程圖如下:

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

  1. 定時任務(wù)平臺,定期觸發(fā)瘦身服務(wù)的跑數(shù)邏輯
  2. 瘦身服務(wù)通過發(fā)布平臺,隨機下線一臺實例
  3. 瘦身服務(wù)通過 salt 平臺,下發(fā)跑數(shù)的腳本任務(wù)
  4. 在已下線的實例上完成跑數(shù),將結(jié)果上報到瘦身服務(wù)
  5. 瘦身服務(wù)將跑數(shù)的原始結(jié)果(每個方法的執(zhí)行次數(shù)等信息)進行存庫
  6. 瘦身服務(wù)通過發(fā)布平臺,將下線的實例進行上線
  7. 瘦身服務(wù)克隆源碼,獲取 “工程中方法全集”
  8. 從打點監(jiān)控平臺(watcher)上取到全部瘦身相關(guān)打點,轉(zhuǎn)換成有打點的方法集合
  9. 將 SA 跑出的結(jié)果方法集 和 有打點的方法集,從 工程方法全集 中排除,得到最終的 “可精簡方法集”,存庫

5、刪得好

代碼想要刪得好,自動化就少不了。我們設(shè)計并提供了兩種代碼刪除方式,分為 全自動 和 半自動,以適配不同重要性的業(yè)務(wù)團隊。

全自動

整個代碼刪除過程完全自動化,包含 克隆代碼、創(chuàng)建瘦身分支、刪除可精簡代碼、推送分支 4 個步驟。最后需要開發(fā)同學(xué)進行 CR,沒問題后走后續(xù)的驗證、發(fā)布過程。

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

刪除代碼時有個注意點,需要保證刪除后的代碼可正常編譯。如果直接刪除方法簽名和方法體,就可能導(dǎo)致無法分支無法正確編譯,這是不能被接受的。

半自動

在全自動方案中,開發(fā)者只有在最終 CR 時才能看到被刪除的代碼,此時如果有大量需要恢復(fù)的代碼,操作起來會比較麻煩,需要手動回滾。同時,為了讓開發(fā)對刪除的代碼有更強的掌控力,因此設(shè)計了半自動方案。

半自動方案中,我們開發(fā)了一個 idea 插件,該插件能掃出可精簡的方法集合,提供批量刪除方法、置空方法體、增加打點等功能。開發(fā)者利用該插件,手動、高效地進行代碼刪除工作,并且對每個方法都有精確掌控,風(fēng)險更低。

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

驗證

代碼刪完、人工 CR 確認后,仍需要做好測試、驗證工作 才能最終發(fā)布到線上,具體包含以下六個步驟:

  1. beta 發(fā)布:先在 beta 環(huán)境進行發(fā)布
  2. 自動化測試:自動化測試平臺對精簡后的服務(wù),在 beta 環(huán)境完成自動化測試
  3. 故障演練:故障演練是為了保障強弱依賴沒有問題
  4. 灰度發(fā)布:保險起見,對線上環(huán)境先進行灰度發(fā)布,并進行觀察
  5. 全量發(fā)布:灰度發(fā)布、觀察沒問題后,進行全量發(fā)布
  6. 觀察指標:全量發(fā)布完成后,需要對各種指標觀察一段時間,發(fā)現(xiàn)問題及時回滾

四、最終效果

最終我們成功精簡了 49.87% 的代碼,代碼總量減少超千萬,取得了超預(yù)期的效果,具體如下:

  1. 開發(fā)估時平均降低約 10.9%:在刪除冗余代碼、精簡系統(tǒng)后,每個需求的估時和開發(fā)耗時明顯降低,預(yù)計每年可以節(jié)省近萬 PD 成本;
  2. 發(fā)布效率提升約 9.5%:代碼大量減少后帶來了更快的發(fā)布速度,從克隆到編譯到運行,各階段耗時均有縮短。單次提升看似有限,但實際每月有幾萬次發(fā)布,綜合收益是很可觀的。

綜上所述,系統(tǒng)瘦身是一項有價值的工作,且實際價值超出預(yù)期。

狂砍千萬行代碼,零故障!去哪兒網(wǎng)系統(tǒng)瘦身技術(shù)揭秘(去哪兒網(wǎng)功能介紹)

五、未來展望

前面分別從服務(wù)精簡和代碼精簡角度,分別介紹了特征分析、找得到、刪得好、實施經(jīng)驗,希望能夠幫助大家將代碼量降下來,降低維護成本,提升開發(fā)效率。在未來,還有以下五個方面的工作可以繼續(xù)探索和實施:

  • 代碼行粒度精簡:目前的方案是方法粒度的,更進一步可以細分為行粒度,有利于圈復(fù)雜度的降低
  • 長周期代碼精簡:一段代碼如果很長時間才執(zhí)行一次(如 一年一次),執(zhí)行的時候不在 SA 跑數(shù)期間,就會產(chǎn)生誤判,該方法應(yīng)該保留
  • 依賴精簡:對服務(wù)依賴的 jar 包進行精簡,減少依賴數(shù)量,避免依賴冗余、減少不兼容的情況
  • 配置精簡:清理服務(wù)所依賴的配置項
  • 服務(wù)合并:探索服務(wù)合并的通用路徑,完成自動化服務(wù)合并功能

作者:馬陽陽

來源:微信公眾號:Qunar技術(shù)沙龍

出處:https://mp.weixin.qq.com/s/H-QedPzfsT88w0n33g6ZhA

版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 舉報,一經(jīng)查實,本站將立刻刪除。

大肉大捧一进一出好爽视频| 蜜臀av在线播放| 久久久精品| 国产亚州精品女人久久久久久| 中文字幕乱妇无码av在线| 国产av一区二区三区传媒| 欧美性猛交╳xxx富婆| 狠狠色噜噜狠狠狠888米奇视频| 日韩精品视频一区二区三区| 国内精品无码一区二区三区| 免费观看完整视频app| 教室停电h嗯啊好硬好湿| 适合女士自慰时看的黄文| 隔壁邻居是巨爆乳寡妇| 巜年轻的公和我做愛| 国产日产欧产精品| zoz○zo女人和另类zoz0| 亚洲色欲综合一区二区三区| 图片区小说区激情区偷拍区| 国产精品无码翘臀在线观看| 不卡无在线一区二区三区观| 成人小说亚洲一区二区三区| 国产乱人伦偷精品视频免下载| 把她日出水来好爽太紧了| 大香线蕉伊人久久爱| 国产精品亚洲欧美大片在线观看 | 国内精品乱码卡一卡2卡三卡| 日本午夜精品一区二区三区电影| 国产亚洲精品麻豆一区二区| 少妇spa按摩按出水了| 亚洲欧洲日产v| 无码精品一区二区三区在线| 成人欧美一区二区三区1314| 亚洲国产成人片在线观看| 午夜时刻免费入口| 夜夜爽妓女8888888视频| 97精品超碰一区二区三区| 中文字幕在线无码一区二区三区 | 亚洲加勒比久久88色综合| 亚洲午夜av久久久精品影院色戒 | 黑人大荫蒂高潮视频|