配置模型
Plumego 服务通过显式的 core.AppConfig 结构体进行配置。没有隐藏的配置注册表,没有全局状态,也没有基于反射的自动绑定。你构建配置、覆盖需要修改的字段,然后传给 core.New。
规范启动模式
Section titled “规范启动模式”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}AppConfig 字段说明
Section titled “AppConfig 字段说明”core.DefaultConfig() 返回安全的默认基线值,只需覆盖不同的字段。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Addr |
string |
:8080 |
TCP 监听地址(如 ":9090"、"0.0.0.0:443") |
TLS.Enabled |
bool |
false |
启用 TLS |
TLS.CertFile |
string |
"" |
TLS 证书 PEM 路径 |
TLS.KeyFile |
string |
"" |
TLS 私钥 PEM 路径 |
Router.MethodNotAllowed |
bool |
false |
方法不匹配时返回 405 + Allow 头,而非 404 |
ReadTimeout |
time.Duration |
30s |
读取完整请求的最长时间 |
ReadHeaderTimeout |
time.Duration |
5s |
读取请求头的最长时间(防 slowloris) |
WriteTimeout |
time.Duration |
30s |
写响应前的超时时间 |
IdleTimeout |
time.Duration |
60s |
keep-alive 连接最长空闲时间 |
MaxHeaderBytes |
int |
1 MiB |
请求头最大尺寸 |
HTTP2Enabled |
bool |
true |
启用 HTTP/2(浏览器需要 TLS;默认开启) |
DrainInterval |
time.Duration |
500ms |
优雅关闭时打印在途连接数的间隔 |
AppDependencies
Section titled “AppDependencies”type AppDependencies struct { Logger log.StructuredLogger}Logger 是内核层唯一注入的依赖。省略则丢弃所有日志输出。传入 log.NewLogger() 可使用默认结构化日志器。
TLS 配置
Section titled “TLS 配置”cfg := core.DefaultConfig()cfg.Addr = ":443"cfg.TLS.Enabled = truecfg.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())}环境变量模式
Section titled “环境变量模式”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。
生产环境加固
Section titled “生产环境加固”生产部署时,请检查以下超时字段:
- 将
ReadHeaderTimeout设为5s或更短,防范 slowloris 攻击。 - 将
WriteTimeout设为最长 handler 延迟加一个余量。 - 将
IdleTimeout设为低于负载均衡器的 idle timeout,避免连接复用时的竞态条件。 - 根据客户端实际需求设置
MaxHeaderBytes(默认 1 MiB 偏大)。