Go 官方部落格
使用 Go Cloud 進行可移植雲程式設計
簡介
今天,Google 的 Go 團隊釋出了一個新的開源專案 Go Cloud,這是一個用於在開放雲上開發的庫和工具。透過這個專案,我們的目標是讓 Go 成為構建可移植雲應用程式的開發人員的首選語言。
本文解釋了我們為何啟動這個專案、Go Cloud 的工作原理細節以及如何參與其中。
為何選擇可移植雲程式設計?為何是現在?
我們估計全球現有超過一百萬 Go 開發者。Go 為許多最關鍵的雲基礎設施專案提供支援,包括 Kubernetes、Istio 和 Docker。Lyft、Capital One、Netflix 以及更多公司都在生產環境中依賴 Go。多年來,我們發現開發者喜歡 Go 進行雲開發,因為它高效、高生產力、內建併發和低延遲。
作為我們支援 Go 快速增長工作的一部分,我們一直在採訪使用 Go 的團隊,以瞭解他們如何使用該語言以及 Go 生態系統如何進一步改進。許多組織的一個共同主題是跨雲提供商的可移植性需求。這些團隊希望在多雲和混合雲環境中部署健壯的應用程式,並在不顯著更改其程式碼的情況下在雲提供商之間遷移其工作負載。
為了實現這一點,一些團隊試圖將他們的應用程式與特定於提供商的 API 解耦,以生成更簡單、更可移植的程式碼。然而,儘快交付功能的短期壓力意味著團隊常常犧牲為可移植性所做的長期努力。因此,大多數執行在雲中的 Go 應用程式與其最初的雲提供商緊密耦合。
作為替代方案,團隊可以使用 Go Cloud(一組開放的通用雲 API)來編寫更簡單、更可移植的雲應用程式。Go Cloud 還為基於這些通用 API 構建可移植雲庫生態系統奠定了基礎。Go Cloud 使團隊能夠在實現其功能開發目標的同時,保留多雲和混合雲架構的長期靈活性。Go Cloud 應用程式也可以遷移到最符合其需求的雲提供商。
什麼是 Go Cloud?
我們識別了雲應用程式使用的常見服務,並建立了可在不同雲提供商上工作的通用 API。今天,Go Cloud 釋出時包含 Blob 儲存、MySQL 資料庫訪問、執行時配置以及配置了請求日誌、跟蹤和健康檢查的 HTTP 伺服器。Go Cloud 支援 Google Cloud Platform (GCP) 和 Amazon Web Services (AWS)。我們計劃很快與雲行業合作伙伴和 Go 社群合作,以新增對更多雲提供商的支援。
Go Cloud 旨在為跨雲提供商最常用的服務開發廠商中立的通用 API,以便在另一個雲上部署 Go 應用程式變得簡單容易。Go Cloud 還為其他開源專案編寫跨提供商工作的雲庫奠定了基礎。來自各種型別、各個級別開發者的社群反饋將指導 Go Cloud 未來 API 的優先順序。
它是如何工作的?
Go Cloud 的核心是一系列用於可移植雲程式設計的通用 API。讓我們來看一個使用 Blob 儲存的例子。您可以使用通用型別 *blob.Bucket
將檔案從本地磁碟複製到雲提供商。讓我們首先使用包含的 s3blob 包開啟一個 S3 bucket
// setupBucket opens an AWS bucket.
func setupBucket(ctx context.Context) (*blob.Bucket, error) {
// Obtain AWS credentials.
sess, err := session.NewSession(&aws.Config{
Region: aws.String("us-east-2"),
})
if err != nil {
return nil, err
}
// Open a handle to s3://go-cloud-bucket.
return s3blob.OpenBucket(ctx, sess, "go-cloud-bucket")
}
一旦程式獲得了 *blob.Bucket
,它就可以建立一個實現了 io.Writer
的 *blob.Writer
。然後,程式可以使用 *blob.Writer
將資料寫入 bucket,並檢查 Close
是否報告錯誤。
ctx := context.Background()
b, err := setupBucket(ctx)
if err != nil {
log.Fatalf("Failed to open bucket: %v", err)
}
data, err := ioutil.ReadFile("gopher.png")
if err != nil {
log.Fatalf("Failed to read file: %v", err)
}
w, err := b.NewWriter(ctx, "gopher.png", nil)
if err != nil {
log.Fatalf("Failed to obtain writer: %v", err)
}
_, err = w.Write(data)
if err != nil {
log.Fatalf("Failed to write to bucket: %v", err)
}
if err := w.Close(); err != nil {
log.Fatalf("Failed to close: %v", err)
}
請注意,使用 bucket 的邏輯不涉及 AWS S3。Go Cloud 使得更換雲端儲存只需改變用於開啟 *blob.Bucket
的函式即可。應用程式可以使用 gcsblob.OpenBucket
構建一個 *blob.Bucket
來使用 Google Cloud Storage,而無需更改複製檔案的程式碼
// setupBucket opens a GCS bucket.
func setupBucket(ctx context.Context) (*blob.Bucket, error) {
// Open GCS bucket.
creds, err := gcp.DefaultCredentials(ctx)
if err != nil {
return nil, err
}
c, err := gcp.NewHTTPClient(gcp.DefaultTransport(), gcp.CredentialsTokenSource(creds))
if err != nil {
return nil, err
}
// Open a handle to gs://go-cloud-bucket.
return gcsblob.OpenBucket(ctx, "go-cloud-bucket", c)
}
雖然訪問不同雲提供商上的 bucket 需要不同的步驟,但應用程式使用的結果型別是相同的:*blob.Bucket
。這將應用程式程式碼與特定於雲的程式碼隔離開來。為了增強與現有 Go 庫的互操作性,Go Cloud 利用了諸如 io.Writer
、io.Reader
和 *sql.DB
等既定介面。
訪問雲服務所需的設定程式碼往往遵循一種模式:更高階的抽象是從更基本的抽象構建而來。雖然您可以手動編寫這些程式碼,但 Go Cloud 使用 Wire 工具自動完成此操作,該工具會為您生成特定於雲的設定程式碼。Wire 文件解釋瞭如何安裝和使用該工具,而訪客留言簿示例展示了 Wire 的實際應用。
我如何參與並瞭解更多?
要開始使用,我們建議按照教程進行操作,然後嘗試自己構建一個應用程式。如果您已經在使用 AWS 或 GCP,可以嘗試將現有應用程式的一部分遷移到使用 Go Cloud。如果您使用的是不同的雲提供商或本地服務,可以透過實現驅動程式介面(如 driver.Bucket
)來擴充套件 Go Cloud 以支援它。
我們感謝您提供的任何和所有關於您使用經驗的反饋。Go Cloud 的開發工作在 GitHub 上進行。我們期待您的貢獻,包括拉取請求。提交問題,告訴我們哪些方面可以改進,或者專案未來應該支援哪些 API。如需獲取專案更新和參與討論,請加入專案郵件列表。
該專案要求貢獻者簽署與 Go 專案相同的貢獻者許可協議 (Contributor License Agreement)。閱讀貢獻指南瞭解更多細節。請注意,Go Cloud 受 Go 行為準則的約束。
感謝您花時間瞭解 Go Cloud。我們很高興能與您合作,使 Go 成為構建可移植雲應用程式開發人員的首選語言。
下一篇文章:Go 1.11 已釋出
上一篇文章:Getting to Go:Go 垃圾回收器的旅程
部落格索引