摘要:本文中,将介紹微服務項目中常用的7種語言,并通過幾個因素對比一下,包括技術方面的考慮、社會(生态系統)方面的考慮以及經濟方面的考慮。
連結:https://t.csdnimg.cn/SQZO
聲明:本文為 CSDN 翻譯,未經允許禁止轉載。
作者:JOSH WULF
譯者:彎月
出品 | CSDN(ID:CSDNnews)
微服務是一種架構風格,通過一組服務構成應用程式,這些服務具備以下特質:
- 高可維護性和可測試性;
- 松散耦合;
- 可獨立部署;
- 緊緊圍繞公司業務組織;
- 由一個小團隊負責。
康威定律指出,“設計系統的架構受制于産生這些設計的組織的溝通結構。”
如果組織擁有多個團隊,每個團隊負責一個大型系統的一部分,那麼就可以通過微服務分離關注點,将各個獨立封裝的服務配置設定給不同的團隊。這些團隊之間應建立明确的職責界限,根據自己的時間計劃部署各個服務。
這些因素有利于采用多種程式設計語言。由于每個服務都是單獨開發和部署的,而且是松散耦合的,由不同的團隊負責,是以完全可以采用不同的語言編寫。
那麼,适合編寫微服務的最佳程式設計語言有哪些呢?
這要視具體情況而定,而且決定因素多種多樣。
在本文中,我将介紹一下微服務項目中常用的7種語言,并通過幾個因素來對比一下這幾種語言,其中包括技術方面的考慮、社會(生态系統)方面的考慮以及經濟方面的考慮。我打算介紹的7種語言如下:
- Java
- C#
- Go
- Typescript
- Python
- Haskell
- Ballerina
我選擇這7種語言主要基于以下因素:
- 受歡迎程度(參考指數:https://pypl.github.io/PYPL.html);
- 微服務的适用性(例如,PHP雖然很流行,卻不适合微服務);
- 某個方面表現出衆(例如,Haskell的絕對受歡迎程度不高,但在函數式語言中的排名很高;Ballerina雖是一種早期的小衆語言,卻展示出了強大的網絡級抽象能力)。
此外,我還會提到一些值得注意的語言,雖然它們沒有進入前七名,但仍然值得考慮。
Java
Java 創立于 1995 年,是世界上最流行的程式設計語言之一。長期的維護和高人氣說明Java是一個可靠的選擇。曾有人說:“沒有人會因為購買IBM而被解雇”,Java也是如此:沒有人會因為選擇的Java作為實作語言而被解雇。
Java離不開JVM,這個跨平台執行環境可以讓Java代碼“編寫一次,随處運作”,此外JVM還有助于實作規模經濟。
雖然你不太可能将服務部署到多個作業系統上,但開發人員能夠在多個目标作業系統之間來回切換對創造規模經濟有很大的好處。這意味着,願意應聘JVM相關崗位的開發人員有很多。
這種規模經濟也造就了一個龐大的生态系統。Spring Boot是一個功能十分強大的流行架構,可用于在 Java 中建構微服務。此外,Micronaut也是一種流行的選擇。
早期版本的JVM有一個主要問題:性能。JVM是一個抽象層,任何抽象都會引入開銷。現代版本的JVM已經解決了運作時的性能問題,尤其是 GraalVM。如果你在為啟動時的開銷而頭疼,則可以考慮Quarkus。啟動時的開銷對于響應式架構來說尤其是一個問題,例如函數即服務(lambda函數)。
此外,Kotlin、Scala 或 Ballerina等其他語言也可以編譯出在JVM上運作的程式。你可以利用現有的 Java 庫和架構生态系統,因為Java具備互操作性。
Java曾因為空指針異常的問題,引發了“十億美元的錯誤”事件。為此,Java 8引入了 Optional 類型。Kotlin 使用不可為空的類型,是以預設就帶有這種保護機制。
下面是一些使用 Spring Boot 實作 REST 路由的示例 Java 代碼:
package com.example.springboot; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("/") public String index { return "Greetings from Spring Boot!"; } }
優點
- 龐大的支援生态系統。
- 悠久的曆史,成功的企業應用程式。
- 大量的開發人員。
缺點
- 冗長的文法(Kotlin等JVM的替代語言解決了這個問題)。
- 開發人員的技術水準層次不齊。
何時選用Java?
- 你已掌握Java。
- 你希望雇傭大量開發人員,外包一些開發。
- 你希望在部署和管理中使用JVM專業知識,而且還可以選擇代替JVM的語言。
C#
C#是微軟早期開發的一種程式設計語言,微軟開發C#是為了阻止JVM和Java語言在Windows上的不斷擴張。
C#的文法與Java非常相似。二者都是基于C的現代語言,支援面向對象。如前所述,最初微軟開發C#是為了在Windows上取代Java。C#是編譯的中間語言,相對應的底層虛拟機是.NET VM。
近年來,.NET VM 已實作跨平台,.NET Core可以讓 C# 代碼在 Linux 和 Mac 作業系統上運作。是以,開發人員也可以在Linux 伺服器上運作C#。
雖然.NET 和 C#近期才實作了跨平台,但由于Windows龐大的使用者基礎,這兩門語言也擁有龐大的庫生态系統。微軟自己的架構ASP.NET也可用來開發微服務。
C# 8.0 引入了可為空的引用類型,以防止在運作時出現空指針異常。
下面是一些在 ASP.NET 中實作 REST 路由的示例 C# 代碼:
[ApiController] public class PeopleController : ControllerBase { [HttpGet("people/all")] public ActionResult> GetAll { return new { new Person { Name = "Ana" }, new Person { Name = "Felipe" }, new Person { Name = "Emillia" } }; } }
優點
- 背後擁有微軟的強大支援,使用者基礎龐大,财力雄厚。
- 大量的開發人員。
缺點
- 冗長的文法。
- 開發人員的技術水準層次不齊。
何時選用C#?
- 你已掌握C#技術。
- 你使用的作業系統是Windows。
Go
Go是一種網絡及系統現代程式設計語言,由谷歌開發,于2012年釋出1.0版本。相較于Java 和C#,Go是一種靜态類型的編譯語言,生成的是靜态連結的原生二進制檔案,而不是在 VM 中執行的中間代碼。
Go旨在成為一種底層的系統和網絡現代程式設計語言,它在強大的功能(例如指針)和安全性(例如記憶體管理)之間找到了平衡點。
Go提供了一套标準的格式化規則,還有一個将這些規則應用到代碼庫的内置實用程式。是以不會再有Tab鍵與空格之類的争論。
雖然你可以利用Go開發底層的網絡功能,但在開發微服務時可能并不需要這麼做。有大量的架構建構在進階抽象之上,比如Gin Web Framework、Buffalo、Gorilla、Fiber 和 Echo等,可供你選擇。
Go的許多微服務和 Web 架構都是由其他程式設計語言編寫的。是以,Ruby on Rails、Express Node.js等開發人員都可能發現一兩種感覺很熟悉的微服務或架構。
許多程式員在遇到Go後,重拾了程式設計的樂趣。TJ Holowaychuk是Node.js的早期采用者之一,也是 Node 生态系統的主要貢獻者,他都選擇轉而使用 Go。
Go沒有在運作時針對nil 指針異常的保護,但它有一個标準的“error, result”模式,會強制使用者編寫錯誤處理,這在大多數時候也能提供一定的安全性。
Go的示例代碼:
func ListAction(out http.ResponseWriter, req *router.Request) { resource, exists := resources[req.Param("resource")] if exists == false { //todo: return not found return } action, exists := resource["list"] if exists == false { //todo: return not found return } action(out, req) }
優點
- 現代程式設計語言。
- 語言的設計考慮了安全性和開發效率,适合程式設計新手。
缺點
- 生态系統不夠成熟。
- 可雇用的開發人員數量較少。
何時選用Go?
- 如果你對Go感興趣。
- 團隊喜歡Go,且重燃了對程式設計的熱情。
- 你需要比JavaScript更安全的程式設計語言。
TypeScript
TypeScript是JavaScript的超集,它添加了嚴格類型(可選)。TypeScript需要轉譯為JavaScript,然後在JavaScript解釋器中執行。
JavaScript本身是一種動态的弱類型語言,最初編寫于 1995 年(作者隻用了10天的時間),旨在實作網頁中的少量互動性。随後,JavaScript逐漸擴充到為浏覽器中的整個應用程式提供支援,如今還可通過Node.js、Deno 或 Bun提供伺服器端代碼。
如今,JavaScript無處不在,使用範圍非常廣泛,因為它的“虛拟機”可通過 Web 浏覽器安裝到網際網路的每台計算機上,而 .NET 和 Java 虛拟機沒有這樣的載體。
雖然JavaScript産生了爆炸式的增長,但從語言的角度來看,它的結構性遠遠跟不上它的增長速度。
TypeScript旨在解決使用動态的解釋性語言建構大型應用程式時出現的許多問題。TypeScript讓JavaScript的類型變得更加嚴格。代碼庫可以通過靜态分析進行推理,并通過重構強化,而且還提供了代碼提示和自動補齊等功能,此外轉譯還增加了一層安全性。
TypeScript 是由 C# 的語言設計者 Anders Hejlsberg 設計的,是以 C# 甚至是 Java 開發人員對TypeScript都不陌生。
Node.js 有一個龐大的庫和架構生态系統,比如功能齊全的NestJS、極簡主義Express等。
NPM(Node包管理器)包含數千個可在應用程式中使用的包。
你可以選用函數式程式設計模式,比如使用 fp-ts 之類的庫,以防止運作時空指針異常,但這并不會一直深入技術棧底層。你引入的庫依然可能會引發運作時空指針異常。
使用 NestJS 的示例 TypeScript 代碼:
import { Controller, Get } from '@nestjs/common'; @Controller('cats') export class CatsController { @Get findAll: string { return 'This action returns all cats'; } } 使用 Express 的示例 TypeScript 代碼: import express, { Express, Request, Response } from 'express'; const app: Express = express; const port = process.env.PORT; app.get('/', (req: Request, res: Response) => { res.send('Express + TypeScript Server'); }); app.listen(port, => { console.log(`[server]: Server is running at https://localhost:${port}`); });
優點
- 大量的庫和架構。
- 大量了解 JavaScript 的開發人員。
- TypeScript 引入了安全功能,對經驗不足的開發人員很友好。
- 整個技術棧隻需要這一種語言。
缺點
- NPM包可能被污染,是一個安全隐患。
- 龐大的 node_modules 目錄會導緻應用程式膨脹。
何時選用TypeScript?
- 你希望整個技術棧隻使用一種語言。
Python
Python是一種進階通用解釋型語言。Python最顯著的特征是“有意義的空白”。Python沒有使用花括号,而是使用縮進來表示嵌套。
Python 最初釋出于上個世紀80年代初期,是目前最流行的程式設計語言之一,并且由于其在資料科學中的大量使用而越來越受歡迎。
你隻需使用Python的标準庫就可以編寫 gRPC 微服務,而且還可以利用許多流行的架構,例如 Flask、Django、Nameko、FastAPI 和 MinOS。
Python 沒有針對空指針異常的保護。
下面是使用 Flask 實作 REST 路由的示例 Python 代碼:
from flask import Flask #importing the module app=Flask(__name__) #instantiating flask object @app.route('/') #defining a route in the application def func: #writing a function to be executed return 'PythonGeeks' if __name__=='main': #calling main app.debug=True #setting the debugging option for the application instance app.run #launching the flask's integrated development webserver
優點
- 曆史悠久的大型社群,廣泛的工具庫。
- 美觀的代碼格式(如果你讨厭花括号的話)。
缺點
- 解釋型語言,速度可能是一個問題。
- 多線程很棘手。
何時選用Python?
- 你已在使用Python。
- 你的領域涉及機器學習、資料科學或人工智能。
Haskell
Haskell是一種純粹的函數式語言,它是惰性求值和靜态類型的,非常适合并發處理。然而,Haskell的學習曲線非常陡峭,不僅僅是文法,還有範式。Haskell 最初是作為大學的學術語言開發的,現已成為深入了解程式抽象的進階程式員的流行語言。
Haskell 程式經過編譯後,可保證每次運作(95% 的時間裡)都沒有未處理的運作時異常。隻要程式編寫正确,Haskell 在運作時就非常穩定。
Mu-haskell是一組Haskell的微服務庫。Haskell的範式并不适用于架構,但适用于庫。
下面是實作 gRPC 伺服器的示例 Haskell 代碼:
main :: IO main = runGRpcApp msgProtoBuf 8080 server server :: (MonadServer m) => SingleServerT Service m _ server = singleService
優點
- 能夠確定程式的正确性,邏輯表達非常優雅。
- 能夠獲得其他程式員的敬畏和尊重。
缺點
- 開發人員數量較少(相應的競争壓力也很小)。
- 對運作時的安全性和程式的正确性重視超過了開發人員的生産力。
何時選用Haskell?
- 你厭倦了常見的程式設計語言,想嘗試“瘋狂的”程式設計模式。
- 你對函數式程式設計充滿熱情。
Ballerina
我們曾在介紹Java的時候提到過Ballerina,這是一種運作在JVM 上的語言,但由于在抽象級别上的創新,我們來單獨介紹一下這門語言。
Ballerina 是一種開源的 C 衍生語言,于 2015 年開發,該語言的首要目标是現代網絡抽象。gRPC 伺服器、JSON 和 XML 之類的技術都是該語言中的首要抽象,這就像Docker 和 Kubernetes的關系一樣。如果你曾在Java中遇到過JSON序列化的難題,并想念JavaScript對JSON的原生支援,就會明白正确的抽象級别可以在語言中産生多大的影響。
Ballerina還可以根據代碼生成序列圖,這為現代微服務項目帶來了一個重大優勢:永不過時的文檔。
Ballerina具有 Java 的互操作性,是以你可以利用現有的Java 庫生态系統。但是,Ballerina 幾乎不需要微服務架構,因為該語言内置了必要的原語。Ballerina的抽象級别與微服務完美比對,這就是我單獨讨論該語言的理由。
Ballerina的示例代碼:
import ballerina/http; import ballerinax/googleapis.sheets; configurable string githubPAT = ?; configurable string repository = "ballerina-platform/ballerina-lang"; configurable string sheetsAccessToken = ?; configurable string spreadSheetId = ?; configurable string sheetName = "Sheet1"; type PR record { string url; string title; string state; string created_at; string updated_at; };
如下是代碼生成的序列圖:
優點
- 最新的系統文檔。
- 一門現代語言,借鑒了之前的語言的許多優秀思想,并将抽象層放到了微服務組合層面上。
缺點
- 新語言,仍在積極的開發中,處于其生命周期的早期。
- 很難聘請到有經驗的開發人員。
何時選用Ballerina?
- 你是一家 JVM 開發公司,并且有一個想要試驗的項目。
- 你是一家初創公司,想挑戰極限。
- 你需要最新的文檔。
其他程式設計語言
還有一些其他的程式設計語言也可用于微服務開發,但沒有入選,主要是因為不太受歡迎,但還是值得一提:
- Swift:蘋果于2014年推出的程式設計語言。開源且跨平台,Vapor、Perfect 等多個架構都可用于編寫微服務。Swift因其在iOS應用中的使用而廣受歡迎,但在微服務中的使用較少。
- Rust:Mozilla于2006年推出的現代程式設計語言。适合編寫微服務的架構有兩個:Rocket 和 Tide。
- Dart:谷歌于2011年推出的現代跨平台程式設計語言。Aqueduct是一個包羅萬象的微服務架構。
- Elixir:一種在 BEAM VM 上運作的現代函數式語言,于2012年推出。在尋求高性能語言的 Ruby on Rails 開發人員中很受歡迎。Phoenix 是一個流行的 Elixir 架構。