Browse Source

支持多微服务

qdy 2 months ago
parent
commit
d976968edf
4 changed files with 273 additions and 150 deletions
  1. 53
    8
      config/config.go
  2. 17
    15
      config/subconfigs/database_config.go
  3. 203
    24
      config/subconfigs/service_config.go
  4. 0
    103
      myservice/start_service.go

+ 53
- 8
config/config.go View File

@@ -34,11 +34,16 @@ type IConfig interface {
34 34
 	SetServiceName(name string)
35 35
 	SetServiceVersion(version string)
36 36
 	SetEnv(name string)
37
+
38
+	GetServiceVersion() string
39
+	GetEnv() string
37 40
 }
38 41
 
39 42
 // Config 主配置结构体 - 访问门面
40 43
 type Config struct {
41
-	initError error // 初始化错误
44
+	initError      error  // 初始化错误
45
+	ServiceVersion string //当前启动微服务版本
46
+	env            string //当前启动微服务环境dev test prod
42 47
 }
43 48
 
44 49
 // ========== 数据库相关方法(更新) ==========
@@ -120,13 +125,37 @@ func (c *Config) GetAuth() *subconfigs.AuthConfig {
120 125
 	return nil
121 126
 }
122 127
 
123
-func (c *Config) GetService() *subconfigs.ServiceConfig {
124
-	if config := subconfigs.GetRegisteredConfig("service"); config != nil {
125
-		return config.(*subconfigs.ServiceConfig)
128
+// ========== 微服务相关方法(更新) ==========
129
+
130
+// GetServices 获取所有微服务配置
131
+func (c *Config) GetServices() *subconfigs.ServicesConfig {
132
+	if config := subconfigs.GetRegisteredConfig("services"); config != nil {
133
+		if dbs, ok := config.(*subconfigs.ServicesConfig); ok {
134
+			return dbs
135
+		}
126 136
 	}
127 137
 	return nil
128 138
 }
129 139
 
140
+// GetService 获取默认微服务配置(向后兼容)
141
+func (c *Config) GetService() *subconfigs.ServiceConfig {
142
+	dbs := c.GetServices()
143
+	if dbs == nil {
144
+		logger.Errorf("获取默认微服务配置发生错误:配置为空!")
145
+		return nil
146
+	}
147
+	return dbs.GetDefaultService()
148
+}
149
+
150
+// GetServiceConfig 按名称获取微服务配置
151
+func (c *Config) GetServiceConfig(name string) *subconfigs.ServiceConfig {
152
+	dbs := c.GetServices()
153
+	if dbs == nil {
154
+		return nil
155
+	}
156
+	return dbs.GetService(name)
157
+}
158
+
130 159
 func (c *Config) GetHTTP() *subconfigs.HTTPConfig {
131 160
 	if config := subconfigs.GetRegisteredConfig("http"); config != nil {
132 161
 		return config.(*subconfigs.HTTPConfig)
@@ -165,9 +194,7 @@ func (c *Config) IsRedisConfigured() bool {
165 194
 
166 195
 // 设置方法
167 196
 func (c *Config) SetEnv(name string) {
168
-	if c.GetService().Env == "" {
169
-		c.GetService().Env = name
170
-	}
197
+	c.env = name
171 198
 }
172 199
 
173 200
 func (c *Config) SetServiceName(name string) {
@@ -177,7 +204,17 @@ func (c *Config) SetServiceName(name string) {
177 204
 }
178 205
 
179 206
 func (c *Config) SetServiceVersion(version string) {
180
-	c.GetService().ServiceVersion = version
207
+	c.ServiceVersion = version
208
+}
209
+
210
+// GetServiceVersion 获取服务版本
211
+func (c *Config) GetServiceVersion() string {
212
+	return c.ServiceVersion
213
+}
214
+
215
+// GetEnv 获取环境
216
+func (c *Config) GetEnv() string {
217
+	return c.env
181 218
 }
182 219
 
183 220
 // ========== 包级便捷函数(更新) ==========
@@ -251,6 +288,14 @@ func GetService() *subconfigs.ServiceConfig {
251 288
 	return cfgInstance.GetService()
252 289
 }
253 290
 
291
+// GetServiceConfig 包级便捷函数 - 按名称获取数微服务配置
292
+func GetServiceConfig(name string) *subconfigs.ServiceConfig {
293
+	if cfgInstance == nil {
294
+		return nil
295
+	}
296
+	return cfgInstance.GetServiceConfig(name)
297
+}
298
+
254 299
 // ========== 单例管理 ==========
255 300
 
256 301
 var (

+ 17
- 15
config/subconfigs/database_config.go View File

@@ -28,18 +28,19 @@ type DatabaseConfig struct {
28 28
 
29 29
 // SetDefaults 设置默认值 - 实现 ConfigLoader 接口
30 30
 func (c *DatabasesConfig) SetDefaults() {
31
-	if c.Databases == nil {
32
-		c.Databases = make(map[string]*DatabaseConfig)
33
-		log.Println("⚠️  数据库配置为空,已初始化空的数据库配置")
34
-		return
35
-	}
36
-
37
-	// 为每个数据库配置设置默认值
38
-	for _, db := range c.Databases {
39
-		if db != nil {
40
-			db.SetDefaults()
41
-		}
42
-	}
31
+	//因为是多集合,外层调这里赋默认值,这个时候对象还没有建立。赋默认值的地方移到其他地方去
32
+	// if c.Databases == nil {
33
+	// 	c.Databases = make(map[string]*DatabaseConfig)
34
+	// 	log.Println("⚠️  数据库配置为空,已初始化空的数据库配置")
35
+	// 	return
36
+	// }
37
+
38
+	// // 为每个数据库配置设置默认值
39
+	// for _, db := range c.Databases {
40
+	// 	if db != nil {
41
+	// 		db.SetDefaults()
42
+	// 	}
43
+	// }
43 44
 }
44 45
 
45 46
 func (c *DatabasesConfig) Load(data map[string]interface{}) error {
@@ -61,8 +62,9 @@ func (c *DatabasesConfig) Load(data map[string]interface{}) error {
61 62
 			}
62 63
 		}
63 64
 
64
-		// 加载单个数据库配置
65 65
 		dbConfig := &DatabaseConfig{}
66
+		dbConfig.SetDefaults() // 先设置默认值
67
+		// 加载单个数据库配置
66 68
 		if err := dbConfig.Load(stringMap); err != nil {
67 69
 			return fmt.Errorf("failed to load database '%s' config: %v", dbName, err)
68 70
 		}
@@ -123,9 +125,9 @@ func (c *DatabaseConfig) Validate() error {
123 125
 
124 126
 // Validate 验证配置(多数据库配置)
125 127
 func (c *DatabasesConfig) Validate() error {
126
-	if c.Databases == nil || len(c.Databases) == 0 {
128
+	if c.Databases == nil {
127 129
 		log.Println("❌ 错误: 未找到任何数据库配置,请检查配置文件中的 'databases' 配置")
128
-		return fmt.Errorf("no database configurations found")
130
+		return fmt.Errorf("no databases configurations found")
129 131
 	}
130 132
 
131 133
 	// 必须要有默认数据库

+ 203
- 24
config/subconfigs/service_config.go View File

@@ -1,49 +1,228 @@
1
+// subconfigs/service_config.go
1 2
 package subconfigs
2 3
 
3
-import "fmt"
4
+import (
5
+	"fmt"
6
+	"log"
7
+)
4 8
 
5
-// ServiceConfig 微服务配置
9
+type ServicesConfig struct {
10
+	BaseConfig
11
+	Services map[string]*ServiceConfig `yaml:"services"`
12
+}
13
+
14
+// DatabaseConfig 数据库配置
6 15
 type ServiceConfig struct {
7 16
 	BaseConfig
8
-	ServiceName    string `yaml:"service_name"`
9
-	ServiceVersion string `yaml:"service_version"`
10
-	ServiceTag     string `yaml:"service_tags"`
11
-	Port           int    `yaml:"port"`
12
-	ReadTimeout    int    `yaml:"read_timeout"`
13
-	WriteTimeout   int    `yaml:"write_timeout"`
14
-	IdleTimeout    int    `yaml:"idle_timeout"`
15
-	TrustedProxies string `yaml:"trusted_proxies"`
16
-	InstanceName   string `yaml:"instance-name"`
17
-	Env            string `yaml:"env"`
17
+	Port         int    `yaml:"port"`
18
+	ServiceName  string `yaml:"service_name"`
19
+	InstanceName string `yaml:"instance_name"`
20
+	ReadTimeout  int    `yaml:"read_timeout"`
21
+	WriteTimeout int    `yaml:"write_timeout"`
22
+	IdleTimeout  int    `yaml:"idle_timeout"`
18 23
 }
19 24
 
20
-func NewServiceConfig() *ServiceConfig {
21
-	return &ServiceConfig{}
25
+// SetDefaults 设置默认值 - 实现 ConfigLoader 接口
26
+func (c *ServicesConfig) SetDefaults() {
27
+	//因为是多集合,外层调这里赋默认值,这个时候对象还没有建立。赋默认值的地方移到其他地方去
22 28
 }
23 29
 
30
+func (c *ServicesConfig) Load(data map[string]interface{}) error {
31
+	// 初始化
32
+	c.Services = make(map[string]*ServiceConfig)
33
+
34
+	// 遍历所有配置
35
+	for dbName, dbData := range data {
36
+		dbDataMap, ok := dbData.(map[interface{}]interface{})
37
+		if !ok {
38
+			return fmt.Errorf("service '%s' config is not a map", dbName)
39
+		}
40
+
41
+		// 转换为 map[string]interface{}
42
+		stringMap := make(map[string]interface{})
43
+		for k, v := range dbDataMap {
44
+			if key, ok := k.(string); ok {
45
+				stringMap[key] = v
46
+			}
47
+		}
48
+
49
+		// 创建 ServiceConfig 对象并设置默认值
50
+		dbConfig := &ServiceConfig{}
51
+		dbConfig.SetDefaults() // 先设置默认值
52
+
53
+		// 加载单个服务配置
54
+		if err := dbConfig.Load(stringMap); err != nil {
55
+			return fmt.Errorf("failed to load servuce '%s' config: %v", dbName, err)
56
+		}
57
+
58
+		c.Services[dbName] = dbConfig
59
+	}
60
+
61
+	// 设置默认值和验证
62
+	//c.SetDefaults()
63
+	return c.Validate()
64
+}
65
+
66
+// SetDefaults 设置默认值 - 实现 ConfigLoader 接口
24 67
 func (c *ServiceConfig) SetDefaults() {
25
-	c.ServiceName = "myService"
26
-	c.Port = 8080
27
-	c.ReadTimeout = 30
28
-	c.WriteTimeout = 30
29
-	c.IdleTimeout = 60
68
+
69
+	if c.Port == 0 {
70
+		c.Port = 8080
71
+	}
72
+	if c.IdleTimeout == 0 {
73
+		c.IdleTimeout = 60
74
+	}
75
+	if c.ReadTimeout == 0 {
76
+		c.ReadTimeout = 30
77
+	}
78
+	if c.WriteTimeout == 0 {
79
+		c.WriteTimeout = 30
80
+	}
30 81
 }
31 82
 
83
+// Load 从yaml数据加载 - 实现 ConfigLoader 接口
32 84
 func (c *ServiceConfig) Load(data map[string]interface{}) error {
85
+	// 虽然可能不会被直接调用,但为了接口完整性还是要实现
33 86
 	return c.LoadFromYAML(data, c)
34 87
 }
35 88
 
89
+// ========== 业务方法 ==========
90
+
91
+// Validate 验证配置(数据库配置)
36 92
 func (c *ServiceConfig) Validate() error {
37
-	if c.ServiceName == "" {
38
-		return fmt.Errorf("service name is required")
39
-	}
93
+
40 94
 	if c.Port <= 0 || c.Port > 65535 {
41
-		return fmt.Errorf("invalid port: %d", c.Port)
95
+		return fmt.Errorf("invalid service port: %d", c.Port)
42 96
 	}
97
+
43 98
 	return nil
44 99
 }
45 100
 
101
+// Validate 验证配置(多数据库配置)
102
+func (c *ServicesConfig) Validate() error {
103
+	if c.Services == nil {
104
+		log.Println("❌ 错误: 未找到任何微服务配置,请检查配置文件中的 'services' 配置")
105
+		return fmt.Errorf("no services configurations found")
106
+	}
107
+
108
+	// 必须要有默认数据库
109
+	if _, exists := c.Services["default"]; !exists {
110
+		availableDBs := c.GetAllServiceNames()
111
+		log.Printf("❌ 错误: 默认微服务配置未找到。可用的微服务配置: %v。请在配置文件中添加 'default' 微服务", availableDBs)
112
+		return fmt.Errorf("default service not found")
113
+	}
114
+
115
+	// 验证每个数据库配置
116
+	for name, db := range c.Services {
117
+		if db == nil {
118
+			log.Printf("❌ 错误: 微服务 '%s' 配置为空", name)
119
+			return fmt.Errorf("service '%s' configuration is nil", name)
120
+		}
121
+
122
+		if err := db.Validate(); err != nil {
123
+			log.Printf("❌ 错误: 微服务 '%s' 验证失败: %v", name, err)
124
+			return fmt.Errorf("service '%s' validation failed: %v", name, err)
125
+		}
126
+	}
127
+
128
+	log.Printf("✅ 微服务配置验证通过,找到 %d 个微服务配置", len(c.Services))
129
+	return nil
130
+}
131
+
132
+// IsConfigured 判断是否已配置(数据库配置)
133
+func (c *ServiceConfig) IsConfigured() bool {
134
+
135
+	if c.Port <= 0 {
136
+		log.Println("⚠️  警告: 微服务 Port 未配置或无效")
137
+		return false
138
+	}
139
+
140
+	return true
141
+}
142
+
143
+// IsConfigured 判断是否已配置(多数据库配置)
144
+func (c *ServicesConfig) IsConfigured() bool {
145
+	defaultDB := c.GetDefaultService()
146
+	if defaultDB == nil {
147
+		log.Println("❌ 错误: 默认微服务不存在")
148
+		return false
149
+	}
150
+
151
+	if !defaultDB.IsConfigured() {
152
+		log.Println("❌ 错误: 默认微服务配置不完整")
153
+		return false
154
+	}
155
+
156
+	return true
157
+}
158
+
159
+// GetDefaultService 获取默认微服务(必须存在)
160
+func (c *ServicesConfig) GetDefaultService() *ServiceConfig {
161
+	if c.Services == nil {
162
+		log.Println("❌ 错误: 尝试获取默认微服务时,微服务配置为空")
163
+		return nil
164
+	}
165
+
166
+	if db, exists := c.Services["default"]; exists {
167
+		return db
168
+	}
169
+
170
+	// 如果没有名为default的,尝试返回第一个(但会记录警告)
171
+	for name, db := range c.Services {
172
+		log.Printf("⚠️  警告: 未找到名为 'default' 的微服务,使用第一个微服务 '%s' 作为默认", name)
173
+		return db
174
+	}
175
+
176
+	log.Println("❌ 错误: 服务模块配置中没有任何配置")
177
+	return nil
178
+}
179
+
180
+// GetService 按名称获取微服务(为空时记录错误)
181
+func (c *ServicesConfig) GetService(name string) *ServiceConfig {
182
+	if c.Services == nil {
183
+		log.Printf("❌ 错误: 尝试获取微服务 '%s' 时,微服务配置为空", name)
184
+		return nil
185
+	}
186
+
187
+	db := c.Services[name]
188
+	if db == nil {
189
+		availableDBs := c.GetAllServiceNames()
190
+		log.Printf("❌ 错误: 微服务 '%s' 不存在。可用的微服务: %v", name, availableDBs)
191
+	}
192
+
193
+	return db
194
+}
195
+
196
+// GetAllServiceNames 获取所有数据库名称
197
+func (c *ServicesConfig) GetAllServiceNames() []string {
198
+	if c.Services == nil {
199
+		log.Println("⚠️  警告: 尝试获取微服务配置节点名称时,微服务配置为空")
200
+		return []string{}
201
+	}
202
+
203
+	names := make([]string, 0, len(c.Services))
204
+	for name := range c.Services {
205
+		names = append(names, name)
206
+	}
207
+	return names
208
+}
209
+
210
+// GetServiceNamesWithoutDefault 获取除default外的所有微服务配置节点名称
211
+func (c *ServicesConfig) GetServiceNamesWithoutDefault() []string {
212
+	if c.Services == nil {
213
+		return []string{}
214
+	}
215
+
216
+	names := make([]string, 0, len(c.Services)-1)
217
+	for name := range c.Services {
218
+		if name != "default" {
219
+			names = append(names, name)
220
+		}
221
+	}
222
+	return names
223
+}
224
+
46 225
 // 自动注册
47 226
 func init() {
48
-	Register("service", &ServiceConfig{})
227
+	Register("services", &ServicesConfig{})
49 228
 }

+ 0
- 103
myservice/start_service.go View File

@@ -1,103 +0,0 @@
1
-package myservice
2
-
3
-import (
4
-	"fmt"
5
-	"log"
6
-	"time"
7
-
8
-	"git.x2erp.com/qdy/go-base/config"
9
-	"github.com/go-micro/plugins/v4/registry/consul"
10
-	"github.com/urfave/cli/v2"
11
-	"go-micro.dev/v4/registry"
12
-	"go-micro.dev/v4/web"
13
-)
14
-
15
-// StartWithRegistry starts microservice with registry (e.g., Consul)
16
-func StartWithRegistry(cfg config.IConfig) web.Service {
17
-	// Get service information from config
18
-	serviceConfig := cfg.GetService()
19
-	microConfig := cfg.GetMicro()
20
-
21
-	// 1. Create Consul registry
22
-	consulRegistry := consul.NewRegistry(
23
-		registry.Addrs(microConfig.RegistryAddress),
24
-	)
25
-
26
-	// 2. Create HTTP web service (for external HTTP access)
27
-	service := web.NewService(
28
-		web.Name(serviceConfig.ServiceName),
29
-		web.Version(serviceConfig.ServiceVersion),
30
-		web.Address(fmt.Sprintf(":%d", serviceConfig.Port)),
31
-		web.Registry(consulRegistry),
32
-		web.RegisterTTL(30*time.Second),      // Health check interval
33
-		web.RegisterInterval(20*time.Second), // Registration interval
34
-		web.Flags(&cli.StringFlag{
35
-			Name:  "env",
36
-			Value: "dev",
37
-			Usage: "环境参数"}),
38
-		web.Action(func(c *cli.Context) {
39
-			cfg.SetEnv(c.String("env"))
40
-			log.Printf("环境参数: %s\n", serviceConfig.Env)
41
-		}),
42
-	)
43
-
44
-	// 3. Initialize service
45
-	service.Init()
46
-
47
-	log.Printf("Microservice started (with registry)")
48
-	log.Printf("   • Service name: %s", serviceConfig.ServiceName)
49
-	log.Printf("   • Version: %s", serviceConfig.ServiceVersion)
50
-	log.Printf("   • Port: %d", serviceConfig.Port)
51
-	log.Printf("   • Registry: %s", microConfig.RegistryAddress)
52
-	log.Printf("   • IdleTimeout: %d秒", serviceConfig.IdleTimeout)
53
-	log.Printf("   • ReadTimeout: %d秒", serviceConfig.ReadTimeout)
54
-	log.Printf("   • WriteTimeout: %d秒", serviceConfig.WriteTimeout)
55
-
56
-	// // Run in background
57
-	// go func() {
58
-	// 	if err := service.Run(); err != nil {
59
-	// 		log.Printf("Microservice stopped: %v", err)
60
-	// 	}
61
-	// }()
62
-
63
-	return service
64
-}
65
-
66
-// StartStandalone starts standalone microservice (not registered to registry)
67
-func StartStandalone(cfg config.IConfig) web.Service {
68
-	// Get service information from config
69
-	serviceConfig := cfg.GetService()
70
-
71
-	// Create HTTP web service (standalone operation)
72
-	service := web.NewService(
73
-		web.Name(serviceConfig.ServiceName),
74
-		web.Version(serviceConfig.ServiceVersion),
75
-		web.Address(fmt.Sprintf(":%d", serviceConfig.Port)),
76
-		// No Registry specified = standalone service
77
-	)
78
-
79
-	// Initialize service
80
-	if err := service.Init(); err != nil {
81
-		log.Fatalf("Service init failed: %v", err)
82
-	}
83
-
84
-	log.Printf("Standalone microservice started")
85
-	log.Printf("	• Service name: %s", serviceConfig.ServiceName)
86
-	log.Printf("	• Version: %s", serviceConfig.ServiceVersion)
87
-	log.Printf("	• Port: %d", serviceConfig.Port)
88
-	log.Printf("	• Mode: Standalone (no service discovery)")
89
-
90
-	// // Run in background
91
-	// go func() {
92
-	// 	if err := service.Run(); err != nil {
93
-	// 		log.Printf("Microservice stopped: %v", err)
94
-	// 	}
95
-	// }()
96
-
97
-	return service
98
-}
99
-
100
-// Start maintains compatibility with original interface, uses registry version by default
101
-func Start(cfg config.IConfig) web.Service {
102
-	return StartWithRegistry(cfg)
103
-}

Loading…
Cancel
Save