日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

蚂蚁构建服务演进史

發布時間:2024/8/23 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 蚂蚁构建服务演进史 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡介:?自動化構建和CI/CD往往是相輔相成的,可以理解為,自動化構建是溫飽問題,解決了溫飽就會有更多的提高生產力的訴求,也就是對應的CI平臺,CI/CD本篇文章不做擴展。

作者 | 琉克
來源 | 阿里技術公眾號

一 構建平臺的由來

只要是軟件開發就離不開構建,構建無處不在,構建是源代碼和用戶呈現之間的橋梁。

這里要澄清一點,構建 != 編譯,構建的本質是把源代碼翻譯成運行環境能識別的產物(源代碼可能是Java代碼,也可能是配置文件、資源文件等,運行環境可能是物理機,也可能是虛擬機,也可能是mobile phone)。

所以工程師每天每時每刻都在構建,不構建就沒法驗證。隨著規劃的擴大,把構建自動化掉,提供一個“打包平臺”也就是一個自然而然的事情,畢竟提高生產力是第一訴求嗎,這也就是構建平臺最開始的由來,把每天干的事情自動化掉,搬上平臺。

自動化構建和CI/CD往往是相輔相成的,可以理解為,自動化構建是溫飽問題,解決了溫飽就會有更多的提高生產力的訴求,也就是對應的CI平臺,CI/CD本篇文章不做擴展。

二 理解構建

構建 != 編譯,構建本身是一個很復雜的編排過程。舉兩個例子:

1 Android APK的構建過程

上圖中綠色部分為工具,淺藍色部門為源代碼+中間產物。可以看到是一系列的工具+輸入的編排,最終生成運行環境可識別的產物。上訴構建過程生成的產物(APK)可被Android手機識別并運行。

2 Java Jar包的構建過程

可以看到jar包的構建過程和上面APK的差異非常大,相對來說也是更簡單。

3 構建工具

上面兩個case可以看出來,構建本身很復雜,要最終構建出一個可以運行的產物需要做很多事情,我們完全可以手動javac copy jar等等一系列操作實現構建過程。但當工程越來越大,文件越來越多,這個事情就不是那么地令人開心了。這些命令往往都是很機械的操作。所以我們可以把這些機械的操作交給機器去做。對應的構建工具也應運而生,畢竟提高生產力是第一訴求。

拿Java舉例:

Ant

上面的示例中,Ant定義了五個任務:init、compile、build、test和clean。

每個任務做什么都定義清楚了。在打包之前要先編譯,所以通過depends來指定依賴的路徑。

如果在命令行里執行ant build,那就會先執行compile,而compile又依賴于init,所以就會先執行init。

執行命令:

ant test

通過命令就可以執行編程,打包,測試。為開發者帶來了很大的便利,提供了工作效率。

但是Ant有一個很致命的缺陷,那就是沒辦法管理依賴。

我們一個工程,要使用很多第三方工具,不同的工具,不同的版本。

每次打包都要自己手動去把正確的版本拷到lib下面去,不用說,這個工作既枯燥還特別容易出錯。為了解決這個問題,Maven如約而至。

Maven

Ant僅是一個構建工具,它并未對項目的中的工程依賴以及項目本身進行管理,并且Ant作為構建工具未能消除軟件構建的重復性,因為不同的項目需要編寫對應的Ant任務。
Maven作為后來者,繼承了Ant的項目構建功能,并且提供了依賴關系,插件機制,項目管理的功能,因此它是一個項目管理和綜合工具, 其核心的依賴管理, 項目信息管理, 中央倉庫,Maven的核心理念是約定大于配置。每一種類型都有固定的構建生命周期。

和ant的build.xml相對的,maven項目的核心是pom.xml,java開發同學肯定都很熟。

Gradle

Gradle已經拋棄了Ant、Maven中Xml配置的形式,取而代之的是Gradle采用了領域特定語言Groovy的配置。Gradle繼承了Maven中倉庫,坐標,依賴這些核心概念。文件的布局也和Maven相同。但同時,又繼承了Ant中target的概念,我們又可以重新定義自己的任務(在Gradle中叫做task)。

相比maven會更簡潔,比如在maven中要引入依賴:

轉換成gradle腳本:

dependencies {compile('org.springframework:spring-core:2.5.6')compile('org.springframework:spring-beans:2.5.6')compile('org.springframework:spring-context:2.5.6')compile('com.google.code.kaptcha:kaptcha:2.3:jdk15')testCompile('junit:junit:4.7') }

配置從原來的28行縮減至7行!效果驚人。

同時gradle在構建性能上也碾壓maven,gradle在maven的基礎上額外增加了增量構建、build cache、daemon等特性,大大提升構建時間。

類似的構建工具其實還有很多,基本屬于百花齊放,比如facebook的BUCK,Google的bazel等,國內也有一些廠商自己的構建工具,比如騰訊的blade。不同的工具都會有自己的優勢和劣勢。

三 構建平臺的演進

1 原始時代

其實最開始的訴求非常簡單,構建工具基本都是現成的,人少,功能簡單。所有構建基本都是手動。

  • 移動端:支付寶一個應用,一個倉庫,誰發版直接在個人電腦上拉取最新代碼執行編譯,發布app store。
  • 服務端:一臺物理機,一套構建腳本,誰要發布,直接登錄,輸入倉庫/分支信息,執行構建,然后發版。

2 自動化

顯然,隨著人員的增長,規模的擴大,原始時代根本無法支撐進一步發展,主要的矛盾:

  • 多人協作困難。
  • 多人搶占。
  • 個人機器構建的不穩定性,成功率極低。
  • 這一階段最大的訴求:項目管理/多人協作/自動化構建。應運而生兩個平臺:CP SCM。

    • CP主要負責項目管理,多人協作。
    • SCM主要負責代碼管理,構建任務調度,構建機器管理運維(SCM慢慢演變成一個大雜燴,jar包上傳管理,客戶端簽名,各種)。

    大概長下面這個樣子:

    初級階段

    這里構建比較大的難點還是在機器的管理和調度,其實做了很多事情:

    • 機器管理,增刪機器。
    • 機器保活,可用性監控。
    • 機器環境一致性的保障。
    • 機器構建負載均衡。
    • 構建腳本的統一升級維護。

    上面框架運行了一段時間后還是發生了很多問題,構建成功率越來越低,主要有幾個問題:

  • ssh通道是有連接數限制的,抽風性的ssh連接異常。
  • 負載均衡控制困難,機器之間負載經常不一致,構建時快時慢。
  • 機器配置管理難度大。
  • 進階階段

    其實這一塊,開源有非常成熟的方案 -- jenkins。我們干的很多的事情jenkins都已經幫我們干了。也能很好的解決我們遇到的痛點:

    • C/S架構,無ssh通道限制。
    • 自動控制負載均衡,機器監控。
    • 靈活的構建和任務配置。
    • 強大的開放能力和豐富的API。

    改造完大概長這樣:

    黑科技(填坑)

    這里要拋出一個新的概念「制品庫」。

    Java開發中,大家對maven、gradle這些工具肯定不能再熟悉了。前面講構建工具的時候講過,Java構建工具有幾代演進:Ant,Maven,Gradle。Maven之前的上古工具,用的人應該非常少了。

    在Maven之前,是不存在版本管理,依賴管理這種概念的,所有的東西都在你的倉庫。你的工程里面用到了gson,spring,log等開源框架和功能時,是需要去手動下載對應的jar包,然后放在代碼庫中。如果需要更新,需要不停去項目對應官網,下載最新發布的包。

    Maven之后的工具,提供了強大的依賴管理功能,只要在pom.xml寫上你要使用的依賴,maven會自動下載依賴,修改和升級只需要修改GAV坐標(groupid,artifactid,version),依賴的所有jar包都存儲在「制品庫」中。

    此時的構建大概長這個樣子:

  • 物理機緩存使用overlay文件系統,每次構建緩存獨立,防止公共緩存被刷入。
  • 監控制品庫的覆蓋記錄,生產delete task,快速通知物理機刪除公共緩存。
  • 記錄overlay文件系統upper層的增加記錄,記錄add task,定時刷入物理機公共緩存。
  • 存在的問題

  • 環境一致性保證,環境升級。
  • 復雜的腳本邏輯。
  • 理解下這兩個問題,隨著業務的迅速發展,接入的系統越來越多,APP越來越多,構建的環境越來越“胖”。

    比如:App除了支付寶,還有口碑,財富,香港錢包等,各個產品有自己的構建邏輯,也有自己的工具,比如支付寶用gradle4,口碑用gradle2。

    其它的技術棧也越來越多,Java,GO,C++等,需要不同的JDK版本,GO環境等。

    所有環境都塞進一臺物理機,這里存在兩個比較嚴重的問題:

  • 頻繁增加新的工具,如何確保不影響既有的環境和構建。
  • 環境不可復制,新的構建機器,初始化困難,很難保證和舊有環境的一致性。
  • 歷史發生過的問題

  • 新加的物理機編碼異常,導致構建產物異常,運行時出現亂碼。
  • 升級IOT的AndroidSDK,影響支付寶,部分手機計步功能失效。
  • 環境升級操作不當導致的各種構建失敗。
  • 3 容器化

    構建是一件非常值得敬畏的事情,需要保證構建的絕對正確,一旦構建異常了,后果不堪設想。

    最好的保證構建正確性的方式,就是什么都不要改,不要加機器,不要改環境,什么都不要動。

    但是現實是總是有越來越多新的場景冒出了,今天要支持這個,明天要支持那個,這里是一個比較矛盾的點。

    在容器技術出來之前,大家都是用的是虛擬機技術,我們可以模擬出來一臺乃至多臺電腦,但是太笨重了,也不好維護。2013年Docker開源,它輕量,高性能(秒級啟動),隔離性,讓他迅速成為焦點。

    構建也嘗試探索,docker技術非常適合在構建時使用,可以很好的解決上面的問題。改造后長下面這樣:

    之后升級環境再也不是痛,各種場景容器隔離,升級互不影響,物理機秒級擴容。運維人員基本只要維護Dockerfile就行。

    當然也會帶來新的問題:

  • Mac構建沒法虛擬化,仍然是傳統物理機構建 + Ansible運維。
  • 容器化之后緩存失效,構建時間暴增。
  • 鏡像本身的管理,物理機磁盤空間管理。
  • 4 鏡像化

    前面講的都是軟件的構建過程和構建服務,這里其實還存在一個問題,除了構建的一致性,軟件的運行環境一致性也至關重要。經常會發生,一個軟件,在我的電腦可以,在別人的環境卻跑不起來。

    隨著容器技術越來越火,serverless技術和應用微服務架構的演進。容器正迅速成為企業應用打包和部署的基本單位,可以真正的實現build once & run everywhere。
    在螞蟻的歷史中也是如此,越來越多的場景開始鏡像化部署,所以鏡像構建本身也變得越來越重要,鏡像構建的效率,穩定性,安全性等至關重要。

    鏡像構建也經過兩次演進:

    docker build

    docker build是比較簡單的,我們在之前的架構之上新增了一種鏡像構建類型,主要存在下面幾個弊端。

    (1)對于multi-stage 的Dockerfile 構建 無法實現并行編譯

    (2)docker build 緩存利用效率低,改變Dockerfile 前面的一層,后面所有的層都需
    要重新構建而無法使用緩存,這要求用戶不得不認真控制寫好自己的Dockerfile以確保鏡像緩存復用。

    buildkit + K8S

    buildkit是從docker build分離出來的單獨項目,目前buildkit已經集成到Docker 18.06之后的版本之中,核心特性:

    • 可擴展的前端格式:buildkit使用前后端分離的架構設計,除了Dockerfile也支持其他類型的前端格式。
    • 并行構建執行:對于multistage類型Dockerfile, buildkit可以實現不同stage之間的并行執行。
    • 支持構建緩存的多種處理方式:buildkit處理本地緩存snapshot,同時還提供了將構建緩存導入/導出到本地或者遠程registry。
    • 多種輸出格式:buildkit支持導出成tar包或者oci格式的鏡像格式。
    • 引入Dockerfile新語法RUN --mount支持構建時掛載。

    這里不進行擴展,有興趣的同學可以查看buildkit的官方項目(螞蟻目前每天運行著上萬數量的高可用鏡像構建服務)。

    5 擁抱云原生

    隨著螞蟻越來越多的業務serverless化,云原生慢慢成為了趨勢。伴隨著的是對K8s之上的構建和資源的使用訴求。

    而K8s本身使用門檻又極高,同時也缺乏靈活的任務編排能力。相應的構建團隊也開始調研和投入云原生的構建和調度解決方案。

    背景

    2019年3月份持續交付基金會(CDF)正式成立,它致力于使企業在多個 CI / CD 平臺上更輕松地構建和復用 DevOps 管道。

    第一批進入CDF項目的主要有四個:

    Tekton 作為谷歌捐贈的 CDF 重要項目 ,是一組用于構建 CI/CD 系統的共享開源組件,與 Kubernetes 緊密相連,其重要性不言而喻。

    并且jenkinsX底層也選擇了tekton作為執行引擎。

    Jenkins X is committing fully to Tekton as its pipeline execution engine. We are convinced that this is the right choice for Jenkins X, as a cloud-native CI/CD platform on Kubernetes, and for our users.

    內部落地

    綜合權衡,采用tekton是一個比較合理的解決方案(站在巨人的肩膀,不重復造輪子)。

    經過一段時間的探索和演進,逐步落地了云原生的資源調度和構建解決方案——ironman。服務內部每天幾萬的構建、代碼掃描、CI任務等場景。

    詳細細節可以參考下面幾篇文章:

  • tektoncd github
  • 持續交付基金會
  • 下一步計劃

    tekton相比K8s,復雜度大大降低,并且提供了足夠靈活的編排和調度能力,但是仍然有缺陷:

  • 概念復雜,偏厚重,整體調度相比直接使用POD會更慢
  • 使用上仍然有一些成本,對一線用戶的接入使用不友好
  • 目前正在投入POD預熱等極簡模式,解決上訴痛點。當然還有很多未解的難題,就不一一贅述。

    6 構建中臺

    經歷了自動化,容器化,鏡像化等場景,發現用戶的需求實在是千奇百怪,越來越多(只能說螞蟻的業務發展太快)。

    我們有越來越多的業務場景(IOT,小程序,大數據,...),構建的需求差異性也非常大。有Mac構建,Linux構建,Windows構建。應付還是有點吃力。尤其是在Mac和Windows兩種無法虛擬化的場景,大量的機器分組,有點維護不動。現狀大概長這樣:

    由于構建邏輯基本都是在構建團隊維護,SCM和構建腳本中的代碼邏輯也處于一個非常混亂的狀態,基本就是大量的if else,偽代碼大概長這樣:

    if (framework == "sofa") {buildCmd = "mvn clean package"if (app == "special") {buildCmd = "mvn clean package -Ptest=true"} } else if (framework == "android") {buildCmd = "gradle clean assembleRelease" } else if (framework == "jar") {buildCmd = "mvn clean install && mvn deploy" } else if (xxx) {buildCmd = "xxx" }

    這個階段在面對一些個性化的構建需求其實有點力不從心,需求千奇百怪:“我要加個額外的參數”,“我要更多的CPU”,“我需要用Mac來跑構建”,“我需要用某某軟件的某某版本”。

    當前階段是沒法繼續支撐螞蟻未來的業務發展的,在加上當前底下已經有非常多的資源(linux,windows,Mac,K8S)管理困難。

    所以未來的構建平臺,至少是可以做到下面兩點:

  • 構建可描述,邏輯回歸業務方。
  • 構建資源(機器)動態插拔,任意切換。
  • 構建可描述

    所有的構建邏輯是透明的,可配置化,可代碼化,可描述內容包括:

    • 構建機器類型
    • 構建所需資源大小
    • 構建所需環境軟件
    • 構建執行邏輯
    • 構建結果產物

    構建資源動態插拔,任意切換

    這里最關鍵的點是去掉大量分組維護帶來的難點,讓資源之間可以共用,互相流動。同時可以實現資源之間的任意切換,降級,保障構建服務的高可用(比如K8s資源降低到物理機構建)。

    新的框架大概長下面這樣:

    業務使用方只要定義好buildspec.yaml文件,就可以實現任何個性化的構建需求。
    底下執行構建的資源可以是K8S,可以是jenkins,可以是物理機,whatever,構建資源描述好自己支持的類型入場即可。

    buildspec.yaml大概長下面這樣:

    name: android-aar-build params:- name: productLinedefault: alipay- name: sprintIddefault: ${SPRINT_ID} resources:- name: code-repotype: giturl: https://code.alipay.com/xxxxxref: master environment:type: LINUX_CONTAINERimage: reg.docker.alibaba-inc.com/alipay/aarbuild:latest buildTasks:- name: Download configimage: python:3commands:- python --version- name: Install Dependencyimage: ruby:2.6commands:- echo "-------2 in ruby:2.6"ruby -v artifacts:- name: pod-for-alipaytype: iot-signpath: xxxx.zip

    四 構建的挑戰

    1 統一構建中臺

    目前還在持續的開發和演進中,作為服務螞蟻全棧的構建服務,其穩定性,高可用,靈活性至關重要。尤其是極限生存能力。

    2 云原生調度基礎設施

    面向K8s的CI/CD,讓K8s的資源使用簡單優雅。tekton的優雅升級,極簡的調度方案,友好的接入成本。

    3 極致的構建效率和體驗

    深度定制構建工具

    • Java研發:Maven,Gradle,并發構建,緩存構建,增量構建,甚至秒級構建。
    • 終端研發:秒級構建,快速本地部署驗證。
    • 鏡像構建:目前仍然需要30+s的構建時間,需要持續做下去,緩存的命中率,鏡像加速,remote cache,除了構建提效,還可以幫助部署提效。

    制品庫升級

    • 顛覆現有不合理模式,比如因為Jar release覆蓋導致的“黑科技”,提升研發體驗和研發效率。
    • 軟件制品身份追蹤,深入可信研發。

    原文鏈接

    本文為阿里云原創內容,未經允許不得轉載。

    總結

    以上是生活随笔為你收集整理的蚂蚁构建服务演进史的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。