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 會隨附 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 儲存區開始

// 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 將資料寫入儲存區,並檢查 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 文件 說明如何安裝和使用此工具,而 Guestbook 範例 展示 Wire 的實際應用。

如何參與並深入了解?

要開始,我們建議您遵循 教學,之後嘗試自行建置應用程式。如果您已經使用 AWS 或 GCP,您可以嘗試將現有應用程式的部分移轉至使用 Go Cloud。如果您使用其他雲端提供商或內部服務,您可以透過實作驅動程式介面(例如 driver.Bucket)來延伸 Go Cloud 以支援它。

我們樂於收到您對體驗的任何意見回饋。 Go Cloud 的開發是在 GitHub 中進行。我們期待您有更多貢獻,包括發送拉取要求。 提出議題 告訴我們還有哪些地方可以更好,或專案應該另外支援哪些介面。若要接收專案的最新消息和討論,請加入 專案寄件清單

此專案要求貢獻者簽署與 Go 專案相同的貢獻者授權合約。請閱讀 貢獻指南 以取得更多詳情。請注意,Go Cloud 適用於 Go 行為準則

感謝您撥冗了解 Go Cloud。我們很興奮與您合作,讓 Go 成為開發人員建構可攜式雲端應用程式的首選語言。

下一篇文章:Go 1.11 已發佈
上一篇文章:認識 Go:Go 垃圾收集器的旅程
部落格索引