Categories
程式開發

新發布的Ecastasy編程語言劍指雲原生計算


本文要點

  • Ecastasy是為雲構建的通用、類型安全的模塊化編程語言
  • 構建Ecastasy的團隊計劃將其用作高度可擴展的平台即服務(PaaS)的基礎
  • Ecastasy仍在開發中,尚未準備好用於生產
  • Ecastasy團隊正在尋找貢獻者,共同定義我們行業的未來

Ecastasy由前Tangosol創始人Cameron Purdy和Gene Gleyzer共同創建,最近他們在CloudNative 2019倫敦大會上展示了這一語言。在創辦xqiz.it,也就是Ecstasy項目的讚助商之前,Purdy是Oracle的高級副總裁,負責企業級Java、WebLogic、Coherence、Traffic Director、HTTP、JDBC和Exalogic等產品。 InfoQ採訪了Purdy,探討了這門語言本身及其旨在解決的問題等話題。

InfoQ:什麼是Ecastasy語言(XTC)?

Cameron PurdyEcastasy是一種為雲構建的通用、類型安全的模塊化編程語言。我們總結了過去30年的經驗,去蕪存菁,將其提煉成了一種易於理解的語言。

某種程度上來說,我真希望當初能用這種語言來構建Tangosol Coherence;我希望當初能用這種語言來構建Web和後端服務的應用程序;我希望在開始構建Oracle Cloud的一部分基礎架構時也能用上這種語言。

它是一種專注於安全性、可組合性和可讀性的語言,而其設計意圖非常明確,可用於存儲庫、持續集成(CI)、Devops、持續部署(CD)、雲和客戶端可移植性、邊緣計算/CDN/5G集成以及地理分佈式系統。

它也不只是一種新語言而已。 Ecastasy語言基於新的託管運行時,使用一種新的指令集編譯為全新的可移植二進制格式,這種運行時的設計支持即時(JIT)、預先(AOT)和自適應編譯。

InfoQ:參考文檔上的內容(如果我理解正確的話)似乎暗示它絕對不是一種系統編程語言?

Purdy:它不是系統編程語言。我的意思是,我們沒有將這種語言設計為用於編寫操作系統或操作系統驅動程序的用途,它也不是用於管理內存或編寫文字處理器的語言。當然,作為一種通用語言,理論上你能用它做任何事情;但語言是為特定目的而構建的,而這種語言是為幫助開發人員在雲中編寫和發展應用程序而誕生的。

這些應用會在各種雲提供商的數據中心內執行,在雲提供商的CDN內運行,在電信公司的5G基礎架構內執行,抑或上至各種ISP的邊緣,下至客戶端的設備,甚至在這些客戶端上運行的瀏覽器中執行。

我們的目標是,程序員只要了解Java或C#(我曾大量使用這兩種語言編程)或Swift,就能無需學習過程,直接讀懂Ecastasy代碼;並且只需花費幾小時或幾天時間學習Ecastasy後,就能編寫它的代碼。儘管這種語言的許多功能對於C和C++開發人員也是非常眼熟的,並且它在技術上屬於C語言家族,但這些語言的用戶並不是我們的主要目標群體。使用Kotlin、Python、Erlang、Elixir、Smalltalk或Ruby的程序員也應該能快速上手Ecastasy;Ecastasy中的許多語言思想和功能已經出現在了這些語言中,或正在被它們採納。

像Java和C#一樣,Ecastasy也是為託管運行時環境而設計的;但憑藉後發優勢,我們的設計能夠充分利用託管運行時環境的理念好處。一個明顯的例子是關於線程的:Ecastasy沒有將線程的概念暴露給開發者,因為這會讓運行時無法動態管理並發。 (在語言中隱藏線程還有其他很多好處,例如避開了在開發人員嘗試編寫正確的並發代碼時遇到的所有陷阱。)在Ecastasy中,如何在可並發和可異步的任務之間分配線程,是運行時來決定的事情;某種程度上來說,我們是將Java語言中“Hotspot”自適應編譯器的理念應用到了並發和線程問題上,從而允許運行時使用運行代碼時收集到的經驗數據,來優化相同代碼之後的執行工作。此外,Ecastasy是為預先(AOT)編譯而設計的,這意味著可以在執行代碼之前完成繁重的編譯和優化工作;至於自適應編譯則意味著,長時間收集到的信息和作出的優化可供未來使用——甚至在應用程序停止時也能發揮作用。

我們還認識到,自1990年代JVM和CLR發明以來,硬件已經發生了翻天覆地的變化。在過去,價值10萬美元的高端服務器也只有2到4個並發的硬件線程,也許還有幾GB的RAM——如今一款現代智能手機也能輕鬆超越這些參數。當我們坐下來開始設計Ecastasy時,我們的目標是讓它在強大的服務器上也能充分發揮硬件優勢,這種服務器可能會在單個進程中擁有數十TB的RAM,並且在單個進程中擁有數千個並發硬件線程。很快,我們消除了諸如“線程”和“同步”之類的語言概念,並增加了諸如不變性之類的概念;我們也有意消除了諸如“堆”之類的潛在限制。通過採用內置的參與者模式(就像Smalltalk的messages和Erlang的processes),我們使架構師或開發人員可以輕鬆地將其應用程序細分為可並發的單元,Ecastasy稱之為服務。內存、線程和安全性的規則都是用服務來描述的,回過頭來看這是非常明顯的。

這種語言的美感在它的類型系統上也體現得很明顯。 Ecastasy是靜態類型的,具有出色的類型推斷和泛型化等優點,但遠不止於此:其類型系統的設計與運行時是一致的。換句話說,我們用一致的方式設計了這兩套組件,這樣類型系統就能在運行時的定義內起作用,而運行時從類型系統的角度來看也是有意義的。甚至屬性、變量和對象引用都是對象,因此運行時反射就變得很自然,並且運行時和類型系統成為了共生體。在這方面的一些決定非常重要,包括設計了類型系統上可證明的閉包,支持分層次(可嵌套)運行時容器,以及安全、動態的代碼加載設計。

InfoQ:對於crates/npm/dep之類的東西有什麼計劃(這些地方有很多關於不做某事的教程)?

Purdy:在設計語言和運行時時,這是一個我們非常關注的領域。我們的部分思想受到我們構建庫、框架和應用程序的經驗影響,這些成果被用在了各種不同的環境中,與其他各種庫、框架和服務器共同使用。

例如,很久以前的某個時候,我工作的公司正在使用SAX或DOM庫進行XML解析。有一天,有人引入了一個完全不兼容的API更改,這迫使我們必須選擇針對舊版或新版進行編寫和構建,不管選哪個都要完全切斷到另一個版本的關係。更糟糕的是,這個庫包含在許多不同的應用服務器中,因此這些應用服務器的較舊版本也會有這個庫的較舊版本,而應用服務器的較新版本也會有這個庫的較新版本。那時,我們的用戶分佈在許多應用服務器的眾多不同版本上,並且一夜之間,我們更新時就不能再附帶這個Apache XML解析器的依賴項了!所以——我沒在開玩笑——我們不得不編寫自己的XML解析器(以避免依賴項),然後一年又一年不斷地支持它!

另一個例子是,我們希望自己的產品與Spring兼容,因此我們與Spring開發人員進行了一些聯合開發;但是為了避免對Spring的強依賴(當時我們的許多客戶沒用過它),同時也為避免Spring對我們的任何強依賴,我們必須通過反射來做所有集成!因此,本來應該只用一行代碼就解決的東西卻要佔用20行代碼,而這種複雜性必須四處散佈。類似地,我們添加了對Hibernate和Solarmetric KODO的插件支持,但是現在,這些“可選”庫的各種組合卻帶來了組合而成的複雜性。通過反射可以在Java中實現模塊化,但這會帶來巨大的痛苦。有一次,我們甚至嘗試使用OSGi來看看它能不能簡化一些東西,但結果卻變得更加複雜。

在與其他公司合作構建應用程序的過程中,許多類似的問題不斷湧現,因此我們從所有這些經驗中汲取了教訓,並著手從頭開始設計Ecastasy以解決這些問題。首先,我們將編譯單元設計為一個模塊——或者可以選擇用一組模塊,當模塊之間存在循環依賴關係時這很有必要。接下來,我們允許模塊(並且只有模塊)以統一資源標識符(URI)的形式聲明其自己的通用身份,從而將存儲庫支持嵌入了進來。當模塊上存在依賴項時,該模塊依賴項會表示為URI,我們就會說這個依賴的模塊已導入。

稍有點偏題了,但是導入模塊如此簡單,其機制如此優雅,這真的很棒:導入的模塊在導入它的模塊內部表示為一個包(也就是命名空間);就好像導入模塊的所有內容都已復製到了這個包中,因此它們都可以通過本地名稱訪問,就像它們會出現在這個包中一樣。例如,每個模塊都會自動將(URI)”Ecstasy.xtclang.org”模塊作為”Ecstasy”包導入,因此,來自Ecstasy模塊的”collections.HashMap”類將作為”Ecstasy.collections.HashMap”類出現在所有模塊中。

構建模塊時會在其上標記一個版本。一般來說這個版本會是開發版本或CI版本。這個版本還包含一個符合Semantic Versioning 2.0.0規範的版本號,並且這個版本標記是可更新的,因此通過所有測試的CI版本可以被標記為QC或預發布版本。當構建準備好發佈時,可以刪除預發布標記。這些都是為了自動化而設計的,其靈活性足以匹配組織的現有流程。

模塊的設計在另一個層面來看也是很獨特的:單個模塊可以包含同一模塊的許多不同版本。當一個模塊的兩個不同版本組合在一起時,增加的模塊體積只是兩個版本之間存在差異的部分。這樣一來,單個模塊文件即可包含其支持的所有版本,再加上未來版本的預發行版,以及較早版本的可選補丁,等等。這一功能背後的理念是讓模塊可以輕鬆地向前和向後滾動,輕鬆進行A/B測試,並安全地提供可選補丁,所有這些都可以在單個交付中完成。
模塊依賴不一定是依賴。例如,應用程序可以指定需要模塊”A”,期望模塊”B”(也就是說,如果可以找到這個模塊就鏈接到它),並且支持模塊”C”(也就是說,如果依賴圖中的其他模塊導致這個模塊被鏈接,則只鏈接到這個模塊)。另外,模塊可以被嵌入,這意味著它實際上被包含在嵌入它的模塊中;這種能力主要是用來支持從多個模塊構造而來的單個模塊(出於組織或其他原因)的交付。

但最強大的方面則是這些功能的組合方式。具體來說,一個模塊在運行時不一定存在(present)另一個模塊,並且如果這個模塊存在,也不一定是某個特定版本,不一定包含特定的類或功能。這就是我們以前所說的DLL地獄。 Ecastasy為類和代碼的存在(presence)提供了一種方法,可選以版本或其他類的存在為條件,並且編譯器將把這些條件編譯到生成的模塊中,具體做法和將多個版本放入同一模塊的做法相同。換句話說,這個模塊可以同時支持另一個模塊或特定版本的存在與否,並且這個解析過程是動態鏈接過程的一部分。這允許模塊避免對某個模塊,或模塊特定版本的硬依賴,同時仍與這些模塊或版本(如果它們存在)完全集成並充分利用它們。
並且由於所有這些信息都被編碼到了模塊中,因此所有這些組合的測試都能完全自動化。說到測試:單元測試、功能測試和集成測試也可以內置到模塊中,並且——就像不需要的版本一樣——在生產環境中使用模塊時就不會存在測試了。

到現在為止應該已經很明顯了,我們考慮了很多事情,並且在設計上付出了很多努力。但為什麼要這樣做?其中一個原因是考慮到CVE和零day,以及生產中引入的重大更改。想像一下,你需要的時候手頭已經有了一個“已使用哪些版本測試了哪些版本”的矩陣。想像一下,模塊中任何給定版本的回歸和驗收測試已經內置進了這個模塊的對應版本中。想像一下,能夠在A/B部署中推出新補丁,並以可以實時將隔離環境中補丁的效果與要替換的版本進行對比,提前確定最終用戶將看到哪些實際更改。
支持這些功能的設計已經到位,但是工具和自動化(依賴於這些基礎功能)尚未構建,並且仍然有一段路要走。

InfoQ:針對DevOps的設計目標是否會擴展到支持漸進式交付?

Purdy:是這樣的,但這並不是一件容易的事。我們首先要明白的一件事是應用程序幾乎總是存在版本偏移,而漸進式交付只是版本偏移的一個例子。每當你同時運行一個應用程序的兩個不同版本時都會發生版本偏移。偏移可能出現在應用程序的舊版客戶端和新版服務後端之間,也可以出現在後端的各種服務器實例之間。不管怎樣,它對協議互操作性和狀態兼容性提出了強制要求,而這種要求本身就很重要。關於狀態,舊版本的代碼必須能夠與新版本的數據非破壞性兼容,並且新版本的代碼必須能夠接受(並可以自動升級)舊版本的數據。

我們首先認識到,版本偏移並不是反常現象,而是普遍存在的情況,幾乎在任何有分量的應用程序中都會出現這種情況。從幾年前設計可移植對象格式(POF)規範的工作中,我們就對該主題積累了一些經驗,這一規範支持向前和向後的schema兼容性。事實證明,接受並支持安全版本偏移是許多強大功能的基礎,包括漸進式交付、增量發布、傳統的A/B測試(及其自動化)等等。在橫向擴展環境中,為避免服務中斷,服務器將使用新版本的應用程序啟動,而裝載舊版應用程序的服務器將繼續運行一段時間。 (當新版本的發佈出現問題時,情況甚至可能會更加複雜,並且必須將應用程序回滾到以前的版本,因此新版本不能以某種方式更改應用程序的持久狀態,使得舊的應用程序無法繼續運行。)因此,我們在對象序列化和數據庫接口設計方面所做的所有設計工作,從一開始就有這個要求。

結合強大的模塊版本控制功能和資源注入(這是應用程序與外界通信的唯一方式),這允許自動化基礎架構同時運行新版本(啟用所有測試模式功能)和舊版本,同時將新版本保留在”盒中”,以使其狀態更改不可見,並且它對客戶端的響應實際上並未傳遞;這樣一來,就可以在生產負載和數據上試用新版本,而不會冒著損壞生產數據庫的風險,也不會影響最終用戶。同樣,自動化基礎架構可以用相同的方式發布升級,方法是逐步啟動和預熱運行新版本的服務器,然後逐漸減少從舊版到新版的流量;如果發生故障,可以逆轉這一過程。理想情況下,應用程序的新版本將在生產中運行一段時間,然後再將實際的生產負載從舊版轉移到新版——這段時間的長度要足夠證明新版沒有明顯的退化。類似地,可以從一個小子集開始轉移流量,同時繼續將大多數流量路由到舊版本,這樣在最終用戶與應用程序交互後才發現問題的情況下,對最終用戶的影響往往就能控制在最低限度。

數據庫API的設計的一個目標是最終允許有狀態系統在分層組織的基礎架構中運行。我們的目標是允許應用程序的某些部分在內容交付網絡(CDN)和邊緣層,直到5G基站中都能運行。為了實現這一目標,Ecastasy被設計為一種安全的可嵌入語言,並且數據庫API的設計使用了基於參與者的模型,也考慮到了工作單元和最終的一致性。最終目標是支持這些API一路直達客戶端級別,從而允許應用程序在間歇連接和脫機模式下也能正常運行。這些功能仍然處於藍圖之上,但我們打算提供概念證明,展示我們在完成這些API的初始版本時會怎樣支持這些能力。

InfoQ:WASM已經在一些領域展現了生機,那麼是什麼讓你們選擇了XTC?

Purdy:首先明確一點,我們尚不支持WASM,但這是我們設計的編譯目標之一,作為原生x86/x64和ARM的補充。 Ecastasy的一個目標是支持從前端的最前級到後端的最後級的所有共享組件。這意味著編程模型必須能一路可移植到瀏覽器中,因為瀏覽器占到客戶端的很大一塊比例。 (在此之前還要能在iOS、Android、macOS和Windows客戶端上原生運行)。

如果你以瀏覽器為目標,就必須轉換為JavaScript或編譯為WASM。由於我寧願砍掉自己的胳膊也不願生成大量的JavaScript來調試,因此這個選擇很簡單。還要記住LLVM已經支持了WASM:WASM是LLVM項目中的一等公民(代碼生成目標),而我們計劃的編譯後端一直都是LLVM。

InfoQ:誰會使用這門語言,他們將如何使用它?

Purdy:我們已經在自己的​​產品開發工作中開始用它,然後發現用了Ecastasy後就很難換回一種較舊的語言了。這種語言令人上癮。另一方面,這種語言仍處於積極開發階段,因此尚未迎來自己的黃金時段;也就是說,它尚未準備好用來構建現代應用程序。除非你真的很喜歡語言、編譯器和工具鏈開發,否則現在還不是採用Ecastasy的時候。

它在接下來的24個月內就可用於生產環境,我們也知道哪些人會用它。有些開發人員在為雲構建應用程序,這些應用程序必須運行在多種客戶端上,還要使用有狀態的無服務器後端部署。還有些開發人員重視自動化、可維護性、可管理性,希望語言能減少軟件生命週期的巨大成本。

在過去的25年中,我合作的大多數公司都花費了95%的IT預算(通常甚至更高!)來維持舊事物的運行。想要投入新的開發工作,甚至為現有的應用程序帶來巨大的發展,往往都是非常困難甚至無法做到的。這麼久以來,我們第一次有機會顛覆這種成本模型。 Ecastasy是思想上的巨大變革。

這種語言是免費和開源的。所有的內容都是如此。運行時、工具鏈、庫,所有的一切,完全開放。我們使用標準的Apa​​che開源許可證。你可以fork Ecastasy,你可以嵌入Ecastasy。 Ecstasy商標歸Ecstasy項目(該語言的維護組織)所有,但是除品牌之外,所有公司和開發人員可以使用這種語言做任何事情。

InfoQ:它會不會陷入無服務器和Kubernetes之間的夾縫中呢?

Purdy:這是第一種專為無服務器設計的語言。這聽起來像是在吹噓,但其實不然。之前的所有語言(除了JavaScript等幾種例外)都是作為分層蛋糕構建的,構建在在原生類庫和實現之上,在操作系統之上(能在系統中暴露的表面都暴露出來了) ,在物理機器之上。問題在於每一層都沒有將自己下面的層隱藏起來,而這個錯誤是有意為之的!

看看現在的亞馬遜是如何實現無服務器的:它們實際上為你提供了你自己的服務器。 (是的,所有操作都在幕後完成,但這就是它的工作機制。)為什麼?因為你的無服務器負載可以對環境、操作系統和“機器”(顯然是虛擬機)做任何事情,所以他們不會冒風險讓多個帳戶共享這台機器。

Ecastasy不會暴露機器,或操作系統,或在操作系統中可以找到的任何庫。相反,它使用的是控制反轉(IOC):Ecastasy將資源注入到應用程序中,而不是允許該應用程序遍歷計算機以查找其所需的資源。需要數據庫嗎?注入它。需要文件系統嗎?注入它。塊存儲?注入它。 HTTP訪問?注入它。網絡服務?注入它。歷史上第一次,一種語言的設計明確隱藏了運行應用程序代碼的整個宇宙,並且這是第一次一種語言允許所有不同的資源,按照託管應用程序的(Ecstasy)容器的意願來完全管理。這是一種從根本上為安全設計的語言,而不是事後通過某些安全事物層來確保安全性。

因此,從設計之初Ecastasy就是無服務器的。對於Kubernetes而言,這是一個令人驚嘆的工程解決方案,可以解決最初就不應該存在的極其複雜的問題。我希望Kubernetes會做得很好,因為有許多項目都與過去的事物緊密相聯,而Kubernetes是讓那些複雜的草皮球繼續滾動的阻力最小的途徑。

看,是時候改變了。如今,構建一個應用程序太昂貴了——通常需要開發人員將數十個甚至數百個庫和組件整合在一起。只要看看Node或其他類似的語言即可; 這些事物幾乎不可能維護,也難以保證安全性
我希望Ecastasy就是變革。

受訪者介紹

Cameron Purdy是11x開發人員,是Ecstasy編程語言的共同創建者,並且是Oracle Coherence的合著者。 Cameron是xqiz.it的聯合創始人兼首席執行官。之前,他是Tangosol的聯合創始人兼首席執行官,該公司被Oracle收購;並曾擔任Oracle的高級副總裁,負責企業級Java、WebLogic、Coherence,Traffic Director和Exalogic等產品。 Cameron是Java語言和虛擬機規範的貢獻者,便攜式對象格式(POF)規範的作者,並且在分佈式計算和數據管理方面擁有大量專利。

原文鏈接

Newly Announced Ecstasy Programming Language Targets Cloud-Native Computing