// Command server 启动 sundynix-gateway —— 第 2 层业务网关 / 统一接入层。 package main import ( "context" "log" "os" "github.com/sundynix/sundynix-gateway/internal/blob" "github.com/sundynix/sundynix-gateway/internal/nats" "github.com/sundynix/sundynix-gateway/internal/router" "github.com/sundynix/sundynix-gateway/internal/store" "github.com/sundynix/sundynix-shared/contract" ) func main() { natsURL := envOr("NATS_URL", "nats://localhost:4222") pgDSN := envOr("POSTGRES_DSN", "postgres://sundynix:sundynix@localhost:5432/sundynix?sslmode=disable") redisAddr := envOr("REDIS_ADDR", "localhost:6379") // 对象存储(大文档正文):默认连 docker-compose 暴露的 MinIO;连不上则降级内联存 PG。 blobStore := blob.Open( envOr("MINIO_ENDPOINT", "localhost:9000"), envOr("MINIO_ACCESS_KEY", "minioadmin"), envOr("MINIO_SECRET_KEY", "minioadmin"), envOr("MINIO_BUCKET", "sundynix-docs"), ) db := store.OpenPostgres(pgDSN) // MainDB: Users / Billing / DSL(连不上则降级) defer db.Close() cache := store.OpenRedis(redisAddr) // CacheDB: Session / Rate Limit(连不上则降级) defer cache.Close() bus := nats.MustConnect(natsURL) // 接入 NATS 零拷贝骨干网 + 声明任务流 defer bus.Close() // 配置控制面:按 kind 响应消费方(Dispatcher=chat / mcp-go=embedding)的配置请求。 for _, kind := range []string{contract.ConfigKindChat, contract.ConfigKindEmbedding} { k := kind if _, err := bus.ServeConfig(k, func() *contract.ModelConfig { row, _ := db.GetActiveModel(context.Background(), k) if row == nil { return nil } return &contract.ModelConfig{Provider: row.Provider, BaseURL: row.BaseURL, APIKey: row.APIKey, Model: row.Model} }); err != nil { log.Printf("[gateway] serve %s config: %v", k, err) } } r := router.New(db, cache, bus, blobStore) addr := envOr("GATEWAY_ADDR", ":8080") log.Printf("[gateway] listening on %s", addr) if err := r.Run(addr); err != nil { log.Fatalf("[gateway] exit: %v", err) } } func envOr(key, def string) string { if v := os.Getenv(key); v != "" { return v } return def }