文章目錄
Google Cloud Functions 發送訊息到 Google Cloud Pub/Sub
因為公司部份產品建置在 SaaS 基礎上,但這些 SaaS 都有自己維護的時間跟計劃,所以為了避免 SaaS 維護造成產品服務異常,所以想要將 SaaS 的相關通知先打進 Google Cloud Pub/Sub,後續再介接進團隊的 IM 系統
在這個目標下,就想透過 Google Cloud Functions 來處理這個需求,不需額外建立 server 也不用 container,今天就先紀錄一下如何透過 Cloud Functions 將訊息送到 Cloud Pub/Sub
基本環境說明
- macOS Ventura 13.2
- .NET SDK 7.0.203
JetBrains Rider 2023.1
NuGet packages
- Google.Cloud.Functions.Hosting 1.1.0
- Google.Cloud.PubSub.V1 3.5.0
使用方式
安裝 Google Cloud Functions project template
dotnet new install Google.Cloud.Functions.Templates::2.0.0
透過 Google Cloud Functions project template 建立專案
安裝 NuGet packages:Google.Cloud.PubSub.V1 3.5.0
新增
PublishMessages.cs
(用來發送訊息至 Google Cloud Pub/Sub)using Google.Cloud.PubSub.V1; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace PublishPubSub; public class PublishMessages { public async Task<int> PublishMessagesAsync(string projectId, string topicId,IEnumerable<string> messageTexts) { TopicName topicName = TopicName.FromProjectTopic(projectId, topicId); PublisherClient publisher = await PublisherClient.CreateAsync(topicName); int publishedMessageCount = 0; var publishTasks = messageTexts.Select(async text => { try { string message = await publisher.PublishAsync(text); Console.WriteLine($"Published message {message}"); Interlocked.Increment(ref publishedMessageCount); } catch (Exception exception) { Console.WriteLine($"An error ocurred when publishing message {text}: {exception.Message}"); } }); await Task.WhenAll(publishTasks); return publishedMessageCount; } }
修改
Function.cs
using System.IO; using System.Text.Json; using Google.Cloud.Functions.Framework; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using System.Threading.Tasks; namespace PublishPubSub; public class Function : IHttpFunction { private readonly ILogger _logger; private const string projectId = ""; private const string topicId = ""; public Function(ILogger<Function> logger) => _logger = logger; public async Task HandleAsync(HttpContext context) { HttpRequest request = context.Request; // Check URL parameters for "message" field string message = request.Query["message"]; // If there's a body, parse it as JSON and check for "message" field. using TextReader reader = new StreamReader(request.Body); string text = await reader.ReadToEndAsync(); try { if (text.Length > 0) { JsonElement json = JsonSerializer.Deserialize<JsonElement>(text); if (json.TryGetProperty("message", out JsonElement messageElement) && messageElement.ValueKind == JsonValueKind.String) { message = messageElement.GetString(); } } if (!string.IsNullOrWhiteSpace(message)) { var pubsubClient = new PublishMessages(); await pubsubClient.PublishMessagesAsync(projectId, topicId, new[] { message }); } } catch (JsonException parseException) { _logger.LogError(parseException, "Error parsing JSON request"); } await context.Response.WriteAsync(message ?? "Empty message"); } }
GCP 設定
建立 Google Cloud Pub/Sub topic
預設會建立 subscription,最終的 message 是在 subscription 可以 pull 到的
建立 Google Cloud Function
Configuration
除了 name 與 Region 可依需求調整,其他部份皆可使用預設值
Code
將前面幾個步驟的結果貼上,或是可以打包成 zip 上傳
建立完成後,有個
TESTING
tab 可以直接執行,並看到相關的 response 與 log
實際效果
心得
GCP 的介面可以直接編輯 Cloud Function 的 code,只是 intellisense 跟 lcoal 開發有不小的落差,加上沒有 NuGet 的 GUI,我個人手打沒辦法打出正確的內容,所以才在 local 先開發完再 sync 上去
完成程式碼:yowko/cloud-function-cloud-pubsub
如果需要為 Google Cloud Functions 增加基本保護可以參考 使用 Google Api Gateway 為 Google Cloud Functions 加上 API Key 保護
參考資訊
文章作者 Yowko Tsai
上次更新 2023-04-26
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。