[轉帖]程序員必知的六種隔離技術

https://blog.csdn.net/ceshi986745/article/details/51787424

 

爲了將咱們的應用部署到服務器上,咱們須要爲其配置一個運行環境。從底層到頂層有這樣的運行環境及容器:html

  1. 隔離硬件:虛擬機程序員

  2. 隔離操做系統:容器虛擬化數據庫

  3. 隔離底層:Servlet容器編程

  4. 隔離依賴版本:虛擬環境瀏覽器

  5. 隔離運行環境:語言虛擬機服務器

  6. 隔離語言:DSL網絡

實現上這是一個請求的處理過程,一個HTTP請求會先到達你的主機。若是你的主機上運行着多個虛擬機實例,那麼請求就會來到這個虛擬機上。又或者是若是你是在Docker這一類容器裏運行你的程序的話,那麼也會先到達Docker。隨後這個請求就會交由HTTP服務器來處理,如Apache、Nginx,這些HTTP服務器再將這些請求交由對應的應用或腳原本處理。隨後將交由語言底層的指令來處理。 架構

不一樣的環境有不一樣的選擇,固然也能夠結合在一塊兒。不過,從理論上來講在最外層仍是應該有一個真機的,可是我想你們都有這個明確的概念,就很少解釋了。編程語言

一、隔離硬件(虛擬機)

在虛擬機技術出現以前,爲了運行不一樣用戶的應用程序,人們須要不一樣的物理機才能實現這樣的需求。對於Web應用程序來講,有的用戶的網站訪問量少消耗的系統資源也少,有的用戶的網站訪問量大消耗的系統資源也多。雖然有不一樣的服務器類型能夠選擇,然而對於多數的訪問少的用戶來講他們須要支付一樣的費用。這聽上去至關的不合理,而且也浪費了大量的資源。而且對於系統管理員來講,管理這些系統也不是一件容易的事。在過去硬件技術革新特別快,讓操做系統運行在不一樣的機器上也不是一件容易的事。工具

虛擬機(Virtual Machine)指經過軟件模擬的具備完整硬件系統功能的、運行在一個徹底隔離環境中的完整計算機系統。

這是一個頗有意思的技術,它可讓咱們在一個主機上同時運行幾個不一樣的操做系統。咱們能夠爲這幾個操做系統使用不一樣的硬件,在這之上的應用可使用不一樣的技術棧來運行,而且從理論上互相不影響。其架構以下圖所示:

藉助於虛擬機技術,當咱們須要更多的資源的時候,建立一個新的虛擬機就好了。同時,因爲這些虛擬機上運行的是一樣的操做系統,而且可使用相同的配置,咱們只須要編寫一些腳本就能夠實現其自動化。當咱們的物聯機發生問題時,咱們也能夠很快將虛擬機遷移或恢復到另外的宿主機。

二、隔離操做系統(容器虛擬化)

對於大部分的開發團隊來講,直接開發基於虛擬機的自動化工具不是一件容易的事,而且他從使用成本上來講比較高。這時候咱們就須要一些更輕量級的工具容器——它能夠提供輕量級的虛擬化,以便隔離進程和資源,並且不須要提供指令解釋機制以及全虛擬化的其餘複雜性。而且,它從啓動速度上來講更快。

LXC

在介紹Docker以前,咱們仍是稍微提一下LXC。由於在過去我有一些使用LXC的經歷,讓我以爲LXC很贊。

LXC,其名稱來自Linux軟件容器(Linux Containers)的縮寫,一種操做系統層虛擬化(Operating system–level virtualization)技術,爲Linux內核容器功能的一個用戶空間接口。它將應用軟件系統打包成一個軟件容器(Container),內含應用軟件自己的代碼,以及所須要的操做系統核心和庫。經過統一的名字空間和共用API來分配不一樣軟件容器的可用硬件資源,創造出應用程序的獨立沙箱運行環境,使得Linux用戶能夠容易的建立和管理系統或應用容器。

咱們能夠將之以上面說到的虛擬機做一個簡單的對比,其架構圖以下所示:

咱們會發現虛擬機中多了一層Hypervisor——運行在物理服務器和操做系統之間,它可讓多個操做系統和應用共享一套基礎物理硬件。這一層級能夠協調訪問服務器上的全部物理設備和虛擬機,然而因爲這一層級的存在,它也將消耗更多的能量。據愛立信研究院和阿爾託大學發表的論文表示:Docker、LXC與Xen、KVM在完成相同的工做時要少消耗10%的能耗。

LXC主要是利用cgroups與namespace的功能,來向提供應用軟件一個獨立的操做系統運行環境。cgroups(即Control Groups)j Linux內核提供的一種能夠限制、記錄、隔離進程組所使用的物理資源的機制。而由namespace來責任隔離控制。

與虛擬機相比,LXC隔離性方面有所不足,這就意味着在實現可移植部署會遇到一些困難。這時候,咱們就須要Docker來提供一個抽象層,並提供一個管理機制。

Docker

Docker 是一個開源的應用容器引擎,讓開發者能夠打包他們的應用以及依賴包到一個可移植的容器中,而後發佈到任何流行的 Linux 機器上,也能夠實現虛擬化。Docker能夠自動化打包和部署任何應用、建立一個輕量級私有PaaS雲、搭建開發測試環境、部署可擴展的Web應用等。

構建出Docker的Container是一個頗有意思的過程。在這一個過程當中,首先咱們須要一個base images,這個基礎鏡像不只包含了一個基礎系統,如Ubuntu、Debian。他還包含了一系列的模塊,如初始化進程、SSH服務、syslog-ng等等的一些工具。由上面原內容構建了一個基礎鏡像,隨後的修改都將於這個鏡像,咱們能夠用它生成新的鏡像,一層層的往上疊加。而用戶的進程運行在writeable的layer中。 

從上圖中咱們還能夠發現一點: Docker容器是創建在Aufs基礎上的。AUFS是一種Union File System,它能夠不一樣的目錄掛載到同一個虛擬文件系統下。它的目的就是爲了實現上圖的增量遞增的過程,同時又不會影響原有的目錄。即以下的流程以下:

其增量的過程和咱們使用Git的過程當中有點像,除了在最開始的時候會有一個鏡像層。隨後咱們的修改均可以保存下來,而且當下次咱們提交修改的時候,咱們也能夠在舊有的提交上運行。

所以,Docker與LXC的差距就以下如圖所示:

LXC時每一個虛擬機只能是一個虛擬機,而Docker則是一系列的虛擬機。

三、隔離底層(Servlet容器)

在上面的例子裏咱們已經隔離開了操做系統的因素,接着咱們還須要解決操做系統、開發環境引發的差別。早期開發Web應用時,人們使用CGI技術,它可讓一個客戶端,從網頁瀏覽器向執行在網絡服務器上的程序請求數據。而且CGI程序能夠用任何腳本語言或者是徹底獨立編程語言實現,只要這個語言能夠在這個系統上運行。而這樣的腳本語言在多數狀況下是依賴於系統環境的,特別是針對於C++這一類的編譯語言來講,在不一樣的操做系統中都須要從新編譯。

而Java的Servlet則是另一種有趣的存在,它是一種獨立於平臺和協議的服務器端的Java應用程序,能夠生成動態的Web頁面。

Tomcat

在開發Java Web應用的過程當中,咱們在開始環境使用Jetty來運行咱們的服務,而在生產環境使用Tomcat來運行。他們都是Servlet容器,能夠在其上面運行着同一個Servlet應用。Servlet是指由Java編寫的服務器端程序,它們是爲響應Web應用程序上下文中的HTTP請求而設計的。它是應用服務器中位於組件和平臺之間的接口集合。

Tomcat服務器是一個免費的開放源代碼的Web應用服務器。它運行時佔用的系統資源小,擴展性好,支持負載平衡與郵件服務等開發應用系統經常使用的功能。除此,它仍是一個Servlet和JSP容器,獨立的Servlet容器是Tomcat的默認模式。其架構以下圖所示:

Servlet被部署在應用服務器中,並由容器來控制其生命週期。在運行時由Web服務器軟件處理通常請求,並把Servlet調用傳遞給「容器」來處理。而且Tomcat也會負責對一些靜態資源的處理。

四、隔離依賴版本(虛擬環境)

對於Java這一類的編譯語言來講,不存在太多語言運行帶來的問題。而對於動態語言來講就存在這樣的問題,如Ruby、Python、Node.js等等,這一個問題主要集中於開發環境。固然若是你在一個服務器上運行着幾個不一樣的應用來講,也會存在這樣的問題。這一類的工具在Python裏有VirtualEnv,在Ruby裏有RVM、Rbenv,在Node.js裏有NVM。

下圖是使用VirtualEnv時的不一樣幾個應用的架構圖:

以下所示,在不一樣的虛擬環境裏,咱們可使用不一樣的依賴庫。在這上面構建不一樣的應用,也可使用不一樣的Python版原本構建系統。一般來講,這一類的工具主要用於本地的開發環境。

五、隔離運行環境(語言虛擬機)

最後一個要介紹的可能就是更加抽象的,可是也是更加實用的一個,JVM就是這方面的一個表明。在咱們的編程生涯裏,咱們很容易就會遇到跨平臺問題——即咱們在咱們的開發機器上開發的軟件,在咱們的產品環境的機器上就沒有辦法運行。特別是當咱們使用Mac OS或者Windows機器上開發了咱們的應用,而後咱們須要在Linux系統上運行,就會遇到各類問題。而且當咱們使用了一個須要從新編譯的庫時,這種問題就更加麻煩。

以下圖所示的是JVM的架構示意圖

JVM是一種用於計算設備的規範,它是一個虛構出來的計算機,是經過在實際的計算機上仿真模擬各類計算機功能來實現的。它能夠實現「編寫一次,處處運行」。

換句話來講,它在底層實現了環境隔離,它屏蔽了與具體操做系統平臺相關的信息,使得Java程序只需生成在Java虛擬機上運行的目標代碼(字節碼),就能夠在多種平臺上不加修改地運行。

基於此,只要其餘編程語言的編譯器能生成正確Java bytecode文件,這個語言也能實如今JVM上運行。以下圖所示的是基於JVM的Jython語言的架構圖:

其底層是基於JVM,而編寫時則是用Python語言,而且他可使用Java的模塊來編程。

常見擁有一樣架構的工具,還有MySQL,以下圖是所示的是MySQL的架構圖:

MySQL在最頂層提供了一個名爲SQL的查詢語言,這個查詢語言只能用於查詢數據庫,然而它倒是一種更高級的用法 。它不像通用目的語言那樣目標範圍涵蓋一切軟件問題,而是專門針對某一特定問題的計算機語言,即領域特定語言。

六、隔離語言(DSL)

這是一門特別有意思也特別值得期待的技術,可是實現它並非一件容易的事。

做爲討論隔離環境的一部分,咱們只看外部DSL。內部DSL與外部DSL最大的區別在於:外部DSL近似於建立了一種新的語法和語義的全新語言。以下圖所示是兩中DSL的一種對比:

在這樣的外部DSL裏,咱們有本身的語法、本身的解析器、類型檢測器等等。最簡單且最經常使用的DSL就是Markdown,以下圖所示:

若是咱們能夠將咱們的業務邏輯寫成DSL,那麼咱們就不須要擔憂底層語言的變更過多地影響原有的業務邏輯。換句話說,這至關於建立了咱們本身的語言隔離環境,咱們不須要思考用何種語言來實用咱們的業務。

相關文章
相關標籤/搜索