|
|
@@ -1,146 +1,109 @@
|
|
1
|
1
|
package main
|
|
2
|
2
|
|
|
3
|
3
|
import (
|
|
4
|
|
- "fmt"
|
|
5
|
4
|
"log"
|
|
6
|
5
|
"net/http"
|
|
7
|
6
|
"os"
|
|
8
|
7
|
"os/signal"
|
|
9
|
|
- "strings"
|
|
10
|
8
|
"syscall"
|
|
11
|
|
- "time"
|
|
12
|
9
|
|
|
13
|
10
|
"git.x2erp.com/qdy/go-base/config"
|
|
14
|
|
- "git.x2erp.com/qdy/go-base/types"
|
|
|
11
|
+ "git.x2erp.com/qdy/go-base/micro"
|
|
|
12
|
+ mymiddleware "git.x2erp.com/qdy/go-base/myMiddleware"
|
|
15
|
13
|
"git.x2erp.com/qdy/go-db/factory/database"
|
|
16
|
|
- "git.x2erp.com/qdy/go-service-agent/auth"
|
|
|
14
|
+ "git.x2erp.com/qdy/go-db/myhandle"
|
|
17
|
15
|
"git.x2erp.com/qdy/go-service-agent/functions"
|
|
18
|
|
- "github.com/gin-gonic/gin"
|
|
|
16
|
+ "go-micro.dev/v4/web"
|
|
19
|
17
|
)
|
|
20
|
18
|
|
|
21
|
19
|
func main() {
|
|
22
|
|
-
|
|
23
|
20
|
cfg := config.GetConfig()
|
|
|
21
|
+ serviceConfig := cfg.GetService()
|
|
24
|
22
|
|
|
25
|
|
- log.Printf("Service Port: %d", cfg.GetService().Port)
|
|
26
|
|
- log.Printf("Service IdleTimeout: %d", cfg.GetService().IdleTimeout)
|
|
27
|
|
- log.Printf("Service ReadTimeout: %d", cfg.GetService().ReadTimeout)
|
|
28
|
|
- log.Printf("Service WriteTimeout: %d", cfg.GetService().WriteTimeout)
|
|
29
|
|
- log.Printf("Service TrustedProxies: %s", cfg.GetService().TrustedProxies)
|
|
|
23
|
+ log.Printf("Service Port: %d", serviceConfig.Port)
|
|
|
24
|
+ log.Printf("Service IdleTimeout: %d", serviceConfig.IdleTimeout)
|
|
|
25
|
+ log.Printf("Service ReadTimeout: %d", serviceConfig.ReadTimeout)
|
|
|
26
|
+ log.Printf("Service WriteTimeout: %d", serviceConfig.WriteTimeout)
|
|
|
27
|
+ log.Printf("Service TrustedProxies: %s", serviceConfig.TrustedProxies)
|
|
30
|
28
|
|
|
31
|
29
|
log.Printf("Using database type: %s", cfg.GetDatabase().Type)
|
|
32
|
30
|
log.Printf("Database host: %s:%d", cfg.GetDatabase().Host, cfg.GetDatabase().Port)
|
|
33
|
31
|
log.Printf("Database name: %s", cfg.GetDatabase().Database)
|
|
34
|
32
|
log.Println("Database connection test passed!")
|
|
35
|
33
|
|
|
36
|
|
- // 3. 启动Gin HTTP服务
|
|
37
|
|
- startHTTPServer()
|
|
|
34
|
+ // 启动微服务
|
|
|
35
|
+ startMicroService()
|
|
38
|
36
|
}
|
|
39
|
37
|
|
|
40
|
|
-// 启动HTTP服务器
|
|
41
|
|
-func startHTTPServer() {
|
|
42
|
|
- //建立路由
|
|
43
|
|
- router := gin.Default()
|
|
|
38
|
+// 启动微服务
|
|
|
39
|
+func startMicroService() {
|
|
44
|
40
|
cfg := config.GetConfig()
|
|
45
|
41
|
serviceConfig := cfg.GetService()
|
|
46
|
42
|
|
|
|
43
|
+ // 初始化数据库
|
|
47
|
44
|
dbFactory, err := database.GetDBFactory()
|
|
48
|
45
|
if err != nil {
|
|
49
|
46
|
log.Fatalf("Failed to create DB factory: %v", err)
|
|
50
|
47
|
}
|
|
51
|
|
- // 设置优雅关闭
|
|
52
|
|
- setupGracefulShutdown(dbFactory)
|
|
53
|
48
|
defer func() {
|
|
54
|
|
- dbFactory.Close()
|
|
55
|
|
- log.Println("Database connection closed")
|
|
|
49
|
+ if err := dbFactory.Close(); err != nil {
|
|
|
50
|
+ log.Printf("Database close error: %v", err)
|
|
|
51
|
+ }
|
|
56
|
52
|
}()
|
|
57
|
53
|
|
|
58
|
|
- // 核心路由
|
|
59
|
|
- router.GET("/api/health", functions.HealthHandler(dbFactory, cfg.GetDatabase().Type))
|
|
60
|
|
- router.POST("/api/query", auth.AuthMiddleware(), withQueryRequest(functions.QueryToJSON(dbFactory)))
|
|
61
|
|
- router.POST("/api/query/csv", auth.AuthMiddleware(), withQueryRequest(functions.QueryToCSV(dbFactory)))
|
|
62
|
|
- router.POST("/api/query/csv/param", auth.AuthMiddleware(), withQueryRequest(functions.QueryPositionalToCSV(dbFactory)))
|
|
63
|
|
- router.GET("/api/info", functions.InfoHandler(dbFactory))
|
|
64
|
|
-
|
|
65
|
|
- // 日志输出配置信息
|
|
66
|
|
- log.Printf("Service Port: %d", serviceConfig.Port)
|
|
67
|
|
- log.Printf("Service IdleTimeout: %d", serviceConfig.IdleTimeout)
|
|
68
|
|
- log.Printf("Service ReadTimeout: %d", serviceConfig.ReadTimeout)
|
|
69
|
|
- log.Printf("Service WriteTimeout: %d", serviceConfig.WriteTimeout)
|
|
70
|
|
- log.Printf("Service TrustedProxies: %s", serviceConfig.TrustedProxies)
|
|
|
54
|
+ // 设置优雅关闭
|
|
|
55
|
+ setupGracefulShutdown(dbFactory)
|
|
71
|
56
|
|
|
72
|
|
- // 设置可信代理
|
|
73
|
|
- setupTrustedProxies(router, serviceConfig.TrustedProxies)
|
|
|
57
|
+ webService := micro.StartStandalone(cfg)
|
|
74
|
58
|
|
|
75
|
|
- // 创建HTTP服务器配置
|
|
76
|
|
- server := &http.Server{
|
|
77
|
|
- Addr: fmt.Sprintf(":%d", serviceConfig.Port),
|
|
78
|
|
- Handler: router,
|
|
79
|
|
- IdleTimeout: time.Duration(serviceConfig.IdleTimeout) * time.Second,
|
|
80
|
|
- ReadTimeout: time.Duration(serviceConfig.ReadTimeout) * time.Second,
|
|
81
|
|
- WriteTimeout: time.Duration(serviceConfig.WriteTimeout) * time.Second,
|
|
82
|
|
- }
|
|
|
59
|
+ // 注册HTTP路由到webService
|
|
|
60
|
+ registerRoutes(webService, dbFactory, cfg)
|
|
83
|
61
|
|
|
84
|
|
- log.Printf("Starting HTTP server on port %d", serviceConfig.Port)
|
|
85
|
|
- if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
|
86
|
|
- log.Fatalf("Failed to start server: %v", err)
|
|
87
|
|
- }
|
|
|
62
|
+ // 等待服务运行
|
|
|
63
|
+ log.Printf("Service started successfully")
|
|
|
64
|
+ log.Printf(" • Service: %s", serviceConfig.ServiceName)
|
|
|
65
|
+ log.Printf(" • Port: %d", serviceConfig.Port)
|
|
|
66
|
+ log.Printf(" • Mode: %s", getServiceMode(cfg))
|
|
88
|
67
|
|
|
|
68
|
+ // 保持主程序运行
|
|
|
69
|
+ select {}
|
|
89
|
70
|
}
|
|
90
|
71
|
|
|
91
|
|
-// 参数绑定包装器
|
|
92
|
|
-func withQueryRequest(handler func(c *gin.Context, req types.QueryRequest)) gin.HandlerFunc {
|
|
93
|
|
- return func(c *gin.Context) {
|
|
94
|
|
- var req types.QueryRequest
|
|
95
|
|
- if err := c.ShouldBindJSON(&req); err != nil {
|
|
96
|
|
- c.JSON(400, &types.QueryResult{
|
|
97
|
|
- Success: false,
|
|
98
|
|
- Error: "Invalid request: " + err.Error(),
|
|
99
|
|
- Data: nil,
|
|
100
|
|
- })
|
|
101
|
|
- return
|
|
102
|
|
- }
|
|
103
|
|
-
|
|
104
|
|
- handler(c, req)
|
|
105
|
|
- }
|
|
|
72
|
+// 判断是否使用注册中心
|
|
|
73
|
+func shouldUseRegistry(cfg config.IConfig) bool {
|
|
|
74
|
+ microConfig := cfg.GetMicro()
|
|
|
75
|
+ // 如果有配置注册中心地址且不为空,则使用注册中心
|
|
|
76
|
+ return microConfig.RegistryAddress != ""
|
|
106
|
77
|
}
|
|
107
|
78
|
|
|
108
|
|
-// 设置可信代理
|
|
109
|
|
-func setupTrustedProxies(router *gin.Engine, trustedProxiesStr string) {
|
|
110
|
|
- if trustedProxiesStr == "" {
|
|
111
|
|
- setupTrustedProxiesRouter(router, nil)
|
|
112
|
|
- return
|
|
113
|
|
- }
|
|
114
|
|
-
|
|
115
|
|
- // 按逗号分割字符串,并去除空格
|
|
116
|
|
- proxies := strings.Split(trustedProxiesStr, ",")
|
|
117
|
|
- trimmedProxies := make([]string, 0, len(proxies))
|
|
118
|
|
-
|
|
119
|
|
- for _, proxy := range proxies {
|
|
120
|
|
- trimmed := strings.TrimSpace(proxy)
|
|
121
|
|
- if trimmed != "" {
|
|
122
|
|
- trimmedProxies = append(trimmedProxies, trimmed)
|
|
123
|
|
- }
|
|
124
|
|
- }
|
|
125
|
|
-
|
|
126
|
|
- if len(trimmedProxies) > 0 {
|
|
127
|
|
- setupTrustedProxiesRouter(router, trimmedProxies)
|
|
128
|
|
- } else {
|
|
129
|
|
- setupTrustedProxiesRouter(router, nil)
|
|
|
79
|
+// 获取服务模式描述
|
|
|
80
|
+func getServiceMode(cfg config.IConfig) string {
|
|
|
81
|
+ if shouldUseRegistry(cfg) {
|
|
|
82
|
+ return "With Service Discovery"
|
|
130
|
83
|
}
|
|
|
84
|
+ return "Standalone"
|
|
131
|
85
|
}
|
|
132
|
86
|
|
|
133
|
|
-func setupTrustedProxiesRouter(router *gin.Engine, trimmedProxies []string) {
|
|
|
87
|
+// 注册所有路由
|
|
|
88
|
+func registerRoutes(webService web.Service, dbFactory *database.DBFactory, cfg config.IConfig) {
|
|
134
|
89
|
|
|
135
|
|
- err := router.SetTrustedProxies(trimmedProxies)
|
|
136
|
|
- if err != nil {
|
|
137
|
|
- log.Printf("Warning: Failed to set trusted proxies: %v", err)
|
|
138
|
|
- } else {
|
|
139
|
|
- log.Printf("Trusted proxies set: %v", trimmedProxies)
|
|
140
|
|
- }
|
|
|
90
|
+ // 查询接口 - JSON
|
|
|
91
|
+ webService.Handle("/api/query/json", mymiddleware.JWTAuthMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
92
|
+ myhandle.QueryHandlerJson(w, r, dbFactory, functions.QueryToJSON)
|
|
|
93
|
+ })))
|
|
141
|
94
|
|
|
|
95
|
+ // 查询接口 - CSV
|
|
|
96
|
+ webService.Handle("/api/query/csv", mymiddleware.JWTAuthMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
97
|
+ myhandle.QueryHandlerBytes(w, r, dbFactory, functions.QueryToCSV)
|
|
|
98
|
+ })))
|
|
|
99
|
+
|
|
|
100
|
+ // 查询接口 - CSV with positional params
|
|
|
101
|
+ webService.Handle("/api/query/csv/param", mymiddleware.JWTAuthMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
102
|
+ myhandle.QueryHandlerBytes(w, r, dbFactory, functions.QueryPositionalToCSV)
|
|
|
103
|
+ })))
|
|
142
|
104
|
}
|
|
143
|
105
|
|
|
|
106
|
+// 设置优雅关闭
|
|
144
|
107
|
func setupGracefulShutdown(dbFactory *database.DBFactory) {
|
|
145
|
108
|
signalCh := make(chan os.Signal, 1)
|
|
146
|
109
|
signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
|
|
|
@@ -148,7 +111,9 @@ func setupGracefulShutdown(dbFactory *database.DBFactory) {
|
|
148
|
111
|
go func() {
|
|
149
|
112
|
<-signalCh
|
|
150
|
113
|
log.Println("\nReceived shutdown signal, closing database connection...")
|
|
151
|
|
- dbFactory.Close()
|
|
|
114
|
+ if err := dbFactory.Close(); err != nil {
|
|
|
115
|
+ log.Printf("Error closing database: %v", err)
|
|
|
116
|
+ }
|
|
152
|
117
|
log.Println("Database connection closed gracefully")
|
|
153
|
118
|
os.Exit(0)
|
|
154
|
119
|
}()
|