Salesforce在生產中大規模採用OpenJDK 11的一年

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Salesforce是首批大規模採用OpenJDK 11的大型企業之一,在2018年底OpenJDK 11發佈後不久,Salesforce就開始了OpenJDK 11的採用之旅。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"前沿嗎? 當然是。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"安全嗎? 絕對地。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"你可能還不知道,Salesforce在整合前沿、轉型技術,並以安全、可靠、無縫的方式,同時在不損害其"},{"type":"link","attrs":{"href":"https:\/\/www.salesforce.com\/company\/our-story\/","title":null,"type":null},"content":[{"type":"text","text":"#1核心價值:信任"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"的前提下,將這些技術提供給客戶方面一直處於行業的領先地位。從"},{"type":"link","attrs":{"href":"https:\/\/www.cncf.io\/case-studies\/salesforce\/","title":null,"type":null},"content":[{"type":"text","text":"gRPC"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"到"},{"type":"link","attrs":{"href":"https:\/\/engineering.salesforce.com\/adopting-kubernetes-46b6c13b204b","title":null,"type":null},"content":[{"type":"text","text":"Kubernetes"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":",Salesforce在新技術領域有着早期大膽探索的歷史。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"在本文的案例中,將主要的Salesforce CRM應用程序升級到OpenJDK 11是一項龐大的跨組織工作。 把它做好,不僅能爲我們帶來幾年的Java運行時創新紅利,也能爲我們的客戶提供更好的體驗,併爲開源社區做出貢獻。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"背景"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"2018年末,OpenJDK 11作爲Java最新的長期支持(LTS)版本面世。這開啓了一個人們期待已久的機遇,推動了Salesforce應用程序的向前發展,併爲我們的內部開發人員帶來了巨大的新特性和創新。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"爲什麼我們認爲我們可以安全地從OpenJDK 8(上一個最新的LTS版本)過渡到OpenJDK 11呢?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"首先,我們並不是一蹴而就的。對於OpenJDK 9和OpenJDK 10這兩個版本,雖然我們只打算將它們作爲墊腳石,而不在生產環境中使用,但一旦它們的版本可用,我們就會立即升級到對應版本。正如你所料,最困難的部分是從OpenJDK 8升級到OpenJDK 9,這需要對Salesforce應用程序進行重大的更改。從OpenJDK 9升級到OpenJDK 10,再從OpenJDK 10升級到OpenJDK 11,都只需做相對較小的改動。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"另外,Java的向後兼容性保證允許用舊版本Java開發編譯的應用程序代碼能運行在新的版本上,這一功能的威力不容小覷。向後兼容性爲遷移提供了巨大的幫助,這樣我們的大多數代碼都不需要更改。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Salesforce應用程序利用Java向後兼容性的方法之一是,將用於構建Salesforce應用程序的Java版本與用於啓動它的Java版本分開。這使我們能夠首先集中精力將過程的一端從OpenJDK 8升級到OpenJDK 11,而另一端仍保持在OpenJDK 8上不變,並將其升級到OpenJDK 11的時間往後推遲。我們內部開發人員的目標是,通過在初始化和啓動Salesforce應用程序的腳本中隱藏所有的差異和複雜性的方式,讓OpenJDK 8和OpenJDK 11運行時之間的切換儘可能的簡單和無縫。因此,對於我們的開發人員來說,升級到OpenJDK 11運行時就像用OpenJDK 11版本的字符串覆蓋配置屬性一樣簡單。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"也就是說,我們面臨的另一個挑戰是,我們的OpenJDK 11遷移工作跨越了多個版本週期,我們必須確保任何支持OpenJDK 11的增量更改都不會打破我們的生產環境(生產環境仍然是基於OpenJDK 8部署的),也不能對客戶的信任產生任何負面影響。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"平臺的變更&挑戰"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"當我們一個接一個地升級OpenJDK版本時,我們遇到了Java平臺的許多顯著變更。而我們的遷移之路漫長且需有條不紊地推進,這意味着這些變更會給我們帶來了很多挑戰,但在這裏我們只討論其中的幾個。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"類路徑與模塊化"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/en.wikipedia.org\/wiki\/Java_version_history#Java_SE_9","title":null,"type":null},"content":[{"type":"text","text":"Java SE 9"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"平臺引入的重大變更之一就是Java平臺模塊系統(Java Platform Module System,JPMS)。JPMS將JDK劃分爲多個模塊,每個模塊都是一組命名唯一且可重用的相關包。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"好消息是,Java 9仍然支持傳統的類路徑,它能與模塊路徑一起工作,並映射到一個被稱爲未命名模塊的特殊模塊上。因此,構成Salesforce應用程序類路徑的所有JAR文件都會自動加入模塊系統,從而導致了傳統類路徑和模塊路徑的混合。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"實際上,Salesforce應用程序的整個類加載器層次結構都保留在Java 9及更高版本中。它由我們的Web服務器和Servlet容器錨定,委託給OSGi類加載器,而OSGi類加載器又委託給Java運行時的內置類加載器。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"然而,作爲Jigsaw計劃的一部分,Java 9帶來了一個影響類加載的重大變更。這是對"},{"type":"link","attrs":{"href":"https:\/\/docs.oracle.com\/javase\/8\/docs\/technotes\/guides\/standards\/index.html","title":null,"type":null},"content":[{"type":"text","text":"授權標準覆蓋機制"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"(Endorsed Standards Override Mechanism,用於支持加載包含授權標準和獨立技術實現的JAR文件)和"},{"type":"link","attrs":{"href":"https:\/\/docs.oracle.com\/javase\/8\/docs\/technotes\/guides\/extensions\/index.html","title":null,"type":null},"content":[{"type":"text","text":"擴展機制"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"( Extension Mechanism,用於支持加載包含擴展或可選軟件包的JAR文件)的移除。由於Salesforce應用程序過去依賴於這兩種機制,因此必須使用 "},{"type":"codeinline","content":[{"type":"text","text":"-module-path"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" 、 "},{"type":"codeinline","content":[{"type":"text","text":"-upgrade-module-path"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" 和 "},{"type":"codeinline","content":[{"type":"text","text":"-patch-module"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" 標誌的組合,將所有受影響的JAR文件遷移到Salesforce應用程序的模塊路徑下。不過,這些非模塊化的JAR文件都無需轉換爲模塊:它們作爲依賴項被放置在Salesforce應用程序的模塊路徑上,從而自動成爲模塊化的。此功能被稱爲自動模塊化,創建它是爲了減輕將現有應用程序轉換爲新模塊系統的負擔。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"影響Salesforce應用程序的另一個變更是刪除了Salesforce應用程序所依賴的Java Enterprise Edition(“Java EE”)API。Java 9開始將這些API分離到它們各自的模塊中,這些模塊被註解爲不推薦使用,以便刪除,這表明了在將來的版本中會刪除它們的意圖。這些模塊包含在運行時鏡像中,但默認情況下未啓用。因而,它們必須通過 "},{"type":"codeinline","content":[{"type":"text","text":"--add modules"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" 標識顯式“激活”。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"從Java11開始,這些模塊不再包含在運行時中("},{"type":"link","attrs":{"href":"https:\/\/openjdk.java.net\/jeps\/320","title":null,"type":null},"content":[{"type":"text","text":"參見JEP 320:刪除Java EE和CORBA模塊"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":")。相反,Java EE和CORBA技術的獨立版本作爲Maven構件發佈,並可以從第三方網站(如Maven Central)上獲取,我們從那裏下載了它們並將它們添加到了Salesforce應用程序的模塊路徑中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"向後不兼容"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"在將Salesforce應用程序的Java運行時遷移到OpenJDK 11時,我們發現了許多向後不兼容的變更。其中大多數都是“設計使然”,並且是涵蓋在版本說明中了的,正如下面所要討論的那樣。(有一個true的迴歸影響了布爾型bean屬性的內省;這是由OpenJDK實現本身的一個bug引起的,我們報告了這個bug,並且它已經被修復了。)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"設計上向後不兼容變更的例子很明顯,因爲它會導致JVM在啓動時中斷,並出現如下的錯誤:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Unrecognized VM option '
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章