Java Obsolete in the Age of Docker
最近看到一篇有趣的文章,標題是: Java and C# are Obsolete in the Age of Docker
很有趣的題目,可以梳理一些觀念,整理一些想到的比較與想法。
東拉西扯 (一):Vagrant vs Docker
看到這篇文章標題我想到 2013 年在 stackoverflow 上一段精彩的討論,討論的是 Docker 與 Vagrant 的選擇,文章標題是:
Should I use Vagrant or Docker for creating an isolated environment?
提問者說,他對於這兩個東西的差異,覺得很難了解他的明白,希望有人分析一下兩者的優缺點。
然後,先是釣出 vagrant 的作者 Mitchell。他一開頭就說:
避免廢話一堆,講白話:依據你特定的情境,像是 自己的開發工作、在 Linux 工作、Production 用 Docker …. 等,這些案例可以用 docker,但是大部分的情況(後述),你想得太簡單了。
原文如下:
Before I talk too much, a direct answer: in your specific scenario (yourself working alone, working on Linux, using Docker in production), you can stick with Docker alone and simplify things. In many other scenarios (I discuss further), it isn’t so easy.
然後,下面一篇回文的第一句話是:
I’m the author of Docker
作者是 Solomon Hykes - Docker 的 Co-Founder. 同樣的,先講結論 (TL;DR)
The short answer is that if you want to manage machines, you should use Vagrant. And if you want to build and run applications environments, you should use Docker.
兩位作者,分別針對 docker / vagrant 的適合場景、優缺點做了分析。
無論兩者的觀點如何,都沒有誰對誰錯的問題,因為這兩個東西,設計的對象完全不一樣:docker 初衷是給 developers 使用的, vagrant 則是 operators。後來 docker 也很適合部署,然後催生 K8s 與 Cloud Native 的概念。
簡述:Container vs Virtual Machine 的原理
Container 與 Virtual Machine (VM) 是兩個不同角度出發的技術,表象看起來很像,但是實際上卻有天壤之別。
Container 由內而外,處理隔離的對象是 Program Process;而 VM則是由外而內,模擬的對象則是硬體,包含 CPU / Memory / I/O (Network, Storage) / Storage … 等,是硬體層級的隔離。
- 卡西哥 03/09 寫了一篇說明 container 原理的介紹文
- 去年同事也跟我問過類似的問題,當時事後的整理:為什麼要使用容器?
很多人剛開始學 Container (Docker) 的時候,很容易掉入一個問題:
把很多東西 (ex: LAMP) 包在一個 docker 裡面
這就是典型的把 Container 當 VM 用的想法。實際上的做法是:
透過 docker-compose 起多個 docker, 像是 LAMP 就至少要起 2 個: Apache (PHP) + MySQL
或者在 K8s 裡面把這兩個 container 包成一個 Pod,K8s 的 Pod 才是對應到 VM 的概念。
東拉西扯(二):Process and Thread
討論標題的 JVM / Container 取代性的問題之前,先回顧一下更基礎的概念,也是很多面試的題目:Process and Thread 的差異。
不知道從什麼時候開始,『Process 和 Thread 的差異』變成面試的指標性題目,然後網路上就有很多『標準』答案,不管國內還是國外。最常見的回答就是:
每個 Process 的資源獨立,Process 裡面會有多個 Thread,Thread 之間會共享資源 …
這種是所謂的『標準式』的回答法。
但是實際的實踐,還是有所差異的,底下列舉一些資料參考:
- 作業系統實作:探討 Process 時,一定會探討的 Process & Thread - 2018 Jserv
- Linux 的 Process 與 Thread 的實作 - 羅習五
- Lecture 4: Processes - University of Massachusetts Amherst
簡單說:
Process 和 Thread 不是絕對的上下關係,不同的作業系統,實際上會有不同的實作。
但是不管是 Process or Thread,本質都在做資源存取過程時的隔離。
簡述:Java Virtual Machine, Cross Compiler
回到一開始的這篇文章,比較的是 JVM 與 Docker。在這之前先大概說整理一下 JVM 是怎樣的 VM?
JVM 全名是 Java Virtual Machine,也是讓 Java 可以 Write Once, Run Anywhere 的基礎,和其他語言比較起來有啥不一樣?
差異在於在 Runtime 之前的 Compile 過程的差異。C 編譯的過程大概需要這些東西:
cross compiler / libraries / assembler / linker
這些統稱 Toolchain,也是大部分語言的 SDK (Standard Development Kit)
會包含的東西,但是各個語言作法可能有所差異。針對不同的 CPU,以 C/C++ 為例,就要針對 x86, ARM 等 CPU 重新編譯,或者針對 OS 也要用不同的 Toolchain / SDK,其中的關鍵在於 Cross Compiler 這段。大部分的語言的編譯器大多都會有 --platform
的參數,讓編譯的結果使用對應 CPU 的 instruction sets。上述概念可以參考我整理的 嵌入式系統設計 筆記。
JVM 是怎樣的 VM?引用一段 解釋不錯的說明:
JVM 其實應該說是一個虛擬處理器 (Virtualized Processor),大部分講的 Virtual Machine 指的是模擬硬體資源,像是 CPU、記憶體、顯示卡、網路 …)
原文:
The difference is essentially that the JVM is a virtualized processor and the other virtual machines are virtualized machines (including video card, network, and other external devices and hardware registers).
透過 JVM 的 instruction set 抽象介面,讓同樣的 byte code 可以動態轉譯成各種 CPU 處理的指令,達到不需要重新編譯,就可以跑在不同的 CPU / OS 環境。
東拉西扯(三):SaaS Multi-Tenency 多租戶架構
探討 SaaS 架構,其中有一個重要的架構議題:Multi-Tenency
,中文稱為 多租戶架構
。
多租戶用什麼當做租戶?背後的目的是希望基於一些條件、場景,將 1) 運算資源與 2) 資料做隔離,達到資訊安全、成本、效能、可靠的考量。
條件有哪一些?這很吃對於領域場景 (Domain Knowhow) 的知識與專業。
先整理我個人認為隔離的實作考量有哪些:
- 應用層: 寫一個 blog SaaS, 用什麼隔離每個租戶?指的是在執行期的隔離 -> runtime,這整個 lifecycle 的運行過程,必須隔離。你家就是你家,你家不是我家。如果你跑來我家,那就要要鑰匙,否則就是非法闖入。
- 資料層:
- 熱資料:時效性低,只要不要錯置即可。
- 溫資料:傳統資料庫 (RMDBS) 的拆分與共用。通常就是集中、獨立、混合三種。
- 冷資料:通常都是
- 物理層: 包含運算資源、網路等
- 運算:通常就是 VM 或者 Container 的隔離,在 K8s 裡就是用 namespace 切割
這裡有很多細節可以整理,先點到一些要注意的點。大多實際的業務場景,架構面很難動,所以最長處理的方法就是直接從 Session 方式切入,透過類似 JWT 的機制管控存取限制。但不管是用 JWT、資料隔離、物理層隔離,實際上的本質都在探討:隔離 (Isolation)
繼續戰:Container vs JVM?
回到這篇文章:Java and C# are Obsolete in the Age of Docker,所以:
Container (Docker) 與 JVM 的差異是?
簡單整理:
- Container 負責的是 Process 之間的隔離,處理的是應用程式與作業系統之間的資源調度與分配。
- JVM 負責是將 Java 語言轉譯的 抽象指令集 (bytecode),在 Runtime 時轉譯成不同 CPU 指令集 (instruction set) 。
Container 還是要處理不同的 Platform (x86, ARM, MIPS …) 的差異,Java 則交給 JVM 處理。
幾個有趣的點:
- 作者對於 JVM 與 VM 的觀念有誤解,應該說誤解很大。
- 這種比較的核心議題是: Isolation 。Isolcation 是大議題,這種比較沒定義清楚比較的邊界、背景,一定是戰文。
- 原文底下有人回一段話:每年都有人會說 Java is dead.
- 討論
Docker 取代 JVM
像是是討論熱狗要取代貓
? 狗呢? - 原文的討論中,一堆人出來補 C# CLR / CIL 的概念,底下回文很值得看。
延伸閱讀
站內文章
參考資料
- Java and C# are Obsolete in the Age of Docker - 2021/03/03
- Should I use Vagrant or Docker for creating an isolated environment? - 2013/05/20
- Is the Java Virtual Machine really a virtual machine in the same sense as my VMWare or Parallels file?
- 探討 Process 時,一定會探討的 Process & Thread