golang快速开发服务的模块化基础框架插件bedrock的使用

Golang快速开发服务的模块化基础框架插件bedrock的使用

概述

bedrock提供了一个最小化、模块化和可组合的基础,用于快速开发更具体的Go框架。它的核心设计理念是可组合性,旨在帮助组织快速开发内部框架,适应不断变化的开发需求。

核心概念

App接口

type App interface {
	Run(context.Context) error
}

App接口是对特定应用程序类型(如HTTP服务器、gRPC服务器等)执行的简单抽象。

AppBuilder接口

type AppBuilder[T any] interface {
	Build(ctx context.Context, cfg T) (App, error)
}

AppBuilder将App初始化的责任交给开发者。泛型参数T是自定义配置类型,开发者无需自己处理配置解析。

config.Source接口

package config

type Source interface {
	Apply(Store) error
}

config.Source是bedrock包中最强大的抽象之一,它抽象了整个应用程序配置来源的机制。这个简单接口可以通过多种方式实现,支持从不同文件(如YAML、JSON、TOML)到远程配置存储(如etcd)加载配置。

Run函数

func Run[T any](ctx context.Context, builder AppBuilder[T], srcs ...config.Source) error

Run函数是bedrock提供的最关键部分,它处理配置解析、应用构建和执行的编排。

完整示例

config.yaml

logging:
  min_level: {{env "MIN_LOG_LEVEL"}}

main.go

package main

import (
	"bytes"
	"context"
	_ "embed"
	"log/slog"
	"os"

	"github.com/z5labs/bedrock"
	"github.com/z5labs/bedrock/app"
	"github.com/z5labs/bedrock/appbuilder"
	"github.com/z5labs/bedrock/config"
)

//go:embed config.yaml
var configBytes []byte

func main() {
	os.Exit(run())
}

func run() int {
	// bedrock不处理进程退出,这主要是为了帮助框架开发者在单元测试中验证返回的错误
	err := bedrock.Run(
		context.Background(),
		appbuilder.Recover(
			bedrock.AppBuilderFunc[myConfig](initApp),
		),
		config.FromYaml(
			config.RenderTextTemplate(
				bytes.NewReader(configBytes),
				config.TemplateFunc("env", os.Getenv),
			),
		),
	)
	if err == nil {
		return 0
	}
	return 1
}

// myConfig可以包含任何内容,唯一需要注意的是必须使用"config"标签名
type myConfig struct {
	Logging struct {
		MinLevel slog.Level `config:"min_level"`
	} `config:"logging"`
}

type myApp struct {
	log *slog.Logger
}

// initApp是bedrock.AppBuilder接口的函数实现
func initApp(ctx context.Context, cfg myConfig) (bedrock.App, error) {
	var base bedrock.App = &myApp{
		log: slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
			Level: cfg.Logging.MinLevel,
		})),
	}
	base = app.Recover(base)
	return base, nil
}

// Run实现bedrock.App接口
func (a *myApp) Run(ctx context.Context) error {
	// 在这里可以执行各种操作,例如:
	// - 运行HTTP服务器
	// - 启动AWS lambda运行时
	// - 运行goroutines消费Kafka消息等

	a.log.InfoContext(ctx, "running my app")
	return nil
}

基于bedrock构建的项目

  • z5labs/humus

更多关于golang快速开发服务的模块化基础框架插件bedrock的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang快速开发服务的模块化基础框架插件bedrock的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang快速开发服务的模块化基础框架插件Bedrock使用指南

Bedrock是一个用于快速开发Golang服务的模块化基础框架插件,它提供了一套标准化的开发模式和常用组件,帮助开发者快速构建稳定、可扩展的微服务。

1. Bedrock核心特性

  • 模块化设计:通过插件机制实现功能解耦
  • 标准化配置:统一的配置管理方式
  • 内置常用组件:日志、监控、数据库连接等
  • 服务治理:服务注册、发现、负载均衡
  • 开发友好:简化开发流程,减少样板代码

2. 快速开始

安装Bedrock

go get github.com/evergreen-ci/bedrock

基础示例代码

package main

import (
	"context"
	"fmt"
	
	"github.com/evergreen-ci/bedrock"
	"github.com/evergreen-ci/bedrock/model"
)

func main() {
	// 初始化Bedrock应用
	app := bedrock.NewApp("my-service")
	
	// 添加内置模块
	app.Enable(
		bedrock.LoggerModule(),    // 日志模块
		bedrock.MetricsModule(),   // 监控模块
		bedrock.DatabaseModule(),  // 数据库模块
	)
	
	// 添加自定义模块
	app.AddModule(&MyModule{})
	
	// 启动应用
	if err := app.Start(context.Background()); err != nil {
		panic(fmt.Sprintf("failed to start app: %v", err))
	}
}

// 自定义模块示例
type MyModule struct {
	model.BaseModule
}

func (m *MyModule) ModuleName() string {
	return "my-module"
}

func (m *MyModule) Start(ctx context.Context) error {
	fmt.Println("MyModule started")
	return nil
}

func (m *MyModule) Stop(ctx context.Context) error {
	fmt.Println("MyModule stopped")
	return nil
}

3. 核心模块详解

3.1 配置管理

Bedrock使用YAML格式的配置文件,默认路径为configs/config.yaml

app:
  name: "my-service"
  env: "dev"
  
logger:
  level: "info"
  format: "json"
  
database:
  driver: "mysql"
  dsn: "user:password@tcp(127.0.0.1:3306)/dbname"

加载配置示例:

config := bedrock.NewConfig()
if err := config.Load("configs/config.yaml"); err != nil {
    panic(fmt.Sprintf("failed to load config: %v", err))
}

// 获取配置值
appName := config.GetString("app.name")

3.2 日志模块

// 获取日志实例
logger := bedrock.Logger(ctx)

// 记录日志
logger.Info("This is an info message")
logger.WithFields(map[string]interface{}{
    "key": "value",
}).Error("This is an error with fields")

3.3 数据库模块

// 获取数据库连接
db, err := bedrock.DB()
if err != nil {
    return fmt.Errorf("failed to get db connection: %v", err)
}

// 执行查询
var result string
if err := db.QueryRow("SELECT 'hello'").Scan(&result); err != nil {
    return fmt.Errorf("query failed: %v", err)
}

3.4 HTTP服务模块

app.Enable(bedrock.HTTPServerModule())

// 添加路由
app.HTTP().GET("/health", func(c *gin.Context) {
    c.JSON(200, gin.H{"status": "ok"})
})

// 启动HTTP服务
go func() {
    if err := app.HTTP().Run(":8080"); err != nil {
        logger.Fatal("HTTP server error", zap.Error(err))
    }
}()

4. 自定义模块开发

type CustomModule struct {
	model.BaseModule
	config *CustomConfig
}

type CustomConfig struct {
	Enabled bool   `yaml:"enabled"`
	Address string `yaml:"address"`
}

func (m *CustomModule) ModuleName() string {
	return "custom-module"
}

func (m *CustomModule) Init(app *bedrock.App) error {
	// 加载配置
	if err := app.Config().UnmarshalKey("custom", &m.config); err != nil {
		return fmt.Errorf("failed to load custom module config: %v", err)
	}
	return nil
}

func (m *CustomModule) Start(ctx context.Context) error {
	if !m.config.Enabled {
		return nil
	}
	
	// 启动自定义逻辑
	go m.runServer()
	return nil
}

func (m *CustomModule) runServer() {
	// 实现自定义服务逻辑
}

5. 最佳实践

  1. 模块划分:按功能划分模块,保持单一职责
  2. 配置分离:不同环境的配置分开管理
  3. 错误处理:统一错误处理机制
  4. 监控指标:为关键操作添加监控指标
  5. 文档注释:为模块和接口添加详细注释

6. 总结

Bedrock框架通过模块化设计简化了Golang服务的开发流程,内置的常用组件和标准化配置减少了重复工作,使开发者能够专注于业务逻辑实现。通过本文介绍的基础用法,您可以快速上手使用Bedrock构建您的微服务应用。

更多高级功能和详细文档请参考Bedrock官方文档

回到顶部