十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

GoFr 连接 Google Cloud SQL:用 DB_IAM_AUTH 一个开关实现 IAM 数据库认证

GoFr 连接 Google Cloud SQL:用 DB_IAM_AUTH 一个开关实现 IAM 数据库认证 GoFr 连接 Google Cloud SQL用 DB_IAM_AUTH 一个开关实现 IAM 数据库认证【免费下载链接】gofrAn opinionated GoLang framework for accelerated microservice development. Built in support for databases and observability.项目地址: https://gitcode.com/GitHub_Trending/go/gofr导读本文讲解 GoFr 框架的cloudsql数据源模块pkg/gofr/datasource/cloudsql它让 GoFr 应用以一行代码同时支持两种环境在 Google Cloud 上使用IAM 数据库认证无静态密码、无 Cloud SQL Auth Proxy sidecar在本地使用传统用户名/密码连接。读完本文你将掌握该模块的安装、配置、工作原理以及如何把同一份代码无改动地部署到本地与 GCP。模块定位面向 Google Cloud SQL 的托管 SQL 数据源cloudsql是 GoFr 的一个 SQL 数据源实现目标数据库是Google Cloud SQL的 Postgres 与 MySQL 两种引擎。它并非重新实现一套 SQL 行为而是构建在 GoFr 标准 SQL 数据源之上通过 Cloud SQL Go Connector 额外增加IAM 数据库认证能力。模块对外呈现为一个独立发布的 Go module模块路径gofr.dev/pkg/gofr/datasource/cloudsql见 go.mod。这样做的直接收益是GCP SDK 依赖只被真正使用 Cloud SQL 的应用拉入GoFr 核心保持精简。通过单一开关DB_IAM_AUTH无需任何代码改动即可在两种模式间切换云端 IAM 数据库认证无静态密码、无 Cloud SQL Auth Proxy sidecar凭据通过 Application Default CredentialsADC解析天然支持 Workload Identity Federation本地用户名/密码当 IAM 认证关闭时cloudsql退化为 GoFr 的标准 SQL 连接行为与原生gofr.New()完全一致。安装在应用目录下执行go get gofr.dev/pkg/gofr/datasource/cloudsql从 go.mod 可以看到模块直接依赖的核心库包括cloud.google.com/go/cloudsqlconnCloud SQL Go Connector负责安全隧道与 IAM 令牌的自动签发与后台刷新github.com/jackc/pgx/v5Postgres 驱动含stdlib子包用于构造driver.Connectorgithub.com/go-sql-driver/mysqlMySQL 驱动。这些依赖只存在于该叶子模块中不会进入 GoFr 核心或其他不使用 Cloud SQL 的应用。使用方法一行代码接入无论本地还是 GCP接入代码完全相同只有配置不同package main import ( gofr.dev/pkg/gofr gofr.dev/pkg/gofr/datasource/cloudsql ) func main() { app : gofr.New() app.AddSQLDB(cloudsql.New(app.Config)) app.Run() }接入之后app.SQL()/ctx.SQL与任何其他 GoFr SQL 连接表现一致查询日志、指标、健康检查全部照常工作。可运行的最小示例见 examples/using-cloudsql。其 main.go 展示了完整的 CRUD 用法app.GET(/customers, listCustomers) app.POST(/customers, addCustomer)处理函数内直接通过ctx.SQL执行查询rows, err : ctx.SQL.QueryContext(ctx, SELECT id, name FROM customers ORDER BY id)写入使用 Postgres 的$1占位符该示例面向 Postgres 编写如需切换到 MySQL将占位符改为?并将SERIAL主键改为AUTO_INCREMENT_, err : ctx.SQL.ExecContext(ctx, INSERT INTO customers (name) VALUES ($1), c.Name)配置项详解全部配置均来自环境变量完整示例可参考 examples/using-cloudsql/configs/.env。环境变量说明DB_HOSTIAM 模式下为实例连接名project:region:instance标准模式下为普通主机名DB_DIALECTpostgres或mysql源码还接受postgresql、pgx作为 postgres 别名见下文DB_NAME数据库名DB_USERIAM 主体服务账号邮箱去掉.gserviceaccount.com后缀或普通数据库用户DB_IAM_AUTHtrue启用 IAM 认证否则使用标准用户名/密码DB_PASSWORD仅当DB_IAM_AUTH不为true时使用DB_CLOUDSQL_IP_TYPEPUBLIC默认、PRIVATE或PSCDB_MAX_IDLE_CONNECTION/DB_MAX_OPEN_CONNECTION连接池大小设为 0 时使用 GoFr 默认值配置解析的源码级细节这些配置的解析逻辑位于 settings.go有几个值得注意的细节dialect 规范化与别名normalizeDialect会将postgres、postgresql、pgx大小写与首尾空格不敏感统一归一为postgres将mysql归一为mysql其他值返回空串并触发“不支持的方言”错误——对应测试见 cloudsql_test.go 的TestNormalizeDialectsqlite、空串均被拒绝。IP 类型默认值normalizeIPType对PRIVATE、PSC之外的任何值含空值与未知值一律回退为PUBLIC见TestNormalizeIPType。布尔开关的宽容解析iamRequested使用strconv.ParseBool并先TrimSpace因此true、TRUE、1、t均为启用false、0、空串、非法值如yes均为关闭——见TestIAMRequested。连接池大小不在此处处理注释明确说明DB_MAX_*_CONNECTION由 GoFr 在包装连接时统一应用因此 IAM 与非 IAM 两条路径的池配置行为完全一致。工作原理从 Connector 到标准 SQL 数据源New返回一个*Connector见 cloudsql.go由 GoFr 通过AddSQLDB驱动核心方法是func (c *Connector) Connect() (driver.Connector, func() error, error)调用链如下非 IAM 模式Connect返回nil, nil, nilnil connector nil cleanup nil error。AddSQLDB收到 nil connector 后保留 GoFr 标准的、由环境变量配置的 SQL 数据源用户名/密码不动。IAM 模式Connect先解析配置并做校验。校验失败如方言不受支持、缺少实例连接名时返回错误而不尝试拨号——对应错误errUnsupportedDialect与errMissingInstance测试见TestConnector_Connect_IAMValidation。校验通过后构造一个database/sql的driver.Connector其拨号路径经过 Cloud SQL connectorPostgrespostgresConnector创建cloudsqlconn.NewDialer用pgx.ParseConfig解析连接串并把cfg.DialFunc指向dialer.Dial(ctx, instanceConnectionName)最后经stdlib.GetConnector得到 connectorcleanup 为dialer.Close。MySQLmysqlConnector创建 dialer 后通过netSeq计数器生成全局唯一的网络名注册 dial-context因为 go-sql-driver 没有 unregister 机制注册名必须每连接器唯一再以mysql.NewConnector构造 connector。包装与收尾GoFr 核心完成包装——AddSQLDB通过 GoFr 标准 SQL 数据源的NewSQLFromConnectorsql.go打开 connector因此日志、指标、健康检查、事务行为完全一致SQL 行为零重复。cleanup 在Close时执行负责拆除 dialer 的后台凭据刷新。AddSQLDB的完整实现见 external_db.go它调用Connect在出错时关闭并置空现有 SQL 连接避免 IAM 路径下把实例连接名当作字面量 host 无限重试在收到 nil connector 时保留环境变量配置的连接在拿到真实 connector 时替换为新连接并确保旧连接池与后台 goroutine 不泄漏。重要的模块边界从源码看本模块只 import 了database/sql/driver和 GCP SDK从不 importgofr.dev。它在本地定义了一个最小化的只读配置接口type Config interface { Get(key string) string GetOrDefault(key, defaultValue string) string }GoFr 的app.Config天然满足该接口因此app.AddSQLDB(cloudsql.New(app.Config))这一行可以直接编译。测试同样不携带任何gofr.dev依赖——cloudsql_test.go 用自定义的fakeConfig完成全部单测。这正是云 SDK 不进入其他应用依赖的架构保证。实战本地与 GCP 的配置切换参考 examples/using-cloudsql/configs/.env云端 IAM 模式的配置为# Cloud SQL instance connection name: project:region:instance. DB_HOSTmy-project:us-central1:my-instance DB_DIALECTpostgres DB_NAMEapp # IAM database user. For a service account, use the email with the # .gserviceaccount.com suffix removed (e.g. app-samy-project.iam). DB_USERapp-samy-project.iam # IAM auth on the cloud: no password needed, credentials come from Application # Default Credentials (supports Workload Identity Federation). DB_IAM_AUTHtrue # PUBLIC | PRIVATE | PSC DB_CLOUDSQL_IP_TYPEPUBLIC本地开发则切换为内置用户名/密码认证DB_IAM_AUTHfalse DB_HOSTlocalhost # plain pq/mysql cant resolve project:region:instance DB_PORT5432 DB_USERpostgres DB_PASSWORDyour-passwordIAM 认证在 GCP 上的前置条件按 examples/using-cloudsql/README.md 所述使用 IAM 认证需完成在项目中启用 Cloud SQL Admin API在实例上为服务账号创建 IAM 数据库用户授予服务账号Cloud SQL Instance User与Cloud SQL Client角色让进程可获取 Application Default Credentials——GKE / Cloud Run 上由 Workload Identity 自动提供本地可用gcloud auth application-default login。建表与运行示例建表语句PostgresCREATE TABLE customers ( id SERIAL PRIMARY KEY, name TEXT NOT NULL );运行与验证go run main.gocurl -X POST http://localhost:8000/customers -d {name:alice} curl http://localhost:8000/customers扩展将同样的契约复制到 AWS 与 Azure该模块是 GoFr managed SQL 提供方的参考实现。开发者指南见 doc.goAWS RDS/Aurora 与 Azure Database 可以作为各自独立的叶子模块加入无需改动 GoFr 核心。其契约极小——提供一个单方法类型Connect() (driver.Connector, func() error, error)返回值分别是可认证到托管数据库的driver.ConnectorClose时执行的清理函数用于拆除database/sql不拥有的后台令牌/凭据刷新器错误。返回 nil connector 且 nil error 表示“未请求托管认证”此时AddSQLDB保留 GoFr 标准的用户名/密码连接——这正是同一行app.AddSQLDB(provider.New(app.Config))能在本地与云端切换、开发者无需分支的原因。GoFr 核心负责其余一切AddSQLDB将 connector 交给NewSQLFromConnector以带 tracing 的方式打开并包装进标准 SQL 数据源日志、指标、健康检查、事务以及后台重试/指标 goroutine 全部复用绝不重复实现。各提供方的区别仅在构造 connector 的部分依据 doc.go 的规划GCP Cloud SQL本模块cloudsqlconn.NewDialer建立安全隧道并在后台透明签发、刷新 IAM 令牌connector 把驱动的拨号路由到 dialer——pgx 通过stdlib.GetConnector配自定义DialFuncMySQL 通过注册 dial-context 配mysql.NewConnectorcleanup 即 dialer 的CloseAWS RDS / Aurora IAM未来模块用aws-sdk-go-v2/feature/rds/auth.BuildAuthToken生成约 15 分钟有效的短时令牌作为 TLS 连接密码因令牌会过期需实现一个按物理连接在Connect时铸造新令牌的driver.ConnectorAzure Database for PostgreSQL/MySQL Microsoft Entra ID未来模块用azure-sdk-for-go/sdk/azidentity获取访问令牌scope 为https://ossrdbms-aad.database.windows.net/.default作为 TLS 密码令牌约 1 小时有效采用与 AWS 相同的刷新式driver.Connector方案确保新建与重连的池连接始终拿到有效令牌。关键在于NewSQLFromConnector接受任意driver.Connector因此认证/刷新逻辑可以完全封装在提供方模块内部。新增一个提供方只是新增一个叶子模块——既不需要改动 GoFr 核心也不需要改动本模块。小结cloudsql数据源展示了 GoFr 在“托管 SQL”集成上的设计范式提供方模块只负责构造driver.Connector其余全部交给核心复用DB_IAM_AUTH一个开关完成云端 IAM 认证与本地密码认证的无缝切换。无论是直接使用安装 → 一行接入 → 配置环境变量还是作为参考实现扩展 AWS/Azure本文覆盖的源码路径与测试用例都可以作为继续深入仓库的起点。【免费下载链接】gofrAn opinionated GoLang framework for accelerated microservice development. Built in support for databases and observability.项目地址: https://gitcode.com/GitHub_Trending/go/gofr创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表