
GoFr HTTP Server 实战Docker Compose 一键启动 Redis MySQL 可观测性全栈【免费下载链接】gofrAn opinionated GoLang framework for accelerated microservice development. Built in support for databases and observability.项目地址: https://gitcode.com/GitHub_Trending/go/gofr本指南以仓库内的 examples/http-server 示例 为核心完整讲解如何使用 GoFr 框架搭建一个同时对接 Redis 与 MySQL 数据源的 HTTP 服务并通过 Docker Compose 一键拉起包含应用、Redis、MySQL、Prometheus 与 Grafana 的完整开发栈。读完本文你将掌握该示例的目录结构、四个业务端点的实现方式、两种启动路径Compose 全栈与单容器 Docker 构建以及链路追踪与指标看板的验证方法。示例概览一个最小但完整的可观测微服务examples/http-server是 GoFr 官方仓库中的一个演示项目用于展示 开箱即用 的微服务开发体验仅凭一个main.go文件即可获得 HTTP 路由、健康检查、Redis/MySQL 数据源客户端、链路追踪Tracing、Prometheus 指标与优雅关闭等能力。示例的服务名为sample-api见 configs/.env默认监听9000端口指标端口为2121。其目录结构如下examples/http-server/ ├── configs/ # 应用配置.env 文件编译进镜像 ├── docker/ │ ├── docker-compose.yaml # 一键启动全栈app redis mysql grafana prometheus │ ├── prometheus/prometheus.yml # Prometheus 抓取配置 │ └── provisioning/ # Grafana 自动配置数据源 仪表盘 ├── static/openapi.json # Swagger/OpenAPI 接口文档 ├── Dockerfile # 多阶段构建镜像 ├── main.go # 应用入口与全部 Handler └── main_test.go # 集成测试 Handler 单元测试示例注册了四个业务路由见 main.go路由Handler演示能力GET /helloHelloHandler最基础的请求-响应支持name查询参数GET /errorErrorHandler错误处理与统一错误响应格式GET /redisRedisHandler通过c.Redis读取 Redis 数据GET /traceTraceHandler自定义 Span、并发子任务、跨服务调用GET /mysqlMysqlHandler通过c.SQL执行 MySQL 查询说明除上述业务路由外GoFr 框架会自动注册健康检查端点/.well-known/health与favicon.ico这一点在 main_test.go 中有明确验证。源码剖析五个 Handler 展示了哪些能力入口代码在 examples/http-server/main.go应用初始化非常简单func main() { // 创建新的 GoFr 应用 a : gofr.New() // 注册 HTTP 服务默认自带健康检查端点 a.AddHTTPService(anotherService, http://localhost:9000) // 注册全部路由 a.GET(/hello, HelloHandler) a.GET(/error, ErrorHandler) a.GET(/redis, RedisHandler) a.GET(/trace, TraceHandler) a.GET(/mysql, MysqlHandler) // 启动应用 a.Run() }值得注意的关键点Handler 签名统一所有 Handler 都采用func(c *gofr.Context) (any, error)签名返回值直接作为响应体序列化错误则交由框架统一处理为错误响应无需手写http.ResponseWriter样板代码。HelloHandler演示参数读取通过c.Param(name)读取查询参数缺省时回退为Worldfunc HelloHandler(c *gofr.Context) (any, error) { name : c.Param(name) if name { c.Log(Name came empty) name World } return fmt.Sprintf(Hello %s!, name), nil }RedisHandler演示数据源封装直接使用c.RedisGoFr 容器注入的 Redis 客户端并对 键不存在 与真实错误做了区分——键不存在返回空串而非错误真实错误则包装为datasource.ErrorDBfunc RedisHandler(c *gofr.Context) (any, error) { val, err : c.Redis.Get(c, test).Result() if err ! nil err ! redis.Nil { return nil, datasource.ErrorDB{Err: err, Message: error from redis db} } return val, nil }MysqlHandler演示 SQL 查询通过c.SQL.QueryRowContext执行原生 SQL示例为select 22结果Scan到 Go 变量func MysqlHandler(c *gofr.Context) (any, error) { var value int err : c.SQL.QueryRowContext(c, select 22).Scan(value) if err ! nil { return nil, datasource.ErrorDB{Err: err, Message: error from sql db} } return value, nil }TraceHandler演示链路追踪是示例中最具深度的 Handler展示了三件事用c.Trace(traceHandler).End()手动创建并结束自定义 Span并发执行 5 次 Redis Pingsync.WaitGroup调用另一个注册的 HTTP 服务anotherService并解析 JSON 响应。这是 GoFr 将分布式追踪基于 OpenTelemetry与 HTTP 服务调用无缝集成的直观体现func TraceHandler(c *gofr.Context) (any, error) { defer c.Trace(traceHandler).End() span2 : c.Trace(some-sample-work) -time.After(time.Millisecond * 1) // 模拟 1ms 工作负载 defer span2.End() // 并发 Ping Redis 5 次 count : 5 wg : sync.WaitGroup{} wg.Add(count) for i : 0; i count; i { go func() { c.Redis.Ping(c) wg.Done() }() } wg.Wait() // 调用另一个服务 resp, err : c.GetHTTPService(anotherService).Get(c, redis, nil) if err ! nil { return nil, err } defer resp.Body.Close() // ... 解析 JSON 并返回 data 字段 }环境配置.env中的关键参数应用配置位于 configs/.envGoFr 会在启动时读取也可通过环境变量覆盖APP_NAMEsample-api HTTP_PORT9000 REDIS_HOSTlocalhost REDIS_PORT2002 DB_HOSTlocalhost DB_USERroot DB_PASSWORDpassword DB_NAMEtest DB_PORT2001 DB_DIALECTmysql TRACE_EXPORTERgofr参数说明配置项默认值/示例作用APP_NAMEsample-api服务名用于日志、指标与追踪标识HTTP_PORT9000HTTP 服务监听端口REDIS_HOST/REDIS_PORTlocalhost/2002Redis 数据源地址Compose 中为redisdb/2002DB_HOST/DB_PORTlocalhost/2001MySQL 数据源地址Compose 中为mysqldb/2001DB_USER/DB_PASSWORD/DB_NAMEroot/password/testMySQL 连接凭据与库名DB_DIALECTmysql数据库方言GoFr 据此选择驱动TRACE_EXPORTERgofr追踪导出器gofr表示由 GoFr 托管的追踪服务tracer.gofr.dev接收其中端口映射值得注意Compose 将容器内 Redis 的6379映射到宿主机2002、MySQL 的3306映射到2001与.env中本地直连配置保持一致便于不启动 Compose 时直接连本机数据源调试。方式一推荐Docker Compose 一键启动全栈示例在 docker/docker-compose.yaml 中编排了 5 个服务gofr-http-server应用、redisdb、mysqldb、grafana、prometheus。在仓库根目录/gofr执行docker compose -f examples/http-server/docker/docker-compose.yml up -d参数说明-f examples/http-server/docker/docker-compose.yml指定 compose 文件路径注意实际文件名在仓库中为docker-compose.yaml与 README 写法等价以你本机文件为准up -d构建如需要并以分离模式detached启动全部服务。启动后各服务端口分配如下服务镜像宿主机端口说明gofr-http-server本地构建9000HTTP、2121指标应用与 Prometheus 指标端点redisdbredis:7.0.52002Redis 数据源mysqldbmysql:8.0.302001MySQL 数据源root 密码password库testgrafanagrafana/grafana:latest3000指标可视化看板prometheusprom/prometheus:latest9090指标采集与存储Compose 文件中的几个关键设计构建上下文为仓库根目录build.context: ../../../这样go.mod、go.sum和源码都能被打包进镜像应用环境变量指向容器内主机名REDIS_HOST: redisdb、DB_HOST: mysqldb因为容器间通过 Docker 网络gofr-network通信依赖顺序depends_on保证 Redis、MySQL、Grafana、Prometheus 先于应用启动Grafana 自动配置通过 provisioning/datasources/datasource.yaml 预置 Prometheus 数据源http://prometheus:9090通过 provisioning/dashboards/dashboards.yaml 自动加载 GoFr 仪表盘登录 Grafana 即可直接看到看板无需手工配置。方式二手动构建并运行单个应用容器如果只想单独运行应用容器不启动数据库和监控栈可以走 Docker build/run 两条命令。构建镜像在仓库根目录/gofr执行docker build -f examples/http-server/Dockerfile -t http-server:latest .参数说明-f examples/http-server/Dockerfile指定 Dockerfile 路径-t http-server:latest为镜像打标签.构建上下文为项目根目录Dockerfile 需要从中拷贝go.mod与go.sum。Dockerfile 采用两阶段构建先用golang:1.27-alpine构建阶段go mod download缓存依赖并CGO_ENABLED0 go build编译出静态二进制再用alpine:3.24运行阶段仅拷贝二进制与configs目录显著缩小镜像体积。运行容器docker run -p 9000:9000 --name http-server http-server:latest参数说明-p 9000:9000将容器 9000 端口映射到宿主机 9000--name http-server可选为容器命名。两种方式的选择建议来自 README 的明确指引使用 Compose需要完整技术栈应用 Redis MySQL Grafana Prometheus时使用 Docker build/run只想单独运行应用容器时。验证示例四个端点逐一测试启动后按 README 指引验证浏览器访问http://localhost:9000/hello将返回Hello World!带查询参数访问http://localhost:9000/hello?namegofr则返回Hello gofr!。查看 GoFr 追踪打开https://tracer.gofr.dev粘贴请求头中的traceid即可看到该请求的完整调用链Span 瀑布视图。访问 Grafana 看板打开http://localhost:3000使用默认管理员凭据登录用户名admin密码password登录后即进入预置的 GoFr 仪表盘可查看请求速率、延迟、错误率与数据源指标。此外还可以验证http://localhost:9000/redis读取 Redis 中test键的值未设置时返回空http://localhost:9000/mysql执行select 22返回4http://localhost:9000/trace触发一次带自定义 Span、并发子任务和跨服务调用的完整追踪链路http://localhost:9000/.well-known/health框架内置的健康检查端点返回 200。Prometheus 的抓取配置见 docker/prometheus/prometheus.yml每 15 秒全局抓取一次其中 Prometheus 任务每 5 秒抓取一次应用指标目标地址为host.docker.internal:2121对应应用暴露的指标端口。示例的 OpenAPI 接口文档位于 static/openapi.json其中定义了/hello、/error、/redis、/mysql、/trace各端点的请求参数与响应结构可作为接口契约参考。测试资产集成测试与 Handler 单测仓库为该示例提供了完整的测试覆盖main_test.go既能验证上述行为也是学习 GoFr 测试写法的好素材TestIntegration_SimpleAPIServer真实启动main()验证/hello、/hello?namegofr、/redis、/mysql的响应数据与 200 状态码其中/mysql期望返回4TestIntegration_SimpleAPIServer_Errors验证/error返回 500 及错误消息some error occurred未注册路由/与/route返回 404 与route not registeredTestIntegration_SimpleAPIServer_Health验证框架自动注册的/.well-known/health与/favicon.ico均返回 200TestRedisHandler/TestMysqlHandler/TestTraceHandler使用container.NewMockContainer与redismock、gomock等模拟数据源与 HTTP 服务展示不依赖真实数据库的单元测试写法TestHelloHandler/TestErrorHandler通过createTestContext将http.Request包装为 GoFr 请求后直接调用 Handler。运行测试只需在examples/http-server目录执行go test ./...小结examples/http-server用最小的代码量演示了 GoFr 的核心主张框架负责 HTTP 路由、数据源注入、分布式追踪、Prometheus 指标与优雅关闭等基础设施开发者专注编写业务 Handler。通过本文的两种启动方式Compose 全栈一键起、单容器 Docker 构建与四类验证路径业务端点、健康检查、traceid 追踪、Grafana 看板你可以快速将这套模式迁移到自己的服务中。若想进一步深入可继续阅读仓库中的 快速开始指南、可观测性配置 以及 连接 Redis、连接 MySQL 等配套文档。【免费下载链接】gofrAn opinionated GoLang framework for accelerated microservice development. Built in support for databases and observability.项目地址: https://gitcode.com/GitHub_Trending/go/gofr创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考