package bootstraps // import ( // "context" // "fmt" // "log" // "net/http" // "os" // "os/signal" // "syscall" // "time" // "git.x2erp.com/qdy/go-base/client" // "git.x2erp.com/qdy/go-base/config" // "git.x2erp.com/qdy/go-base/consul" // "git.x2erp.com/qdy/go-base/logger" // ) // // 定义接口 // type ShutdownHandler interface { // OnShutdown() // } // // WebService Web服务实例 // type WebService struct { // serviceName string // HttpServer *http.Server // Router *http.ServeMux // quit chan os.Signal // shutdownHandler ShutdownHandler // Port int // Ip string // } // // Bootstrapper 服务启动器 // type Bootstrapper struct { // appName string // appVersion string // Cfg config.IConfig // services map[string]*WebService // 存储多个服务实例 // quit chan os.Signal // } // // NewBootstrapper 创建启动器 // func NewBootstrapper(name, version string) *Bootstrapper { // b := &Bootstrapper{ // appName: name, // appVersion: version, // quit: make(chan os.Signal, 1), // services: make(map[string]*WebService), // } // b.init() // return b // } // // Init 初始化配置和日志 // func (b *Bootstrapper) init() *Bootstrapper { // // 1. 初始化启动日志 // if err := logger.InitBootLog(b.appName); err != nil { // log.Fatal("无法初始化启动日志: ", err) // } // // 2. 加载配置 // log.Println("正在加载配置...") // cfg, err := config.GetConfig() // if err != nil { // log.Fatalf("加载配置失败: %v", err) // } // cfg.SetAppName(b.appName) // cfg.SetAppVersion(b.appVersion) // b.Cfg = cfg // // 3. 初始化运行时日志 // logger.InitRuntimeLogger(b.appName, b.appVersion, b.Cfg.GetLog()) // log.Println("配置和日志初始化完成") // return b // } // // CreateService 创建Web服务实例 // func (b *Bootstrapper) createService() *WebService { // serviceCfg := b.Cfg.GetServiceConfig() // // 检查是否已存在同名服务 // if _, exists := b.services[yamlNode]; exists { // logger.Debug("服务 %s 已存在,将返回现有实例", yamlNode) // return b.services[yamlNode] // } // io := client.GetServiceIP("") // // 创建新的服务实例 // ws := &WebService{ // serviceName: serviceCfg.ServiceName, // Router: http.NewServeMux(), // quit: make(chan os.Signal, 1), // Port: serviceCfg.Port, // Ip: io, // } // // 创建HTTP服务器 // ws.HttpServer = &http.Server{ // Addr: fmt.Sprintf(":%d", serviceCfg.Port), // Handler: ws.Router, // ReadTimeout: 15 * time.Second, // WriteTimeout: 15 * time.Second, // IdleTimeout: 60 * time.Second, // } // // 存储服务实例 // b.services[yamlNode] = ws // logger.Debug("已创建服务实例: %s (端口: %d)", serviceCfg.ServiceName, serviceCfg.Port) // return ws // } // // GetAllServices 获取所有服务实例 // func (b *Bootstrapper) GetAllServices() map[string]*WebService { // return b.services // } // // StartService 启动指定服务 // func (b *Bootstrapper) StartService(yamlNode string) *Bootstrapper { // service := b.createService(yamlNode) // log.Printf("正在启动服务: %s ", service.serviceName) // log.Printf("模式: 独立运行 (net/http)") // log.Printf("服务端口: :%d", service.Port) // return b // } // // Run 运行所有服务 // func (b *Bootstrapper) Run(shutdownHandler ShutdownHandler) { // if len(b.services) == 0 { // log.Fatal("没有要运行的服务,请先创建服务实例") // } // log.Printf("开始运行 %d 个服务...", len(b.services)) // // 设置全局信号监听 // signal.Notify(b.quit, syscall.SIGINT, syscall.SIGTERM) // // 启动所有服务 // for serviceName, service := range b.services { // go func(name string, ws *WebService) { // consul.Register(service.serviceName, service.Ip, service.Port, b.Cfg.GetConsulConfig()) // log.Printf("启动服务 %s 在 %s", name, ws.HttpServer.Addr) // if err := ws.HttpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { // log.Fatalf("服务 %s 运行失败: %v", name, err) // } // }(serviceName, service) // } // // 等待中断信号 // b.waitForShutdown(shutdownHandler) // } // // RunSingle 运行单个服务 // func (b *Bootstrapper) RunSingle(yamlNode string, shutdownHandler ShutdownHandler) { // service := b.createService(yamlNode) // log.Printf("服务 %s 开始运行...", service.serviceName) // // 设置服务级别的信号监听 // signal.Notify(service.quit, syscall.SIGINT, syscall.SIGTERM) // // 启动服务 // go func() { // log.Printf("服务器启动在 %s", service.HttpServer.Addr) // if err := service.HttpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { // log.Fatalf("服务运行失败: %v", err) // } // }() // consul.Register(service.serviceName, service.Ip, service.Port, b.Cfg.GetConsulConfig()) // // 等待中断信号 // b.waitForServiceShutdown(service, shutdownHandler) // } // // RunTLS 运行HTTPS服务 // func (b *Bootstrapper) RunTLS(serviceName, certFile, keyFile string, shutdownHandler ShutdownHandler) { // service := b.createService(serviceName) // log.Printf("服务 %s 开始运行(HTTPS)...", service.serviceName) // // 设置服务级别的信号监听 // signal.Notify(service.quit, syscall.SIGINT, syscall.SIGTERM) // // 启动HTTPS服务器 // go func() { // log.Printf("HTTPS服务器启动在 %s", service.HttpServer.Addr) // if err := service.HttpServer.ListenAndServeTLS(certFile, keyFile); err != nil && err != http.ErrServerClosed { // log.Fatalf("服务运行失败: %v", err) // } // }() // // 等待中断信号 // b.waitForServiceShutdown(service, shutdownHandler) // } // // waitForShutdown 等待关闭信号(关闭所有服务) // func (b *Bootstrapper) waitForShutdown(handler ShutdownHandler) { // log.Println("按 Ctrl+C 停止所有服务") // // 等待信号 // <-b.quit // log.Println("接收到终止信号,正在优雅关闭所有服务...") // // 创建关闭上下文,给30秒完成当前请求 // ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) // defer cancel() // // 关闭所有服务 // shutdownComplete := make(chan bool, len(b.services)) // for serviceName, service := range b.services { // go func(name string, ws *WebService) { // log.Printf("正在关闭服务: %s", name) // //退出注册中心 // consul.Deregister(service.serviceName, service.Ip, service.Port, b.Cfg.GetConsulConfig()) // if err := ws.HttpServer.Shutdown(ctx); err != nil { // log.Printf("服务 %s 关闭失败: %v", name, err) // } else { // log.Printf("服务 %s 已关闭", name) // } // shutdownComplete <- true // }(serviceName, service) // } // // 等待所有服务关闭完成 // for i := 0; i < len(b.services); i++ { // <-shutdownComplete // } // // 执行关闭处理 // if handler != nil { // handler.OnShutdown() // } // // 停止日志写入 // logger.StopESWriter() // log.Println("所有服务优雅关闭完成") // // 等待一小段时间确保日志写入完成 // time.Sleep(100 * time.Millisecond) // os.Exit(0) // } // // waitForServiceShutdown 等待单个服务关闭 // func (b *Bootstrapper) waitForServiceShutdown(service *WebService, handler ShutdownHandler) { // log.Printf("按 Ctrl+C 停止服务 %s", service.serviceName) // // 等待信号 // <-service.quit // log.Printf("接收到终止信号,正在优雅关闭服务 %s...", service.serviceName) // //退出注册中心 // consul.Deregister(service.serviceName, service.Ip, service.Port, b.Cfg.GetConsulConfig()) // // 创建关闭上下文,给30秒完成当前请求 // ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) // defer cancel() // // 停止接收新请求,完成当前请求 // if err := service.HttpServer.Shutdown(ctx); err != nil { // log.Printf("服务 %s 关闭失败: %v", service.serviceName, err) // } else { // log.Printf("服务 %s 已关闭", service.serviceName) // } // // 执行关闭处理 // if handler != nil { // handler.OnShutdown() // } // // 停止日志写入 // logger.StopESWriter() // log.Printf("服务 %s 优雅关闭完成", service.serviceName) // // 等待一小段时间确保日志写入完成 // time.Sleep(100 * time.Millisecond) // os.Exit(0) // } // // GetConfig 获取配置 // func (b *Bootstrapper) GetConfig() config.IConfig { // return b.Cfg // } // // GetWebService 获取指定服务的路由器 // func (b *Bootstrapper) GetRouter(yamlNode string) *http.ServeMux { // service := b.createService(yamlNode) // return service.Router // } // // GetRouterDefault 获取第一个服务的路由器(兼容性方法) // func (b *Bootstrapper) GetRouterDefault() *http.ServeMux { // for _, service := range b.services { // return service.Router // } // // 如果没有服务,创建默认路由器(向后兼容) // return http.NewServeMux() // } // // // Handle 注册路由处理器到指定服务 // // func (b *Bootstrapper) Handle(serviceName, pattern string, handler http.Handler) bool { // // if service, exists := b.services[serviceName]; exists { // // service.Router.Handle(pattern, handler) // // return true // // } // // log.Printf("错误: 服务 %s 不存在", serviceName) // // return false // // } // // SetShutdownHandler 为服务设置关闭处理器 // func (b *Bootstrapper) SetShutdownHandler(serviceName string, handler ShutdownHandler) bool { // if service, exists := b.services[serviceName]; exists { // service.shutdownHandler = handler // return true // } // return false // } // // ========== WebService 的方法 ========== // // GetServiceName 获取服务名称 // // func (ws *WebService) GetServiceName() string { // // return ws.serviceName // // } // // // GetServiceConfig 获取服务配置 // // func (ws *WebService) GetServiceConfig() *subconfigs.ServiceConfig { // // return ws.serviceConfig // // } // // GetRouter 获取服务的路由器 // // func (ws *WebService) GetRouter() *http.ServeMux { // // return ws.Router // // } // // Handle 注册路由处理器 // // func (ws *WebService) Handle(pattern string, handler http.Handler) { // // ws.Router.Handle(pattern, handler) // // } // // SetShutdownHandler 设置关闭处理器 // func (ws *WebService) SetShutdownHandler(handler ShutdownHandler) { // ws.shutdownHandler = handler // } // // Run 运行单个服务 // func (ws *WebService) Run(shutdownHandler ShutdownHandler) { // log.Printf("服务 %s 开始运行...", ws.serviceName) // // 设置信号监听 // signal.Notify(ws.quit, syscall.SIGINT, syscall.SIGTERM) // // 启动服务 // go func() { // log.Printf("服务器启动在 %s", ws.HttpServer.Addr) // if err := ws.HttpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { // log.Fatalf("服务 %s 运行失败: %v", ws.serviceName, err) // } // }() // // 等待中断信号 // log.Printf("按 Ctrl+C 停止服务 %s", ws.serviceName) // <-ws.quit // log.Printf("接收到终止信号,正在优雅关闭服务 %s...", ws.serviceName) // // 创建关闭上下文 // ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) // defer cancel() // // 关闭服务 // if err := ws.HttpServer.Shutdown(ctx); err != nil { // log.Printf("服务 %s 关闭失败: %v", ws.serviceName, err) // } else { // log.Printf("服务 %s 已关闭", ws.serviceName) // } // // 执行关闭处理 // if shutdownHandler != nil { // shutdownHandler.OnShutdown() // } else if ws.shutdownHandler != nil { // ws.shutdownHandler.OnShutdown() // } // log.Printf("服务 %s 优雅关闭完成", ws.serviceName) // time.Sleep(100 * time.Millisecond) // os.Exit(0) // }