3月25日,網易雲技術佈道系列第三期•對話架構師活動在網易杭州園區舉辦,網易雲基礎服務總經理陳諤、美麗聯合集團研發部副總裁曾憲傑和51信用卡CTO郭威分別從雲原生應用技術、技術人員的成長和技術對業務的價值等方面帶來了乾貨分享。本文將爲你們重點解讀網易雲基礎服務總經理陳諤帶來的分享:Cloud Native 實踐從0到1。數據庫
陳諤,網易雲基礎服務總經理,現負責網易雲計算平臺產品線建設,對內主導公司軟件基礎設施雲化改造,建設網易私有云將網易互聯網產品線遷入私有云環境,對外打造公有云產品,實踐網易雲計算戰略。對分佈式系統設計開發、雲計算平臺系統架構有必定的經驗和理解。我的同時致力於提高尋求解決方案幫助開發人員提高開發效率,近年來一直帶領團隊推動公司開發技術棧的標準化、工具化。後端
說到Cloud Native,國內大多數都翻譯成雲原生,就是讓雲成爲成功的基石,而不是障礙。陳諤對於爲何要實現雲原生應用深有體會,網易從2012年開始實施雲化的戰略,當初版雲計算平臺建好的時候,開始引導公司的項目逐漸向雲遷移。這個過程當中就遇到了一個問題:用上雲以後,並無變得效率奇高,甚至有些項目的效率反而有所降低,你們有不少抱怨。安全
從那個時候陳諤就有一個想法,雲計算怎樣才能成爲公司和開發團隊成功的基石,而不是用上雲以後給你製造麻煩。陳諤認爲要作到這一點首先要理解雲的優點,規避雲的弱點;另外一方面要充分利用雲的各層能力,幫助你去成功。因此雲原生就是採用適合雲端的軟件架構和研發模式去作這個事情。服務器
關於如何實踐雲原生,陳諤爲你們分享了一些建議。假設你們不是相似BAT這樣規模的公司,或者有很是強大的IT團隊,當擇技術路線的時候,陳諤建議你們使用公有云,爲何呢?網絡
首先,使用公有云起步的成本很是低,不須要你去租機房、買物理機,每月幾百塊錢就能夠起步了。若是你成功了,在爆發性增加的時候,公有云有足夠大的資源彈性來幫助你從一臺scale到幾百臺,不須要臨時去買服務器。架構
另外一方面,因爲公有云的規模化效應,網絡質量是自建不可比擬的:負載均衡
有些公有云出入口的帶寬很大,甚至有些互聯網大廠的公有云平臺,用的基礎設施跟公司總體業務是一體的;框架
帶寬大的另外一個好處是能夠抵禦DDoS和CC攻擊;運維
其次,公有云有更強的排障能力,國內的國情,網絡故障是很是難以排查的,須要有專門的IT團隊才能作好。異步
雲計算有數據庫、中間件這些服務,而且不須要你去關注高可用部署、故障恢復、擴縮容等系統層面的運維,操做系統內核級掌控、中間件源碼級維護也均由雲提供商負責,而且有明確的SLA保障。
另外,雲計算能夠幫你作高級別的高可用保障。平常的高可用保障,好比雙機熱備也好,冷備也好,都比不過公有云提供的多可用區的保障。雲的多可用區至少是IDC級別的,在一個可用區內就像一張大網同樣,至少保證三層的鏈接,保證你的業務都是互通的,總體架構不用考慮跨機房的問題。
雲還有多Region的保障,有一些公司會作異地多活的架構,固然這對業務的侵入性是很大的,但至少能夠用多Region的設施,來作數據的災備。
另外,雲的進化速度很快,會持續地更新,如今大多數都是基於Linux的技術棧,可能會不時地出現bug或安全漏洞,若是本身去跟進是很是困難的,公有云通常都會有專業的團隊,及時跟進和修復這些安全問題,又省下了用戶一筆人員開銷。
固然,公有云要支持這麼大規模的用戶,自己有必定的取捨
Design For Failure:公有云傾向於更快失敗(影響範圍受控)、更快恢復。若是你用的是物理機,出現問題的時候你會關注這個物理機是否是還「活着」。而公有云若是發現一臺機器掛了,會直接進行服務遷移和重啓,由於公有云自己有SLA的承諾,爲了保證系統的魯棒性,會更快地把這些疑似故障的節點排除掉。
因爲公有云這樣的特性,平常業務必須結合公有云能力實施高可用架構:
一方面以可用域爲基礎,實現高可用;
另外一方面,將數據狀態和業務邏輯分離,若是業務被遷移走了,只要掛上原來的盤就能夠恢復了;
節點可重啓或重建
Design For Scale:虛擬化性能稍弱於物理機,公有云更追求交付的性能指標的穩定,避免租戶業務間的影響,支持業務作Scale。對於開發者來講:
一方面,要知道你採購的磁盤、網絡可以提供的性能是什麼,根據這些QoS指標去作容量的規劃;
另外一方面要基於負載均衡、集羣管理等能力去作Scale Out,而不是讓機器規格越變越大。
除了上面提到的基礎設施,在項目的工程化方面,陳諤也爲你們帶來了一些啓示。陳諤認爲項目工程化是研發協做與雲端運維的基礎,也是不少團隊在起步的時候可能會忽視的事情。項目的整個流程中,開發、測試、發佈的每一步都涉及到公司內角色之間的協做,若是這些步驟作得不流暢,每個環節的銜接很是困難,效率就會變的很是低,因此項目工程化是對高效構建、發佈、運行流程的支持。
那麼如何作到項目的工程化呢?首先要選擇合理的版本控制工具與策略:
Git是社區和業界公認的一個比較好的工具;
建議每一個應用採用單一的Codebase(12Factors-1: Codebase),把整個開發,構建,發佈的流程串聯起來,不至於拉下一個base還要決定這裏面的代碼哪一部分要拿去構建。
常見的版本控制策略包括:
基於Merge的多分支策略,這種模式和多人協做的方式是匹配的,能夠看到你們協做產生的代碼從分支到合併的過程,可是分支不少也形成了管理的複雜度很高;
若是團隊能切割得比較小,功能比較集中的話,能夠採用基於Rebase的單Master分支策略,它沒有Merge信息,管理起來比較簡單。
而後能夠去作基於配置的依賴管理:
聲明依賴(Maven等),而不是把你的軟件包全拷貝在代碼庫下面,實現自動構建
建議聲明全部的依賴,包括運行環境的初始化,不隱式依賴系統庫(12Factors-2: Dependencies)
接下來要合理拆分模塊,能夠按業務拆分模塊,同時實現公共代碼的模塊化。
以前在網易,對穩定性要求很高的產品,其發佈流程一般都很曲折,主要緣由在於環境的不一致。陳諤的建議是使用Docker實現環境的一致性,Docker容器完整虛擬化了Linux操做系統,將業務代碼與運行環境裝箱爲Docker容器發佈到生產環境,差別僅僅爲外部注入的配置(如數據庫地址等),容器內部文件在開發環境一旦發佈則再也不變化,從而保證開發環境與生產環境一致。
工程化是作業務架構,創建一個高效團隊的基礎,接下來要考慮的就是服務化的思惟。微服務是當下很流行的概念,採用微服務確實能爲應用的迭代和架構帶來不少好處。但服務化的架構會帶來額外的負擔,若是一個項目還處在初期階段,網易雲的建議則是服務化思惟先於服務化架構。
運維成本:一旦服務多了,環境搭建、故障診斷、運維的工做量都會成倍增長。
服務拆分以後,各個服務間的生命週期是不一致的,要作生命週期的分離,就須要處理更多的異常。服務間存在更多的約束,仍是異步的,如依賴關係、版本,要保證消息可以可靠地到達那裏;
另外一方面,還會有分佈式事務的問題,雖然解決起來不難,可是會侵入你的業務
雖然業務初期,不適合服務化,可是應該爲後續的服務化作一些準備,不然後面想拆分的時候會變得很是困難:
提取Service API,理解業務中的服務抽象
數據庫設計的時候就考慮服務的劃分
避免跨服務事務,對跨服務事務進行標記
若是項目發展起來,遇到的第一個問題一般是數據庫會掛掉,因此在業務初期就作分庫分表是頗有必要的
選擇事務支持更好的數據庫,若是你用缺少事務支持的數據庫作業務的後端,當你要作服務化拆分或分佈式事務的時候,可能會比用MySQL的痛苦不少
隨着業務的壯大,是否要採用微服務,就要去衡量微服務帶來的收益是否大於成本?
控制迭代更新的影響域,而單體架構很難評估patch的影響範圍
加速迭代,提交代碼內心負擔小,迭代也能加快
隔離局部故障
防止代碼架構層面的腐化,好比開發過程當中爲了趕進度,可能會把原有的架構推倒重來。若是用微服務架構,最多隻須要將本身負責的那個模塊從新設計。
更多的依賴(eg: ZooKeeper,MQ),要作一個註冊中心
運維複雜度,幾十個服務發佈更新,運維的複雜度必然會上升,
技術實現的侵入性,在這個過程當中不免要用到一些微服務化的框架,雖然對代碼的侵入性不大,但對架構的侵入性仍是不可避免的
良好的工程化,不要給運維的工做帶來不少困難
使用基於雲端託管的 PaaS 服務
使用基於雲端託管的編排服務,幫你去作集羣化的運維和管理的工做
利用基於Kubernetes的基礎設施能夠簡化微服務,一方面Kubernetes提供了基於域名的服務發現
使用 VIP+域名暴露服務:對比「註冊中心」,採用域名服務具備更小的侵入性,更少的依賴
支持名稱空間隔離,簡化測試環境部署
Kubernetes還能夠作基於 iptables的透明RPC 分發
無需在程序中訪問註冊中心獲取成員列表進行軟負載均衡
無需內網負載均衡層次增長網絡開銷
好比,服務 A 訪問服務 B 的 虛擬IP VIP,利用 iptables 作 DNAT,轉成B中的全部成員,服務A能夠直接,並利用 probability特性按權重分發請求,比域名作輪轉的負載均衡效果要好,由於iptables可控,域名不可控。
用Kubernetes還可讓你得到自動化運維能力
自動擴縮容
自動故障處理(重試、遷移)
自動化滾動更新,經過健康檢查與滾動的配合實現無縫更新
還能夠基於Service 抽象實現藍綠髮布
Kubernetes 以解耦的基礎服務層的方式提供了對服務化的支持,避免了代碼實現層面的耦合,經過雲端託管 Kubernetes 服務可以將實現服務化的成本大幅下降。並且Kubernetes對業務沒有侵入性,實現服務化的代價相對會比較小,後面業務變得很是重,須要細粒度控制的時候,再用到其它框架也沒有什麼影響。
網易雲深度整合了Docker技術和Kubernetes集羣編排技術,網易雲中會有一個Kubernetes Master,全部租戶的業務均可以使用這個Master,不用用戶本身維護。
前面講到的都是雲原生相關的技術,實際上實現雲原生還須要一些研發、運維和組織架構上的方式調整,好比DevOps。DevOps的出現是爲了解決運維角色與開發角色的矛盾,運維追求的是可用率優先,而開發但願應用能快速更新迭代。
微服務架構可以支持更高頻的迭代,下降更新迭代的風險,這與 DevOps 的目標是一致;可是微服務架構也會給運維帶來成倍的工做量,可基於DevOps分散運維操做,而不是集中依賴少許運維角色。
實施DevOps須要CI/CD、編排、故障診斷等工具鏈的支持,同時須要運維實現從操做到審計的職能轉換,運維工做前置,在前期和開發團隊合做。不少運維還須要開發工具,提升運轉效率。
Pipeline as Code:實施服務化後持續集成的複雜度成倍增長,須要定義大量的流程,包含大量Jobs,以代碼的方式管理Pipeline可以支持審計,有效管理複雜性並下降維護成本
日誌服務:Kafka+ELK套件,以網易云爲例自動完成容器日誌收集,並提供訂閱接口可對接ELK。
分佈式跟蹤系統:在微服務架構下必需要作到與單體架構一樣的服務請求的調用路徑跟蹤能力,纔可以有效定位故障。可參考的框架有Zipkin, 須要對RPC框架等作instrumentation,在調用過程當中攜帶額外的頭信息。
性能管理服務:微服務架構下依賴關係複雜,發生性能問題時難以定位源頭及影響範圍,性能管理服務可提供調用關係拓撲,及時統計慢響應及錯誤響應,有利於發現性能問題與定位故障。以網易云爲例,利用Kubernetes提供元信息,利用AOP對經常使用庫作instrumentation,可在無須配置及侵入代碼的狀況下,自動繪製拓撲,分析性能。下圖是網易雲內部性能管理的拓撲截圖:
最後,陳諤將雲原生架構實現的要點總結以下,但願能給雲計算的用戶帶來有價值的參考:
使用公有云
重視項目工程化
項目起步時創建服務化思惟,而不要急於採用服務化架構帶來沒必要要的負擔
實施微服務需權衡收益與成本,基於Kubernetes可簡化微服務實施
DevOps能與微服務架構良好匹配,但實施DevOps須要完善的工具鏈支持