Brak opisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bootstrap.go 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. package bootstraps
  2. // import (
  3. // "context"
  4. // "fmt"
  5. // "log"
  6. // "net/http"
  7. // "os"
  8. // "os/signal"
  9. // "syscall"
  10. // "time"
  11. // "git.x2erp.com/qdy/go-base/client"
  12. // "git.x2erp.com/qdy/go-base/config"
  13. // "git.x2erp.com/qdy/go-base/consul"
  14. // "git.x2erp.com/qdy/go-base/logger"
  15. // )
  16. // // 定义接口
  17. // type ShutdownHandler interface {
  18. // OnShutdown()
  19. // }
  20. // // WebService Web服务实例
  21. // type WebService struct {
  22. // serviceName string
  23. // HttpServer *http.Server
  24. // Router *http.ServeMux
  25. // quit chan os.Signal
  26. // shutdownHandler ShutdownHandler
  27. // Port int
  28. // Ip string
  29. // }
  30. // // Bootstrapper 服务启动器
  31. // type Bootstrapper struct {
  32. // appName string
  33. // appVersion string
  34. // Cfg config.IConfig
  35. // services map[string]*WebService // 存储多个服务实例
  36. // quit chan os.Signal
  37. // }
  38. // // NewBootstrapper 创建启动器
  39. // func NewBootstrapper(name, version string) *Bootstrapper {
  40. // b := &Bootstrapper{
  41. // appName: name,
  42. // appVersion: version,
  43. // quit: make(chan os.Signal, 1),
  44. // services: make(map[string]*WebService),
  45. // }
  46. // b.init()
  47. // return b
  48. // }
  49. // // Init 初始化配置和日志
  50. // func (b *Bootstrapper) init() *Bootstrapper {
  51. // // 1. 初始化启动日志
  52. // if err := logger.InitBootLog(b.appName); err != nil {
  53. // log.Fatal("无法初始化启动日志: ", err)
  54. // }
  55. // // 2. 加载配置
  56. // log.Println("正在加载配置...")
  57. // cfg, err := config.GetConfig()
  58. // if err != nil {
  59. // log.Fatalf("加载配置失败: %v", err)
  60. // }
  61. // cfg.SetAppName(b.appName)
  62. // cfg.SetAppVersion(b.appVersion)
  63. // b.Cfg = cfg
  64. // // 3. 初始化运行时日志
  65. // logger.InitRuntimeLogger(b.appName, b.appVersion, b.Cfg.GetLog())
  66. // log.Println("配置和日志初始化完成")
  67. // return b
  68. // }
  69. // // CreateService 创建Web服务实例
  70. // func (b *Bootstrapper) createService() *WebService {
  71. // serviceCfg := b.Cfg.GetServiceConfig()
  72. // // 检查是否已存在同名服务
  73. // if _, exists := b.services[yamlNode]; exists {
  74. // logger.Debug("服务 %s 已存在,将返回现有实例", yamlNode)
  75. // return b.services[yamlNode]
  76. // }
  77. // io := client.GetServiceIP("")
  78. // // 创建新的服务实例
  79. // ws := &WebService{
  80. // serviceName: serviceCfg.ServiceName,
  81. // Router: http.NewServeMux(),
  82. // quit: make(chan os.Signal, 1),
  83. // Port: serviceCfg.Port,
  84. // Ip: io,
  85. // }
  86. // // 创建HTTP服务器
  87. // ws.HttpServer = &http.Server{
  88. // Addr: fmt.Sprintf(":%d", serviceCfg.Port),
  89. // Handler: ws.Router,
  90. // ReadTimeout: 15 * time.Second,
  91. // WriteTimeout: 15 * time.Second,
  92. // IdleTimeout: 60 * time.Second,
  93. // }
  94. // // 存储服务实例
  95. // b.services[yamlNode] = ws
  96. // logger.Debug("已创建服务实例: %s (端口: %d)", serviceCfg.ServiceName, serviceCfg.Port)
  97. // return ws
  98. // }
  99. // // GetAllServices 获取所有服务实例
  100. // func (b *Bootstrapper) GetAllServices() map[string]*WebService {
  101. // return b.services
  102. // }
  103. // // StartService 启动指定服务
  104. // func (b *Bootstrapper) StartService(yamlNode string) *Bootstrapper {
  105. // service := b.createService(yamlNode)
  106. // log.Printf("正在启动服务: %s ", service.serviceName)
  107. // log.Printf("模式: 独立运行 (net/http)")
  108. // log.Printf("服务端口: :%d", service.Port)
  109. // return b
  110. // }
  111. // // Run 运行所有服务
  112. // func (b *Bootstrapper) Run(shutdownHandler ShutdownHandler) {
  113. // if len(b.services) == 0 {
  114. // log.Fatal("没有要运行的服务,请先创建服务实例")
  115. // }
  116. // log.Printf("开始运行 %d 个服务...", len(b.services))
  117. // // 设置全局信号监听
  118. // signal.Notify(b.quit, syscall.SIGINT, syscall.SIGTERM)
  119. // // 启动所有服务
  120. // for serviceName, service := range b.services {
  121. // go func(name string, ws *WebService) {
  122. // consul.Register(service.serviceName, service.Ip, service.Port, b.Cfg.GetConsulConfig())
  123. // log.Printf("启动服务 %s 在 %s", name, ws.HttpServer.Addr)
  124. // if err := ws.HttpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
  125. // log.Fatalf("服务 %s 运行失败: %v", name, err)
  126. // }
  127. // }(serviceName, service)
  128. // }
  129. // // 等待中断信号
  130. // b.waitForShutdown(shutdownHandler)
  131. // }
  132. // // RunSingle 运行单个服务
  133. // func (b *Bootstrapper) RunSingle(yamlNode string, shutdownHandler ShutdownHandler) {
  134. // service := b.createService(yamlNode)
  135. // log.Printf("服务 %s 开始运行...", service.serviceName)
  136. // // 设置服务级别的信号监听
  137. // signal.Notify(service.quit, syscall.SIGINT, syscall.SIGTERM)
  138. // // 启动服务
  139. // go func() {
  140. // log.Printf("服务器启动在 %s", service.HttpServer.Addr)
  141. // if err := service.HttpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
  142. // log.Fatalf("服务运行失败: %v", err)
  143. // }
  144. // }()
  145. // consul.Register(service.serviceName, service.Ip, service.Port, b.Cfg.GetConsulConfig())
  146. // // 等待中断信号
  147. // b.waitForServiceShutdown(service, shutdownHandler)
  148. // }
  149. // // RunTLS 运行HTTPS服务
  150. // func (b *Bootstrapper) RunTLS(serviceName, certFile, keyFile string, shutdownHandler ShutdownHandler) {
  151. // service := b.createService(serviceName)
  152. // log.Printf("服务 %s 开始运行(HTTPS)...", service.serviceName)
  153. // // 设置服务级别的信号监听
  154. // signal.Notify(service.quit, syscall.SIGINT, syscall.SIGTERM)
  155. // // 启动HTTPS服务器
  156. // go func() {
  157. // log.Printf("HTTPS服务器启动在 %s", service.HttpServer.Addr)
  158. // if err := service.HttpServer.ListenAndServeTLS(certFile, keyFile); err != nil && err != http.ErrServerClosed {
  159. // log.Fatalf("服务运行失败: %v", err)
  160. // }
  161. // }()
  162. // // 等待中断信号
  163. // b.waitForServiceShutdown(service, shutdownHandler)
  164. // }
  165. // // waitForShutdown 等待关闭信号(关闭所有服务)
  166. // func (b *Bootstrapper) waitForShutdown(handler ShutdownHandler) {
  167. // log.Println("按 Ctrl+C 停止所有服务")
  168. // // 等待信号
  169. // <-b.quit
  170. // log.Println("接收到终止信号,正在优雅关闭所有服务...")
  171. // // 创建关闭上下文,给30秒完成当前请求
  172. // ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  173. // defer cancel()
  174. // // 关闭所有服务
  175. // shutdownComplete := make(chan bool, len(b.services))
  176. // for serviceName, service := range b.services {
  177. // go func(name string, ws *WebService) {
  178. // log.Printf("正在关闭服务: %s", name)
  179. // //退出注册中心
  180. // consul.Deregister(service.serviceName, service.Ip, service.Port, b.Cfg.GetConsulConfig())
  181. // if err := ws.HttpServer.Shutdown(ctx); err != nil {
  182. // log.Printf("服务 %s 关闭失败: %v", name, err)
  183. // } else {
  184. // log.Printf("服务 %s 已关闭", name)
  185. // }
  186. // shutdownComplete <- true
  187. // }(serviceName, service)
  188. // }
  189. // // 等待所有服务关闭完成
  190. // for i := 0; i < len(b.services); i++ {
  191. // <-shutdownComplete
  192. // }
  193. // // 执行关闭处理
  194. // if handler != nil {
  195. // handler.OnShutdown()
  196. // }
  197. // // 停止日志写入
  198. // logger.StopESWriter()
  199. // log.Println("所有服务优雅关闭完成")
  200. // // 等待一小段时间确保日志写入完成
  201. // time.Sleep(100 * time.Millisecond)
  202. // os.Exit(0)
  203. // }
  204. // // waitForServiceShutdown 等待单个服务关闭
  205. // func (b *Bootstrapper) waitForServiceShutdown(service *WebService, handler ShutdownHandler) {
  206. // log.Printf("按 Ctrl+C 停止服务 %s", service.serviceName)
  207. // // 等待信号
  208. // <-service.quit
  209. // log.Printf("接收到终止信号,正在优雅关闭服务 %s...", service.serviceName)
  210. // //退出注册中心
  211. // consul.Deregister(service.serviceName, service.Ip, service.Port, b.Cfg.GetConsulConfig())
  212. // // 创建关闭上下文,给30秒完成当前请求
  213. // ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  214. // defer cancel()
  215. // // 停止接收新请求,完成当前请求
  216. // if err := service.HttpServer.Shutdown(ctx); err != nil {
  217. // log.Printf("服务 %s 关闭失败: %v", service.serviceName, err)
  218. // } else {
  219. // log.Printf("服务 %s 已关闭", service.serviceName)
  220. // }
  221. // // 执行关闭处理
  222. // if handler != nil {
  223. // handler.OnShutdown()
  224. // }
  225. // // 停止日志写入
  226. // logger.StopESWriter()
  227. // log.Printf("服务 %s 优雅关闭完成", service.serviceName)
  228. // // 等待一小段时间确保日志写入完成
  229. // time.Sleep(100 * time.Millisecond)
  230. // os.Exit(0)
  231. // }
  232. // // GetConfig 获取配置
  233. // func (b *Bootstrapper) GetConfig() config.IConfig {
  234. // return b.Cfg
  235. // }
  236. // // GetWebService 获取指定服务的路由器
  237. // func (b *Bootstrapper) GetRouter(yamlNode string) *http.ServeMux {
  238. // service := b.createService(yamlNode)
  239. // return service.Router
  240. // }
  241. // // GetRouterDefault 获取第一个服务的路由器(兼容性方法)
  242. // func (b *Bootstrapper) GetRouterDefault() *http.ServeMux {
  243. // for _, service := range b.services {
  244. // return service.Router
  245. // }
  246. // // 如果没有服务,创建默认路由器(向后兼容)
  247. // return http.NewServeMux()
  248. // }
  249. // // // Handle 注册路由处理器到指定服务
  250. // // func (b *Bootstrapper) Handle(serviceName, pattern string, handler http.Handler) bool {
  251. // // if service, exists := b.services[serviceName]; exists {
  252. // // service.Router.Handle(pattern, handler)
  253. // // return true
  254. // // }
  255. // // log.Printf("错误: 服务 %s 不存在", serviceName)
  256. // // return false
  257. // // }
  258. // // SetShutdownHandler 为服务设置关闭处理器
  259. // func (b *Bootstrapper) SetShutdownHandler(serviceName string, handler ShutdownHandler) bool {
  260. // if service, exists := b.services[serviceName]; exists {
  261. // service.shutdownHandler = handler
  262. // return true
  263. // }
  264. // return false
  265. // }
  266. // // ========== WebService 的方法 ==========
  267. // // GetServiceName 获取服务名称
  268. // // func (ws *WebService) GetServiceName() string {
  269. // // return ws.serviceName
  270. // // }
  271. // // // GetServiceConfig 获取服务配置
  272. // // func (ws *WebService) GetServiceConfig() *subconfigs.ServiceConfig {
  273. // // return ws.serviceConfig
  274. // // }
  275. // // GetRouter 获取服务的路由器
  276. // // func (ws *WebService) GetRouter() *http.ServeMux {
  277. // // return ws.Router
  278. // // }
  279. // // Handle 注册路由处理器
  280. // // func (ws *WebService) Handle(pattern string, handler http.Handler) {
  281. // // ws.Router.Handle(pattern, handler)
  282. // // }
  283. // // SetShutdownHandler 设置关闭处理器
  284. // func (ws *WebService) SetShutdownHandler(handler ShutdownHandler) {
  285. // ws.shutdownHandler = handler
  286. // }
  287. // // Run 运行单个服务
  288. // func (ws *WebService) Run(shutdownHandler ShutdownHandler) {
  289. // log.Printf("服务 %s 开始运行...", ws.serviceName)
  290. // // 设置信号监听
  291. // signal.Notify(ws.quit, syscall.SIGINT, syscall.SIGTERM)
  292. // // 启动服务
  293. // go func() {
  294. // log.Printf("服务器启动在 %s", ws.HttpServer.Addr)
  295. // if err := ws.HttpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
  296. // log.Fatalf("服务 %s 运行失败: %v", ws.serviceName, err)
  297. // }
  298. // }()
  299. // // 等待中断信号
  300. // log.Printf("按 Ctrl+C 停止服务 %s", ws.serviceName)
  301. // <-ws.quit
  302. // log.Printf("接收到终止信号,正在优雅关闭服务 %s...", ws.serviceName)
  303. // // 创建关闭上下文
  304. // ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  305. // defer cancel()
  306. // // 关闭服务
  307. // if err := ws.HttpServer.Shutdown(ctx); err != nil {
  308. // log.Printf("服务 %s 关闭失败: %v", ws.serviceName, err)
  309. // } else {
  310. // log.Printf("服务 %s 已关闭", ws.serviceName)
  311. // }
  312. // // 执行关闭处理
  313. // if shutdownHandler != nil {
  314. // shutdownHandler.OnShutdown()
  315. // } else if ws.shutdownHandler != nil {
  316. // ws.shutdownHandler.OnShutdown()
  317. // }
  318. // log.Printf("服务 %s 优雅关闭完成", ws.serviceName)
  319. // time.Sleep(100 * time.Millisecond)
  320. // os.Exit(0)
  321. // }