golang构建生产级可扩展Web服务的插件库ardanlabs/servicestarter kit的使用
Golang构建生产级可扩展Web服务的插件库ardanlabs/service starter kit的使用
项目简介
ardanlabs/service starter kit是一个用于构建生产级可扩展Web服务应用的起点,它利用了领域驱动、数据导向架构的优势,并能在Kubernetes中运行。该项目的目标是提供一个经过验证的起点,减少新项目投入生产所需的重复性任务。
正如John Ousterhout所说:“随着程序演进并获得更多功能,它会变得复杂,组件之间存在微妙的依赖关系。随着时间的推移,复杂性不断累积,程序员在修改系统时越来越难以将所有相关因素都记在脑海中。这减慢了开发速度并导致错误,从而进一步减慢开发速度并增加成本。”
核心特点
- 使用最少的依赖
- 实现惯用代码
- 遵循Go最佳实践
- 采用领域驱动、数据导向架构
- 支持Kubernetes部署
- 项目结构清晰,便于维护心智模型
安装与使用
克隆项目
$ cd $HOME
$ mkdir code
$ cd code
$ git clone https://github.com/ardanlabs/service.git
$ cd service
创建自定义版本
如果你想创建自己的项目版本,可以使用gonew
命令:
$ go install golang.org/x/tools/cmd/gonew@latest
$ cd $HOME
$ mkdir code
$ cd code
$ gonew github.com/ardanlabs/service github.com/mydomain/myproject
$ cd myproject
$ go mod vendor
运行项目
# 安装工具
$ make dev-gotooling
$ make dev-brew
$ make dev-docker
# 运行测试
$ make test
# 关闭测试
$ make test-down
# 运行项目
$ make dev-up
$ make dev-update-apply
$ make token
$ export TOKEN=<COPY TOKEN>
$ make users
# 运行负载测试
$ make load
# 运行监控工具
$ make grafana
$ make statsviz
# 关闭项目
$ make dev-down
示例代码
以下是一个简单的Web服务示例,展示了如何使用该starter kit的基本结构:
package main
import (
"context"
"expvar"
"net/http"
"os"
"github.com/ardanlabs/service/app/services/sales-api/handlers"
"github.com/ardanlabs/service/business/web/v1/debug"
"github.com/ardanlabs/service/foundation/web"
"go.uber.org/zap"
)
func main() {
// 初始化日志
log, err := zap.NewProduction()
if err != nil {
log.Error("初始化日志失败", zap.Error(err))
os.Exit(1)
}
defer log.Sync()
// 创建应用
app := web.NewApp(
shutdown,
log,
)
// 注册调试路由
debugMux := debug.StandardLibraryMux()
app.HandleDebug("/debug/vars", expvar.Handler())
app.HandleDebug("/debug/", debugMux)
// 注册API路由
api := app.Group("/api")
{
// 健康检查端点
api.Handle("/health", handlers.HealthCheck)
// 用户管理端点
users := api.Group("/users")
{
users.Handle("", handlers.CreateUser)
users.Handle("/:id", handlers.QueryUserByID)
}
}
// 启动服务
if err := app.Serve(":8080"); err != nil {
log.Error("服务启动失败", zap.Error(err))
os.Exit(1)
}
}
func shutdown(ctx context.Context, reason string) {
// 在这里实现优雅关闭逻辑
}
架构设计
该starter kit采用以下核心架构原则:
- 领域驱动设计:将业务逻辑集中在领域层
- 数据导向架构:优化数据处理性能
- 分层架构:
- 表现层:处理HTTP请求/响应
- 业务层:核心业务逻辑
- 数据层:数据访问和存储
- 依赖注入:通过构造函数注入依赖
- 中间件链:处理横切关注点
最佳实践
- 错误处理:使用自定义错误类型和错误包装
- 日志记录:结构化日志和上下文日志
- 配置管理:环境变量和配置验证
- 测试:单元测试、集成测试和端到端测试
- 监控:指标收集和健康检查
- 文档:API文档和代码注释
学习资源
该项目还提供相关培训课程,教授如何:
- 在Go中构建生产级软件
- 利用领域驱动、数据导向架构
- 部署和管理Kubernetes环境
- 处理和减少系统复杂性
许可证
该项目使用Apache License 2.0许可证:
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
更多关于golang构建生产级可扩展Web服务的插件库ardanlabs/servicestarter kit的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang构建生产级可扩展Web服务的插件库ardanlabs/servicestarter kit的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用ardanlabs/service构建生产级可扩展Web服务
ardanlabs/service是Go语言中一个优秀的Web服务启动工具包,它提供了一套完整的生产级Web服务框架,包含日志、配置、监控、优雅关闭等企业级功能。
核心特性
- 内置标准化的服务生命周期管理
- 集成优雅关闭(graceful shutdown)机制
- 提供统一的配置管理
- 内置健康检查、指标和跟踪支持
- 结构化日志记录
- 支持多路复用(mux)的HTTP服务器
基本使用示例
package main
import (
"context"
"net/http"
"github.com/ardanlabs/service/app/services/sales-api/handlers"
"github.com/ardanlabs/service/business/web/v1/debug"
"github.com/ardanlabs/service/foundation/logger"
"github.com/ardanlabs/service/foundation/web"
)
func main() {
// 初始化日志
log := logger.New("SALES-API")
// 创建服务
service := web.NewApp(
log,
web.WithShutdownFunc(func(ctx context.Context) {
// 自定义关闭逻辑
log.Info(ctx, "shutdown started")
}),
)
// 注册路由
service.Handle(http.MethodGet, "/ready", handlers.Ready)
service.Handle(http.MethodGet, "/live", handlers.Live)
// 注册调试路由
debugMux := debug.StandardLibraryMux()
service.Handle(http.MethodGet, "/debug/", http.StripPrefix("/debug", debugMux))
// 启动服务
if err := service.Run(context.Background()); err != nil {
log.Error(context.Background(), "shutdown", "msg", err)
return
}
}
配置管理
ardanlabs/service提供了统一的配置管理方式:
import (
"github.com/ardanlabs/conf/v3"
)
type Config struct {
Web struct {
APIHost string `conf:"default:0.0.0.0:3000"`
DebugHost string `conf:"default:0.0.0.0:4000"`
ReadTimeout time.Duration `conf:"default:5s"`
WriteTimeout time.Duration `conf:"default:10s"`
IdleTimeout time.Duration `conf:"default:120s"`
ShutdownTimeout time.Duration `conf:"default:20s"`
}
}
func main() {
cfg := Config{}
help, err := conf.Parse("SALES", &cfg)
if err != nil {
log.Fatalf("parsing config: %v", err)
}
// 使用配置启动服务
service := web.NewApp(
log,
web.WithServerOptions(
web.WithReadTimeout(cfg.Web.ReadTimeout),
web.WithWriteTimeout(cfg.Web.WriteTimeout),
web.WithIdleTimeout(cfg.Web.IdleTimeout),
),
)
}
中间件支持
// 自定义中间件
func middlewareExample(next web.HandlerFunc) web.HandlerFunc {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
// 前置处理
log.Info(ctx, "middleware: before")
// 调用下一个处理程序
err := next(ctx, w, r)
// 后置处理
log.Info(ctx, "middleware: after")
return err
}
}
// 注册带中间件的路由
service.Handle(http.MethodGet, "/example", handlers.Example, middlewareExample)
数据库集成
import (
"github.com/ardanlabs/service/business/core/user/stores/userdb"
"github.com/ardanlabs/service/business/data/dbsql/pgx"
)
func main() {
// 配置数据库
dbConfig := pgx.Config{
User: "postgres",
Password: "postgres",
Host: "localhost",
Name: "postgres",
MaxIdleConns: 2,
MaxOpenConns: 0,
DisableTLS: true,
}
// 创建数据库连接
db, err := pgx.Open(dbConfig)
if err != nil {
log.Fatalf("opening database connection: %v", err)
}
// 创建用户存储
userCore := userdb.NewStore(log, db)
// 创建API处理器
api := handlers.API{
User: userCore,
}
// 注册路由
service.Handle(http.MethodGet, "/users", api.Query)
service.Handle(http.MethodPost, "/users", api.Create)
}
监控和健康检查
import (
"github.com/ardanlabs/service/business/web/v1/mid"
"github.com/ardanlabs/service/foundation/web"
)
func main() {
// 添加监控中间件
service.Use(
mid.Logger(log),
mid.Errors(log),
mid.Metrics(),
mid.Panics(log),
)
// 健康检查路由
service.Handle(http.MethodGet, "/health", handlers.Health)
// 指标路由
service.Handle(http.MethodGet, "/metrics", handlers.Metrics)
}
生产环境最佳实践
- 日志配置:确保在生产环境中配置适当的日志级别和输出格式
- 优雅关闭:实现完整的优雅关闭逻辑,包括数据库连接关闭等
- 监控集成:集成Prometheus或其他监控工具
- 配置管理:使用环境变量或配置中心管理敏感信息
- 错误处理:实现统一的错误处理中间件
ardanlabs/service提供了一套完整的生产级Web服务解决方案,通过合理的配置和使用,可以快速构建出高可用、可扩展的Web服务。