一起來聊聊自己使用的企業級項目開發技術棧~

一起來聊聊自己使用的企業級項目開發技術棧~

【贈書】《Spring Boot 開發實戰》作者與你探討最佳實踐的開發-小蝦2018參與的聚能聊話題-雲棲社區 http://yq.aliyun.com/roundtable/325534/answer/608736#visit608736

1.Java 程序員到了必須學習 Spring Boot 的時候了嗎?

image

說起 Spring Boot 我們不得不先了解一下 Spring 這個企業,不僅因爲 Spring Boot 來源於 Spirng 大家族,而且 Spring Boot 的誕生和 Sping 框架的發展息息相關。

時間回到2002年,當時正是 Java EE 和 EJB 大行其道的時候,很多知名公司都是採用此技術方案進行項目開發。這時候有一個美國的小夥子認爲 EJB 太過臃腫,並不是所有的項目都需要使用 EJB 這種大型框架,應該會有一種更好的方案來解決這個問題。

爲了證明他的想法是正確的,於2002年10月甚至寫了一本書《 Expert One-on-One J2EE 》,介紹了當時 Java 企業應用程序開發的情況,並指出了 Java EE 和 EJB 組件框架中存在的一些主要缺陷。在這本書中,他提出了一個基於普通 Java 類和依賴注入的更簡單的解決方案。

隨着使用 Spring 進行開發的個人和企業越來越多,Spring 也慢慢從一個單一簡潔的小框架變成一個大而全的開源軟件,Spring 的邊界不斷的進行擴充,到了後來 Spring 幾乎可以做任何事情了,市面上主流的開源軟件、中間件都有 Spring 對應組件支持,人們在享用 Spring 的這種便利之後,也遇到了一些問題。

Spring 每集成一個開源軟件,就需要增加一些基礎配置,慢慢的隨着人們開發的項目越來越龐大,往往需要集成很多開源軟件,因此後期使用 Spirng 開發大型項目需要引入很多配置文件,太多的配置非常難以理解,並容易配置出錯,到了後來人們甚至稱 Spring 爲配置地獄。

Spring 似乎也意識到了這些問題,急需有這麼一套軟件可以解決這些問題,這個時候微服務的概念也慢慢興起,快速開發微小獨立的應用變得更爲急迫,Spring 剛好處在這麼一個交叉點上,於 2013 年初開始的 Spring Boot 項目的研發,2014年4月,Spring Boot 1.0.0 發佈。

Spring Boot 誕生之初,就受到開源社區的持續關注,陸續有一些個人和企業嘗試着使用了 Spring Boot,並迅速喜歡上了這款開源軟件。直到2016年,在國內 Spring Boot 才被正真使用了起來,期間很多研究 Spring Boot 的開發者在網上寫了大量關於 Spring Boot 的文章,同時有一些公司在企業內部進行了小規模的使用,並將使用經驗分享了出來。從2016年到2018年,使用 Spring Boot 的企業和個人開發者越來越多,我們從 Spring Boot 關鍵字的百度指數就可以看出。

image

上圖爲2014年到2018年 Spring Boot 的百度指數,可以看出 Spring Boot 2.0 的推出引發了搜索高峯。

當然 Spring Boot 不是爲了取代 Spring ,Spring Boot 基於 Spring 開發,是爲了讓人們更容易的使用 Spring。看到 Spring Boot 的市場反應,Spring 官方也非常重視 Spring Boot 的後續發展,已經將 Spring Boot 作爲公司最頂級的項目來推廣,放到了官網上第一的位置,因此後續 Spring Boot 的持續發展也被看好。

Spring Boot 特性

使用 Spring 項目引導頁面可以在幾秒構建一個項目
方便對外輸出各種形式的服務,如 REST API、WebSocket、Web、Streaming、Tasks
非常簡潔的安全策略集成
支持關係數據庫和非關係數據庫
支持運行期內嵌容器,如 Tomcat、Jetty
強大的開發包,支持熱啓動
自動管理依賴
自帶應用監控
支持各種 IED,如 IntelliJ IDEA 、NetBeans
Spring Boot 這些特性會給我們研發帶來非常大的優勢!

2.我的Java語言用得很溜,還需要學習什麼 Kotlin 嗎?

下面這張圖片來自 Code Complete 一書,展示了軟件項目的各種活動所佔的比例:

image

遵循 Steve McConnell 在 Code Complete 一書中提出的模式,我們可以將軟件構建活動分解成三個子活動:詳細設計、編碼與調試、開發測試。

Kotlin 對於詳細設計子活動沒什麼影響(這項活動通常獨立於選用的特定的面向對象編程語言),因此,在這一部分,Kotlin 和 Java 需要付出同樣的努力。

據我所知,對於開發測試子活動,Kotlin 也沒有提出什麼革命性的東西。因此,開發測試需要付出的努力也一樣。

就剩編碼與調試子活動了。

在考慮了所有的情況之後,谷歌最終決定支持 Kotlin Anroid 開發。我認爲,谷歌員工都是非常聰明的人,我相信他們在決定支持 Kotlin 之前已經進行了非常深入的分析。

Kotlin是JetBrains的一種新的編程語言。它首次出現在2011年,JetBrains推出了名爲“科特林”的項目。 Kotlin是開源語言。
基本上像Java一樣,C和C ++ - Kotlin也是“靜態類型編程語言”。

Kotlin語言的好處

Kotlin編譯爲JVM字節碼或JavaScript - 像Java一樣,Bytecode也是Kotlin程序的編譯格式。 字節碼錶示編程代碼,一旦編譯,就通過虛擬機而不是計算機的處理器運行。 通過使用這種方法,一旦編譯並運行虛擬機,源代碼就可以在任何平臺上運行。 一旦kotlin程序被轉換爲字節碼,它可以通過網絡傳輸並由JVM(Java虛擬機)執行。

Kotlin程序可以使用所有現有的Java框架和庫 - 是的,Kotlin程序可以使用所有現有的Java框架和庫,甚至依賴於註釋處理的高級框架也是如此。關於kotlin語言的主要重點是它可以輕鬆地與Maven的,搖籃和其他構建系統集成。
Kotlin可以輕鬆學習,平易近人。通過簡單的閱讀語言參考可以輕鬆學習。語言乾淨直觀(易於使用和理解)。Kotlin看起來很像Scala,但更簡單。
Kotlin是開放源碼,沒有收費。
將Java自動轉換爲Kotlin - JetBrains將IntelliJ集成了一個新功能,將Java轉換爲Kotlin,節省了大量的時間。而且它也節省了我們重新編寫世代代碼。
Kotlin的空安全性很好 - 現在擺脫NullPointerExceptions。這種類型的系統幫助我們避免空指針異常。在Kotlin系統中,系統只拒絕編譯嘗試分配或返回null的代碼考慮以下示例 -
代碼審查不是問題 - 科特林更注重可讀性的語法,所以代碼審查不是一個問題,它們仍然可以由那些不熟悉語言的團隊成員完成。

Kotlin語言的特點

十億美元的錯誤是正確的。 如上所述,Kotlin避免了空指針異常。 如果我們嘗試分配或返回null到變量或函數,那麼它將不會編譯。

但是在某些特殊情況下,如果我們在程序中需要可空性,那麼我們必須非常好地問Kotlin。 每個Nullable型都需要特別的護理和治療。 我們不能像非可空類型那樣對待它們,這是一件非常好的事情。

2017年穀歌I/O大會的最後,谷歌宣佈將Kotlin語言作爲安卓開發的一級編程語言。Kotlin由JetBrains公司開發,與Java 100%互通,並具備諸多Java尚不支持的新特性。谷歌稱還將與JetBrains公司合作,爲Kotlin設立一個非盈利基金會。

Kotlin的文件擴展名爲.kt和.kts,使用Kotlin,你可以用更少的代碼獲得更多的功能。 而你寫的代碼越少,你犯的錯誤就越少。除此以外,他還有如下特點:

Kotlin編譯爲JVM字節碼或JavaScript,方便在沒有JVM的設備上運行。
Kotlin程序可以使用所有現有的Java框架和庫,也就是說所有的現有程序不需要更改就可以直接被調用。
Kotlin可以輕鬆學習,平易近人。它的規則及其簡單,語法規則少,易於學習。
Kotlin是開放源碼,沒有收費。雖然java也是開源語言,但是相比於其他的非開源的還是有一定優勢的。
將Java自動轉換爲Kotlin,有強迫症的也可以這麼搞,不用逼死強迫症的。
Kotlin的空安全性很好
代碼審查不是問題。
精簡語法和簡明,看得懂,學得會,寫得出。
空安全 Null Safety- 如上節所述,Kotlin避免了NullPointerException。
擴展函數Extension Functions- Kotlin允許我們擴展現有類的功能,而不繼承它們。意味着Kotlin提供了擴展具有新功能的類的能力,而無需繼承類。
智能Casts - 當談到Casts時,Kotlin編譯器真的很聰明。在許多情況下不需要在kotlin中使用顯式轉換操作符,但是在Kotlin中,對於不可變值有“is-checking”,在需要時自動插入

類型推斷Type Inference- 在Kotlin中,有一件偉大的事情,你不必明確指定每個變量的類型(以清晰詳細的方式)。但是,如果要明確定義數據類型,還可以這樣做。

函數式編程Functional Programming- 重要的是Kotlin是一種功能性的編程語言。基本上,Kotlin由許多有用的方法組成,其中包括高階函數,lambda表達式,運算符重載,惰性評估,運算符重載等等。

你可以擺脫util類讓我們來討論一下有關使用util類的醜陋事情。 你有沒有一個項目沒有他們? 我們幾乎不記得這一切。 Kotlin有一個聰明的解決方案 - 擴展功能 - 幫助你擺脫所有的util類一勞永逸。擴展函數幾乎是一個通常的Kotlin函數。 但是當你聲明它,你需要指定的實例將具有擴展功能的類。

3.Maven 已經這麼強大了,Gradle 真的有那麼好用嗎?

Java世界中主要有三大構建工具:Ant、Maven和Gradle。經過幾年的發展,Ant幾乎銷聲匿跡、Maven也日薄西山,而Gradle的發展則如日中天。筆者有幸見證了Maven的沒落和Gradle的興起。Maven的主要功能主要分爲5點,分別是依賴管理系統、多模塊構建、一致的項目結構、一致的構建模型和插件機制。我們可以從這五個方面來分析一下Gradle比起Maven的先進之處。

依賴管理系統

Maven爲Java世界引入了一個新的依賴管理系統。在Java世界中,可以用groupId、artifactId、version組成的Coordination(座標)唯一標識一個依賴。任何基於Maven構建的項目自身也必須定義這三項屬性,生成的包可以是Jar包,也可以是war包或者ear包。一個典型的依賴引用如下所示:


junit
junit
4.12
test


org.springframework
spring-test

從上面可以看出當引用一個依賴時,version可以省略掉,這樣在獲取依賴時會選擇最新的版本。而存儲這些組件的倉庫有遠程倉庫和本地倉庫之分。遠程倉庫可以使用世界公用的central倉庫,也可以使用Apache Nexus自建私有倉庫;本地倉庫則在本地計算機上。通過Maven安裝目錄下的settings.xml文件可以配置本地倉庫的路徑,以及採用的遠程倉庫的地址。

Gradle在設計的時候基本沿用了Maven的這套依賴管理體系。不過它在引用依賴時還是進行了一些改進。首先引用依賴方面變得非常簡潔。

dependencies {
compile 'org.hibernate:hibernate-core:3.6.7.Final'
testCompile ‘junit:junit:4.+'
}
第二,Maven和Gradle對依賴項的scope有所不同。在Maven世界中,一個依賴項有6種scope,分別是complie(默認)、provided、runtime、test、system、import。而grade將其簡化爲了4種,compile、runtime、testCompile、testRuntime。那麼如果想在gradle使用類似於provided的scope怎麼辦?彆着急,由於gradle語言的強大表現力,我們可以輕鬆編寫代碼來實現類似於provided scope的概念(例如How to use provided scope for jar file in Gradle build?)。

第三點是Gradle支持動態的版本依賴。在版本號後面使用+號的方式可以實現動態的版本管理。

第四點是在解決依賴衝突方面Gradle的實現機制更加明確。使用Maven和Gradle進行依賴管理時都採用的是傳遞性依賴;而如果多個依賴項指向同一個依賴項的不同版本時就會引起依賴衝突。而Maven處理這種依賴關係往往是噩夢一般的存在。而Gradle在解決依賴衝突方面相對來說比較明確。

Maven將項目的構建週期限制的太死,你無法在構建週期中添加新的phase,只能將插件綁定到已有的phase上。而現在項目的構建過程變得越來越複雜,而且多樣化,顯然Maven對這種複雜度缺少足夠的應變能力。比如你想在項目構建過程中進行一項壓縮所有javascript的任務,那麼就要綁定到Maven的現有的某個phase上,而顯然貌似放在哪個phase都不太合適。而且這些phase都是串行的,整個執行下來是一條線,這也限制了Maven的構建效率。而Gradle在構建模型上則非常靈活。在Gradle世界裏可以輕鬆創建一個task,並隨時通過depends語法建立與已有task的依賴關係。甚至對於Java項目的構建來說,Gradle是通過名爲java的插件來包含了一個對Java項目的構建週期,這等於Gradle本身直接與項目構建週期是解耦的。

插件機制

Maven和Gradle設計時都採用了插件機制。但顯然Gradle更勝一籌。主要原因在於Maven是基於XML進行配置。所以其配置語法太受限於XML。即使實現很小的功能都需要設計一個插件,建立其與XML配置的關聯。

Maven的設計核心Convention Over Configuration被Gradle更加發揚光大,而Gradle的配置即代碼又超越了Maven。在Gradle中任何配置都可以作爲代碼被執行的,我們也可以隨時使用已有的Ant腳本(Ant task是Gradle中的一等公民)、Java類庫、Groovy類庫來輔助完成構建任務的編寫。

這種採用本身語言實現的DSL對本身語言項目進行構建管理的例子比比皆是。比如Rake和Ruby、Grunt和JavaScript、Sbt和Ruby…..而Gradle之所以使用Groovy語言實現,是因爲Groovy比Java語言更具表現力,其語法特性更豐富,又兼具函數式的特點。這幾年興起的語言(比如Scala、Go、Swift)都屬於強類型的語言,兼具面向對象和函數式的特點。

最後想說的Gradle的命令行比Maven的要強大的多。

4.在Docker容器中運行Spring Boot應用真的有那麼方便嗎?

image

Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後發佈到任何流行的Linux機器上,也可以實現虛擬化,容器是完全使用沙箱機制,相互之間不會有任何接口。

接下來我們看看docker的故事。
環境管理複雜 - 從各種OS到各種中間件到各種app, 一款產品能夠成功作爲開發者需要關心的東西太多,且難於管理,這個問題幾乎在所有現代IT相關行業都需要面對。
雲計算時代的到來 - AWS的成功, 引導開發者將應用轉移到 cloud 上, 解決了硬件管理的問題,然而中間件相關的問題依然存在 (所以openstack HEAT和 AWS cloudformation 都着力解決這個問題)。開發者思路變化提供了可能性。
虛擬化手段的變化 - cloud 時代採用標配硬件來降低成本,採用虛擬化手段來滿足用戶按需使用的需求以及保證可用性和隔離性。然而無論是KVM還是Xen在 docker 看來,都在浪費資源,因爲用戶需要的是高效運行環境而非OS, GuestOS既浪費資源又難於管理, 更加輕量級的LXC更加靈活和快速
LXC的移動性 - LXC在 linux 2.6 的 kernel 裏就已經存在了,但是其設計之初並非爲雲計算考慮的,缺少標準化的描述手段和容器的可遷移性,決定其構建出的環境難於遷移和標準化管理(相對於KVM之類image和snapshot的概念)。docker 就在這個問題上做出實質性的革新。這是docker最獨特的地方。

image

image

VM技術和容器技術對比

面對上述幾個問題,docker設想是交付運行環境如同海運,OS如同一個貨輪,每一個在OS基礎上的軟件都如同一個集裝箱,用戶可以通過標準化手段自由組裝運行環境,同時集裝箱的內容可以由用戶自定義,也可以由專業人員製造。這樣,交付一個軟件,就是一系列標準化組件的集合的交付,如同樂高積木,用戶只需要選擇合適的積木組合,並且在最頂端署上自己的名字(最後個標準化組件是用戶的app)。這也就是基於docker的PaaS產品的原型。

image

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章