Go 部落格

使用 Go Cloud 進行行動式雲程式設計

Eno Compton 和 Cassandra Salisbury
2018 年 7 月 24 日

引言

今天,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 釋出了對物件儲存、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.Bucket 將檔案從本地磁碟複製到雲提供商。讓我們從使用附帶的s3blob 包開啟一個 S3 儲存桶開始。

// 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,它就可以建立一個 *blob.Writer,該介面實現了 io.Writer。然後,程式可以使用 *blob.Writer 將資料寫入儲存桶,並檢查 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)
}

請注意,使用儲存桶的邏輯並不引用 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)
}

雖然訪問不同雲提供商的儲存桶需要不同的步驟,但應用程式使用的最終型別是相同的:*blob.Bucket。這可以將應用程式程式碼與特定於雲的程式碼隔離。為了增加與現有 Go 庫的互操作性,Go Cloud 利用了諸如 io.Writerio.Reader*sql.DB 等成熟的介面。

訪問雲服務所需的設定程式碼通常遵循一個模式:更高層級的抽象是由更低層級的抽象構建的。雖然您可以手動編寫這些程式碼,但 Go Cloud 使用 **Wire** 自動完成此操作,Wire 是一個為您生成特定於雲的設定程式碼的工具。Wire 文件解釋瞭如何安裝和使用該工具,而Guestbook 示例展示了 Wire 的實際應用。

如何參與和了解更多資訊?

要開始,我們建議您遵循教程,然後嘗試自己構建一個應用程式。如果您已經在為 AWS 或 GCP 開發,可以嘗試將現有應用程式的部分內容遷移到使用 Go Cloud。如果您使用的是不同的雲提供商或本地服務,可以透過實現驅動程式介面(如driver.Bucket)來擴充套件 Go Cloud 以支援它。

我們非常感謝您關於使用體驗的任何反饋。Go Cloud 的開發在 GitHub 上進行。我們期待您的貢獻,包括 pull request。提交 issue 來告訴我們哪些方面可以改進,或者專案應該支援哪些未來的 API。有關專案的更新和討論,請加入專案郵件列表

該專案要求貢獻者簽署與 Go 專案相同的貢獻者許可協議。請閱讀貢獻指南瞭解更多詳情。請注意,Go Cloud 遵循 Go 的行為準則

感謝您花時間瞭解 Go Cloud。我們很期待與您一起努力,使 Go 成為構建行動式雲應用程式開發者的首選語言。

下一篇文章:Go 1.11 已釋出
上一篇文章:走向 Go:Go 垃圾回收器的歷程
部落格索引