跳转到内容

配置模型

Plumego 服务通过显式的 core.AppConfig 结构体进行配置。没有隐藏的配置注册表,没有全局状态,也没有基于反射的自动绑定。你构建配置、覆盖需要修改的字段,然后传给 core.New

import "github.com/spcent/plumego/core"
func main() {
cfg, err := config.Load() // 你的应用级加载函数
if err != nil {
log.Fatalf("config: %v", err)
}
app := core.New(cfg.Core, core.AppDependencies{
Logger: myLogger,
})
// 注册路由和中间件 ...
app.Start()
}

config.Load() 是你自己拥有的应用级函数。最小实现:

func Load() (Config, error) {
addr := os.Getenv("ADDR")
if addr == "" {
addr = ":8080"
}
cfg := core.DefaultConfig()
cfg.Addr = addr
return Config{Core: cfg}, nil
}

core.DefaultConfig() 返回安全的默认基线值,只需覆盖不同的字段。

字段类型默认值说明
Addrstring:8080TCP 监听地址(如 ":9090""0.0.0.0:443"
TLS.Enabledboolfalse启用 TLS
TLS.CertFilestring""TLS 证书 PEM 路径
TLS.KeyFilestring""TLS 私钥 PEM 路径
Router.MethodNotAllowedboolfalse方法不匹配时返回 405 + Allow 头,而非 404
ReadTimeouttime.Duration30s读取完整请求的最长时间
ReadHeaderTimeouttime.Duration5s读取请求头的最长时间(防 slowloris)
WriteTimeouttime.Duration30s写响应前的超时时间
IdleTimeouttime.Duration60skeep-alive 连接最长空闲时间
MaxHeaderBytesint1 MiB请求头最大尺寸
HTTP2Enabledbooltrue启用 HTTP/2(浏览器需要 TLS;默认开启)
DrainIntervaltime.Duration500ms优雅关闭时打印在途连接数的间隔
type AppDependencies struct {
Logger log.StructuredLogger
}

Logger 是内核层唯一注入的依赖。省略则丢弃所有日志输出。传入 log.NewLogger() 可使用默认结构化日志器。

cfg := core.DefaultConfig()
cfg.Addr = ":443"
cfg.TLS.Enabled = true
cfg.TLS.CertFile = "/etc/tls/cert.pem"
cfg.TLS.KeyFile = "/etc/tls/key.pem"
app := core.New(cfg, deps)

在启动路径中根据 cfg.TLS.Enabled 选择启动方式:

srv, _ := app.Server()
if cfg.TLS.Enabled {
log.Fatal(srv.ListenAndServeTLS("", ""))
} else {
log.Fatal(srv.ListenAndServe())
}

Plumego 不会自动绑定环境变量。规范模式是在应用的 config.Load() 函数中读取:

func Load() (Config, error) {
cfg := core.DefaultConfig()
if addr := os.Getenv("ADDR"); addr != "" {
cfg.Addr = addr
}
if v := os.Getenv("READ_TIMEOUT"); v != "" {
d, err := time.ParseDuration(v)
if err != nil {
return Config{}, fmt.Errorf("READ_TIMEOUT: %w", err)
}
cfg.ReadTimeout = d
}
if os.Getenv("TLS_ENABLED") == "true" {
cfg.TLS = core.TLSConfig{
Enabled: true,
CertFile: os.Getenv("TLS_CERT_FILE"),
KeyFile: os.Getenv("TLS_KEY_FILE"),
}
}
return Config{Core: cfg}, nil
}

完整示例见 reference/standard-service/internal/config/config.go

生产部署时,请检查以下超时字段:

  • ReadHeaderTimeout 设为 5s 或更短,防范 slowloris 攻击。
  • WriteTimeout 设为最长 handler 延迟加一个余量。
  • IdleTimeout 设为低于负载均衡器的 idle timeout,避免连接复用时的竞态条件。
  • 根据客户端实际需求设置 MaxHeaderBytes(默认 1 MiB 偏大)。