雲原生應用的概念和雲原生應用的 15 個特徵
攜手創作,共同成長!這是我參與「掘金日新計劃 · 8 月更文挑戰」的第4天,點選檢視活動詳情
微服務架構只是一種軟體架構風格,並不限制所採用的實現技術,開發團隊可以自由選擇最合適的技術來實現。微服務架構實現最大的挑戰是它的複雜度,這些複雜度是微服務架構本身天然所具備的,是每個微服務架構應用繞不開的難題。在實現微服務架構時,開發團隊當然希望把全部的精力放在實現業務邏輯上,而不是應對微服務架構自身的複雜度,這就意味著,需要選擇能夠幫助應對這些複雜性的平臺和工具。雲原生(Cloud Native)應用就是微服務架構的最佳實現方式。
雲原生應用的概念
顧名思義,雲原生應用的概念由雲和原生兩個部分組成,雲在這裡指的是雲平臺,也就是平臺即服務(Platform as a Service,PaaS);原生應用指的是專門針對雲平臺而設計和實現的,充分利用了雲平臺的特性。應用的微服務可以專注於實現業務邏輯,而把微服務架構的複雜度交給雲平臺來解決。
起初CNCF(雲原生計算基金會)認為雲原生系統需包含的屬性:
容器化封裝
:以容器為基礎,提高整體開發水平,形成程式碼和元件重用,簡化雲原生應用程式的維護。在容器中執行應用程式和程序,並作為應用程式部署的獨立單元,實現高水平資源隔離。自動化管理
:統一排程和管理中心,從根本上提高系統和資源利用率,同時降低運維成本。面向微服務
:通過鬆耦合方式,提升應用程式的整體敏捷性和可維護性。
隨著近幾年來雲原生生態的不斷壯大,所有主流雲計算供應商都加入了該基金會,且從 Cloud Native Landscape 中可以看出雲原生有意蠶食原先非雲原生應用的部分。CNCF 基金會中的會員以及容納的專案越來越多,該定義已經限制了雲原生生態的發展,CNCF 為雲原生進行了重新定位。
雲原生技術有利於各組織在公有云、私有云和混合雲等新型動態環境中,構建和執行可彈性擴充套件的應用。雲原生的代表技術包括容器
、服務網格
、微服務
、不可變基礎設施
和宣告式 API
。
容器技術(container)
:容器技術真正核心的創新是容器映象(docker image),映象是一種新型的應用打包、分發和執行機制。容器映象將應用執行環境,包括程式碼、依賴庫、工具、資原始檔和元資訊等,打包成一種作業系統發行版無關的不可變更軟體包。容器技術和雲原生好比一對螺旋體,容器技術催生了雲原生思潮,雲原生生態推動了容器技術發展。容器映象打包了整個容器執行依賴的環境,以避免依賴執行容器的伺服器的作業系統,從而實現“build once, run anywhere”。容器映象一旦構建完成,就變成read only,成為不可變基礎設施的一份子。在容器技術的基礎上,容器編排技術(主流方案:K8S)為容器化的應用提供部署執行、資源排程、服務發現和動態伸縮等功能,使用者不需要再過度的關注資源的管理問題,降低操作的複雜度,提高了大規模容器叢集管理的便捷性。微服務(Microservices)
:微服務架構中,服務是一個單一的、可獨立部署的軟體元件,它實現了一些有用的功能,服務的API封裝了其內部實現,與單體架構不同,開發人員無法繞過服務的API直接訪問服務內部的方法和資料,因此,微服務架構強制實現了應用程式的模組化。微服務架構的最核心特性是服務之間的松耦合性。服務網格
:服務網格是用於處理服務間通訊的專用基礎設施層,負責在微服務間進行可靠地請求傳遞。服務網格通常通過一組輕量級網路代理來實現,這些代理與應用程式程式碼一起部署,而不需要感知應用程式本身。不可變基礎設施
:一個工作負載(比如容器、虛擬機器等)一旦部署以後就不會被修改。當需要更新,修復或修改某些內容的時候,只需要將新的、經過驗證的工作負載替換舊的即可。宣告式API
:宣告式API是一種比命令式API更高階的介面設計方式,簡單來說,命令式API提供給使用者怎麼做的能力,而宣告式API給使用者提供了做什麼的能力。DevOps
:DevOps就是基於敏捷開發將軟體開發/測試人員/IT運維關聯在一起,通過工具、組織等方式使開發、測試、釋出流程自動化,軟體釋出頻繁,高效。DevOps的核心是CICD。- 持續整合(CONTINUOUS INTEGRATION,CI)其核心是新提交的程式碼與原始碼正確的整合。開發人員多次、頻繁的將程式碼提交到程式碼倉庫中,在合併到指定分支之前,對新提交上來的內容進行編譯、自動化檢測(如:程式碼格式檢測)的驗證,這樣的過程既保證了程式碼的完整性、安全性,為後面的工作提供了質量保證。
- 持續交付(CONTINUOUS DELIVERY,CD),其重點不在程式碼本身,而是可以交付的產品上。在釋出到生產環境之前,對新增的程式碼進行測試(test) -> 模擬(staging) -> 生產(produciton),即簡化繁瑣的釋出流程,又保障新新增的程式碼在生產環境是可用的。
- 持續部署(CONTINUOUS DEPLOYMENT)通過自動化部署的方式頻繁的交付產品,關注的重點在於自動化部署。從開發人員提交程式碼到編譯、測試、部署整個流程都是通過自動化執行,這種方式加快了交付的速度,同時在發現問題時也縮短修復的時間。
這些技術能夠構建容錯性好、易於管理和便於觀察的松耦合系統。結合可靠的自動化手段,雲原生技術使工程師能夠輕鬆地對系統作出頻繁和可預測的重大變更。
雲原生應用的特徵
與其他應用相比,總結起來,雲原生應用有如下 15 個特徵。
單一程式碼庫
雲原生應用必須有單一的程式碼庫,並在版本管理系統中進行追蹤。 對於微服務架構的應用來說,每個應用由多個服務組成,這些服務應該由單一的程式碼庫進行管理,這保證了構建版本的穩定性。
- 如果一個改動涉及到多個服務,則這個改動應該在一次程式碼提交中完成對所有相關服務的修改;
- 如果服務的程式碼分散在多個程式碼庫中,則一個改動會被分成多個程式碼提交,每個程式碼提交都會觸發一次持續整合流程,產生對應服務的構建版本,這些服務的構建版本只包含了部分改動,是不完整的。
API 優先
雲原生應用應該採用 API 優先的設計策略。微服務架構的應用使用公開 API 來作為服務的對外介面,API 遮蔽了服務的內部實現細節。API 優先的設計策略指的是在設計階段,應該首先設計 API 並確定 API 的細節。API 的設計過程需要多個團隊的參與,包括 API 的實現者和可能的使用者,這些團隊在充分討論中最終完成 API 的定義。API 可以使用 OpenAPI 規範描述,從該規範中可以生成 API 文件和進行測試的模擬伺服器。
- API 優先的策略保證了 API 的穩定性,同時可以減少不必要的後期修改。
- API 優先的另外一個好處是可以提高開發效率。不同的團隊可以並行工作,從而提高效率。
依賴管理
雲原生應用應該管理自己的依賴,Java 開發人員對依賴管理應該並不陌生,常用的 Java 構建工具 Maven 和 Gradle 都提供了依賴管理的支援。在開發過程中,只需要利用構建工具的支援即可;在管理依賴時,則需要區分應用自帶的依賴和執行環境提供的依賴。雲原生應用通常會包含全部所需的依賴,尤其是以容器形式執行的應用,典型的例子是微服務的 REST API。雲原生應用會自帶嵌入式的 Tomcat 這樣的伺服器來提供 HTTP 服務。
設計、構建、釋出和執行
雲原生應用應該有完整的設計、構建、釋出和執行流程,如下圖所示。
程式碼、配置和憑據
程式碼、配置和憑據是雲原生應用開發中建立的三種不同型別的實體。
程式碼
包括原始碼和相關資原始檔;配置
是與部署環境相關的配置資訊,通常以 XML、YAML、JSON 或屬性檔案的形式出現,配置中包含的資訊包括第三方服務的連線方式、資料庫連線資訊和應用自身的配置屬性等;憑據
指的是密碼、私鑰和 API 金鑰等敏感資訊。
程式碼和配置的區別在於,程式碼不會隨著部署環境而變化,而配置則相反。在實踐中,應該儘可能把配置從應用中分離出來,進行外部化管理,構建出來的二進位制工件中不包含任何配置資訊,實際的配置值在部署時根據環境來確定。在執行時,一般使用環境變數來傳遞配置值,還可以使用類似 Spring Cloud Config 這樣的專門配置伺服器來管理配置值。憑據都應該從原始碼倉庫中刪除。
日誌
日誌是應用開發中不可或缺的部分。與傳統應用不同的是,雲原生應用並不需要對日誌的輸出方式進行很多配置,只是簡單地把日誌寫到標準輸出流(stdout)和標準錯誤流(stderr)。 日誌的收集和處理由雲平臺上的其他服務來提供,這把應用開發人員從日誌管理相關的任務中解放出來。 雲平臺上的日誌管理服務非常多,開源的典型實現包括 ELK 技術棧(ElasticSearch + LogStash + Kibana)和 Fluentd。
隨時可丟棄
雲原生應用的生命週期可能是短暫的,隨時可能被終止。雲平臺可能會隨時啟動和停止應用的例項,這就要求雲原生應用的啟動和停止速度都要非常快。
支撐服務
雲原生應用的執行離不開支撐服務。支撐服務是一個寬泛的概念,包括資料庫、訊息中介軟體、快取、使用者認證和授權、儲存等。連線這些支撐服務的配置資訊應該被抽離出來,在執行時根據部署環境提供實際值。
環境等同
雲原生應用的不同部署環境應該是等同的。開發、測試和生產環境之間不應該有差異,環境的等同性保證了雲原生應用可以快速的進行部署,這一特徵與構建工件的不變性是相輔相成的,兩者缺一不可。有了這兩個特徵之後,每一個唯一版本的構建工件可以被依次部署到不同的環境,在測試環境上經過測試的版本,可以直接部署到生產環境。我們可以確定應用在生產環境上的行為與測試環境中一樣。
管理任務
雲原生應用執行中可能會需要執行一些管理任務,比如生成報表或者執行一次性的資料查詢等,這些任務通常並不屬於業務流程的一部分,更多的是為了管理和運維的需要。這些任務在執行中會用到雲原生應用所依賴的支撐服務,對於這些任務,應該建立獨立的應用,並在同樣的雲平臺上執行。對於定期執行的任務,可以充分利用雲平臺的支援,比如,Kubernetes 提供了對定時任務(CronJob)的支援。
埠繫結
雲原生應用在執行時並不負責管理實際的埠繫結,而是由雲平臺統一管理。比如,一個基於 Spring Boot 的微服務應用通常在 8080 埠執行 HTTP 服務,當應用執行在雲平臺上時,這個埠只是虛擬機器或容器內的埠,並不是外部使用者或其他服務訪問時的實際埠。雲平臺對網路進行統一管理,負責分配實際的埠,雲平臺同時提供了相應的機制來發現訪問服務的實際地址和埠。
無狀態程序
雲原生應用應該是無狀態的。所有的狀態資訊都應該從應用中抽離出來,並儲存在支撐服務中,比如資料庫中。正因為應用是無狀態的,才可以由雲平臺快速的啟動和停止,並進行垂直或水平擴充套件。
併發性
雲原生應用使用水平擴充套件來併發執行多個例項,使用負載均衡來把請求分配到某個例項進行處理。
遙測資料
雲原生應用需要收集一系列遙測資料,包括應用效能指標、執行狀態和日誌等,這些遙測資料,對於雲平臺和應用來說同等重要。 雲平臺可以用效能指標來進行自動水平擴充套件,比如,Kubernetes 支援 Pod 的自動水平擴充套件,當 CPU 的利用率超過預定的閾值時,會自動啟動新的 Pod 來處理請求。
認證和授權
雲原生應用應該是安全的,安全應該在應用的設計階段就充分考慮。在實現中,可以使用基於角色的訪問控制(RBAC)來保護 API,已經有大量的開源框架來幫助實現認證和授權。
總結
在理想情況下,雲原生應用應該具備上述全部 15 個特徵,但是在實際的開發中,不一定能夠做到。開發團隊可以根據需要,選擇對應用最重要的特徵來實現。
參考: http://lib.jimmysong.io/cloud-native-handbook/intro/what-is-cloud-native/ 拉勾:《雲原生微服務架構實戰精講-成富》
本文內容到此結束了,
如有收穫歡迎點贊👍收藏💖關注✔️,您的鼓勵是我最大的動力。
如有錯誤❌疑問💬歡迎各位大佬指出。
保持熱愛,奔赴下一場山海。🏃🏃🏃
- SpringCloud系列之服務治理Eureka
- 自定義過濾器和攔截器實現ThreadLocal執行緒封閉
- AQS同步元件-CyclicBarrier(迴圈屏障)解析和用例
- SpringBoot中的配置檔案詳解(yml、properties全域性配置和自定義配置、有趣的banner圖配置)
- 雲原生應用的概念和雲原生應用的 15 個特徵
- AQS同步元件-CountDownLatch解析和案例
- MyBatis從入門到精通—MyBatis外掛原理探究和自定義外掛實現
- 面試官:可以談談樂觀鎖和悲觀鎖嗎
- Spring JdbcTemplate&宣告式事務
- Java中的JDBC詳解
- Spring從入門到精通(一)—Spring概述、Spring的優勢和體系結構
- 資料庫連線池入門(c3p0、Druid)
- group by和having的區別
- Java流處理之序列化和列印流
- Cookie和Session詳解