Bladeren bron

添加注册中心代码,注册到consul

qdy 2 maanden geleden
bovenliggende
commit
f2a3673ad7
6 gewijzigde bestanden met toevoegingen van 425 en 38 verwijderingen
  1. 45
    29
      bootstraps/bootstrap.go
  2. 73
    0
      client/ip_resolver.go
  3. 161
    0
      client/service_client.go
  4. 26
    9
      config/config.go
  5. 40
    0
      config/subconfigs/consul_config.go
  6. 80
    0
      consul/register_consul.go

+ 45
- 29
bootstraps/bootstrap.go Bestand weergeven

@@ -10,8 +10,9 @@ import (
10 10
 	"syscall"
11 11
 	"time"
12 12
 
13
+	"git.x2erp.com/qdy/go-base/client"
13 14
 	"git.x2erp.com/qdy/go-base/config"
14
-	"git.x2erp.com/qdy/go-base/config/subconfigs"
15
+	"git.x2erp.com/qdy/go-base/consul"
15 16
 	"git.x2erp.com/qdy/go-base/logger"
16 17
 )
17 18
 
@@ -23,11 +24,12 @@ type ShutdownHandler interface {
23 24
 // WebService Web服务实例
24 25
 type WebService struct {
25 26
 	serviceName     string
26
-	serviceConfig   *subconfigs.ServiceConfig
27 27
 	HttpServer      *http.Server
28 28
 	Router          *http.ServeMux
29 29
 	quit            chan os.Signal
30 30
 	shutdownHandler ShutdownHandler
31
+	Port            int
32
+	Ip              string
31 33
 }
32 34
 
33 35
 // Bootstrapper 服务启动器
@@ -78,21 +80,24 @@ func (b *Bootstrapper) init() *Bootstrapper {
78 80
 }
79 81
 
80 82
 // CreateService 创建Web服务实例
81
-func (b *Bootstrapper) CreateService(serviceName string) *WebService {
82
-	serviceCfg := b.Cfg.GetServiceConfig(serviceName)
83
+func (b *Bootstrapper) createService(yamlNode string) *WebService {
84
+
85
+	serviceCfg := b.Cfg.GetServiceConfig(yamlNode)
83 86
 
84 87
 	// 检查是否已存在同名服务
85
-	if _, exists := b.services[serviceName]; exists {
86
-		logger.Debug("服务 %s 已存在,将返回现有实例", serviceName)
87
-		return b.services[serviceName]
88
+	if _, exists := b.services[yamlNode]; exists {
89
+		logger.Debug("服务 %s 已存在,将返回现有实例", yamlNode)
90
+		return b.services[yamlNode]
88 91
 	}
89 92
 
93
+	io := client.GetServiceIP("")
90 94
 	// 创建新的服务实例
91 95
 	ws := &WebService{
92
-		serviceName:   serviceName,
93
-		serviceConfig: serviceCfg,
94
-		Router:        http.NewServeMux(),
95
-		quit:          make(chan os.Signal, 1),
96
+		serviceName: serviceCfg.ServiceName,
97
+		Router:      http.NewServeMux(),
98
+		quit:        make(chan os.Signal, 1),
99
+		Port:        serviceCfg.Port,
100
+		Ip:          io,
96 101
 	}
97 102
 
98 103
 	// 创建HTTP服务器
@@ -105,7 +110,7 @@ func (b *Bootstrapper) CreateService(serviceName string) *WebService {
105 110
 	}
106 111
 
107 112
 	// 存储服务实例
108
-	b.services[serviceName] = ws
113
+	b.services[yamlNode] = ws
109 114
 
110 115
 	logger.Debug("已创建服务实例: %s (端口: %d)", serviceCfg.ServiceName, serviceCfg.Port)
111 116
 
@@ -118,14 +123,13 @@ func (b *Bootstrapper) GetAllServices() map[string]*WebService {
118 123
 }
119 124
 
120 125
 // StartService 启动指定服务
121
-func (b *Bootstrapper) StartService(serviceName string) *Bootstrapper {
126
+func (b *Bootstrapper) StartService(yamlNode string) *Bootstrapper {
122 127
 
123
-	service := b.CreateService(serviceName)
128
+	service := b.createService(yamlNode)
124 129
 
125
-	serviceCfg := service.serviceConfig
126
-	log.Printf("正在启动服务: %s ", serviceCfg.ServiceName)
130
+	log.Printf("正在启动服务: %s ", service.serviceName)
127 131
 	log.Printf("模式: 独立运行 (net/http)")
128
-	log.Printf("服务端口: :%d", serviceCfg.Port)
132
+	log.Printf("服务端口: :%d", service.Port)
129 133
 
130 134
 	return b
131 135
 }
@@ -144,6 +148,9 @@ func (b *Bootstrapper) Run(shutdownHandler ShutdownHandler) {
144 148
 	// 启动所有服务
145 149
 	for serviceName, service := range b.services {
146 150
 		go func(name string, ws *WebService) {
151
+
152
+			consul.Register(service.serviceName, service.Ip, service.Port, b.Cfg.GetConsulConfig())
153
+
147 154
 			log.Printf("启动服务 %s 在 %s", name, ws.HttpServer.Addr)
148 155
 			if err := ws.HttpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
149 156
 				log.Fatalf("服务 %s 运行失败: %v", name, err)
@@ -156,10 +163,10 @@ func (b *Bootstrapper) Run(shutdownHandler ShutdownHandler) {
156 163
 }
157 164
 
158 165
 // RunSingle 运行单个服务
159
-func (b *Bootstrapper) RunSingle(serviceName string, shutdownHandler ShutdownHandler) {
160
-	service := b.CreateService(serviceName)
166
+func (b *Bootstrapper) RunSingle(yamlNode string, shutdownHandler ShutdownHandler) {
167
+	service := b.createService(yamlNode)
161 168
 
162
-	log.Printf("服务 %s 开始运行...", service.serviceConfig.ServiceName)
169
+	log.Printf("服务 %s 开始运行...", service.serviceName)
163 170
 
164 171
 	// 设置服务级别的信号监听
165 172
 	signal.Notify(service.quit, syscall.SIGINT, syscall.SIGTERM)
@@ -172,15 +179,17 @@ func (b *Bootstrapper) RunSingle(serviceName string, shutdownHandler ShutdownHan
172 179
 		}
173 180
 	}()
174 181
 
182
+	consul.Register(service.serviceName, service.Ip, service.Port, b.Cfg.GetConsulConfig())
183
+
175 184
 	// 等待中断信号
176 185
 	b.waitForServiceShutdown(service, shutdownHandler)
177 186
 }
178 187
 
179 188
 // RunTLS 运行HTTPS服务
180 189
 func (b *Bootstrapper) RunTLS(serviceName, certFile, keyFile string, shutdownHandler ShutdownHandler) {
181
-	service := b.CreateService(serviceName)
190
+	service := b.createService(serviceName)
182 191
 
183
-	log.Printf("服务 %s 开始运行(HTTPS)...", service.serviceConfig.ServiceName)
192
+	log.Printf("服务 %s 开始运行(HTTPS)...", service.serviceName)
184 193
 
185 194
 	// 设置服务级别的信号监听
186 195
 	signal.Notify(service.quit, syscall.SIGINT, syscall.SIGTERM)
@@ -215,6 +224,9 @@ func (b *Bootstrapper) waitForShutdown(handler ShutdownHandler) {
215 224
 	for serviceName, service := range b.services {
216 225
 		go func(name string, ws *WebService) {
217 226
 			log.Printf("正在关闭服务: %s", name)
227
+			//退出注册中心
228
+			consul.Deregister(service.serviceName, service.Ip, service.Port)
229
+
218 230
 			if err := ws.HttpServer.Shutdown(ctx); err != nil {
219 231
 				log.Printf("服务 %s 关闭失败: %v", name, err)
220 232
 			} else {
@@ -245,12 +257,16 @@ func (b *Bootstrapper) waitForShutdown(handler ShutdownHandler) {
245 257
 
246 258
 // waitForServiceShutdown 等待单个服务关闭
247 259
 func (b *Bootstrapper) waitForServiceShutdown(service *WebService, handler ShutdownHandler) {
260
+
248 261
 	log.Printf("按 Ctrl+C 停止服务 %s", service.serviceName)
249 262
 
250 263
 	// 等待信号
251 264
 	<-service.quit
252 265
 	log.Printf("接收到终止信号,正在优雅关闭服务 %s...", service.serviceName)
253 266
 
267
+	//退出注册中心
268
+	consul.Deregister(service.serviceName, service.Ip, service.Port)
269
+
254 270
 	// 创建关闭上下文,给30秒完成当前请求
255 271
 	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
256 272
 	defer cancel()
@@ -282,8 +298,8 @@ func (b *Bootstrapper) GetConfig() config.IConfig {
282 298
 }
283 299
 
284 300
 // GetRouter 获取指定服务的路由器
285
-func (b *Bootstrapper) GetRouter(serviceName string) *http.ServeMux {
286
-	service := b.CreateService(serviceName)
301
+func (b *Bootstrapper) GetRouter(yamlNode string) *http.ServeMux {
302
+	service := b.createService(yamlNode)
287 303
 	return service.Router
288 304
 }
289 305
 
@@ -322,10 +338,10 @@ func (ws *WebService) GetServiceName() string {
322 338
 	return ws.serviceName
323 339
 }
324 340
 
325
-// GetServiceConfig 获取服务配置
326
-func (ws *WebService) GetServiceConfig() *subconfigs.ServiceConfig {
327
-	return ws.serviceConfig
328
-}
341
+// // GetServiceConfig 获取服务配置
342
+// func (ws *WebService) GetServiceConfig() *subconfigs.ServiceConfig {
343
+// 	return ws.serviceConfig
344
+// }
329 345
 
330 346
 // GetRouter 获取服务的路由器
331 347
 func (ws *WebService) GetRouter() *http.ServeMux {
@@ -344,7 +360,7 @@ func (ws *WebService) SetShutdownHandler(handler ShutdownHandler) {
344 360
 
345 361
 // Run 运行单个服务
346 362
 func (ws *WebService) Run(shutdownHandler ShutdownHandler) {
347
-	log.Printf("服务 %s 开始运行...", ws.serviceConfig.ServiceName)
363
+	log.Printf("服务 %s 开始运行...", ws.serviceName)
348 364
 
349 365
 	// 设置信号监听
350 366
 	signal.Notify(ws.quit, syscall.SIGINT, syscall.SIGTERM)

+ 73
- 0
client/ip_resolver.go Bestand weergeven

@@ -0,0 +1,73 @@
1
+// ip_resolver.go
2
+package client
3
+
4
+import (
5
+	"net"
6
+	"os"
7
+	"strings"
8
+)
9
+
10
+// func main() {
11
+// 	// 1. 用户可以在yaml配置:hostname: "192.168.3.190" 或 "kendemacbook-air.local"
12
+// 	// 2. 如果不配置,自动获取
13
+// 	yamlHostname := "" // "kendemacbook-air.local" // 从yaml读取,可以设为空、IP或主机名
14
+
15
+// 	ip := GetIP(yamlHostname)
16
+// 	fmt.Printf("服务IP: %s\n", ip)
17
+// }
18
+
19
+// GetIP 获取IP地址  configHostname 主机名称或者ip地址
20
+func GetServiceIP(configHostname string) string {
21
+	// 1. 如果yaml配置了,直接用
22
+	if configHostname != "" {
23
+		return parseToIP(configHostname)
24
+	}
25
+
26
+	// 2. 获取主机名(这很少出错)
27
+	hostname, _ := os.Hostname()
28
+
29
+	// 3. 解析为IP
30
+	return parseToIP(hostname)
31
+}
32
+
33
+// parseToIP 解析为IP(可以是IP或主机名)
34
+func parseToIP(address string) string {
35
+	// 如果本来就是IP,直接返回
36
+	if ip := net.ParseIP(address); ip != nil {
37
+		return ip.String()
38
+	}
39
+
40
+	// 是主机名,加上.local后缀
41
+	if !strings.Contains(address, ".") {
42
+		address = address + ".local"
43
+	}
44
+
45
+	// 解析DNS
46
+	ips, err := net.LookupHost(address)
47
+	if err != nil || len(ips) == 0 {
48
+		return getSimpleIP()
49
+	}
50
+
51
+	// 取第一个非127.0.0.1的IPv4
52
+	for _, ip := range ips {
53
+		if ip == "127.0.0.1" || ip == "::1" {
54
+			continue
55
+		}
56
+		if parsedIP := net.ParseIP(ip); parsedIP != nil && parsedIP.To4() != nil {
57
+			return ip
58
+		}
59
+	}
60
+
61
+	// 没有合适的,返回第一个
62
+	return ips[0]
63
+}
64
+
65
+// getSimpleIP 最简单的获取本机IP方法
66
+func getSimpleIP() string {
67
+	conn, err := net.Dial("udp", "8.8.8.8:80")
68
+	if err != nil {
69
+		return "127.0.0.1"
70
+	}
71
+	defer conn.Close()
72
+	return conn.LocalAddr().(*net.UDPAddr).IP.String()
73
+}

+ 161
- 0
client/service_client.go Bestand weergeven

@@ -0,0 +1,161 @@
1
+package client
2
+
3
+import (
4
+	"bytes"
5
+	"encoding/json"
6
+	"errors"
7
+	"io"
8
+	"net/http"
9
+	"strconv"
10
+	"sync"
11
+	"time"
12
+
13
+	"github.com/hashicorp/consul/api"
14
+)
15
+
16
+var (
17
+	balancer *ServiceBalancer
18
+	once     sync.Once
19
+)
20
+
21
+type ServiceBalancer struct {
22
+	mu         sync.RWMutex
23
+	services   map[string][]string
24
+	indexes    map[string]int
25
+	consulAddr string
26
+}
27
+
28
+// Init 初始化客户端,传入Consul地址
29
+func Init(consulAddr string) {
30
+	once.Do(func() {
31
+		balancer = &ServiceBalancer{
32
+			services:   make(map[string][]string),
33
+			indexes:    make(map[string]int),
34
+			consulAddr: consulAddr,
35
+		}
36
+		go balancer.watchConsul()
37
+	})
38
+}
39
+
40
+func (s *ServiceBalancer) watchConsul() {
41
+	config := api.DefaultConfig()
42
+	config.Address = s.consulAddr
43
+	client, _ := api.NewClient(config)
44
+
45
+	for {
46
+		s.mu.Lock()
47
+		services, _, _ := client.Health().Service("", "", true, nil)
48
+
49
+		// 清空旧数据
50
+		s.services = make(map[string][]string)
51
+
52
+		for _, entry := range services {
53
+			service := entry.Service.Service
54
+			addr := entry.Service.Address + ":" + strconv.Itoa(entry.Service.Port)
55
+
56
+			// 使用map去重
57
+			if s.services[service] == nil {
58
+				s.services[service] = []string{}
59
+			}
60
+
61
+			// 检查是否已存在
62
+			exists := false
63
+			for _, existingAddr := range s.services[service] {
64
+				if existingAddr == addr {
65
+					exists = true
66
+					break
67
+				}
68
+			}
69
+			if !exists {
70
+				s.services[service] = append(s.services[service], addr)
71
+			}
72
+		}
73
+		s.mu.Unlock()
74
+
75
+		time.Sleep(10 * time.Second)
76
+	}
77
+}
78
+
79
+func (s *ServiceBalancer) GetServiceAddr(service string) string {
80
+	s.mu.RLock()
81
+	defer s.mu.RUnlock()
82
+
83
+	addrs := s.services[service]
84
+	if len(addrs) == 0 {
85
+		return ""
86
+	}
87
+
88
+	idx := s.indexes[service]
89
+	addr := addrs[idx]
90
+	s.indexes[service] = (idx + 1) % len(addrs)
91
+
92
+	return addr
93
+}
94
+
95
+func Get(service, path string, result interface{}) error {
96
+	if balancer == nil {
97
+		return errors.New("client not initialized, call client.Init() first")
98
+	}
99
+
100
+	baseURL := balancer.GetServiceAddr(service)
101
+	if baseURL == "" {
102
+		return errors.New("service unavailable")
103
+	}
104
+
105
+	resp, err := http.Get("http://" + baseURL + path)
106
+	if err != nil {
107
+		return err
108
+	}
109
+	defer resp.Body.Close()
110
+
111
+	if resp.StatusCode != http.StatusOK {
112
+		return errors.New("HTTP error: " + resp.Status)
113
+	}
114
+
115
+	body, err := io.ReadAll(resp.Body)
116
+	if err != nil {
117
+		return err
118
+	}
119
+
120
+	return json.Unmarshal(body, result)
121
+}
122
+
123
+func Post(service, path string, body, result interface{}) error {
124
+	if balancer == nil {
125
+		return errors.New("client not initialized, call client.Init() first")
126
+	}
127
+
128
+	baseURL := balancer.GetServiceAddr(service)
129
+	if baseURL == "" {
130
+		return errors.New("service unavailable")
131
+	}
132
+
133
+	jsonBytes, err := json.Marshal(body)
134
+	if err != nil {
135
+		return err
136
+	}
137
+
138
+	resp, err := http.Post(
139
+		"http://"+baseURL+path,
140
+		"application/json",
141
+		bytes.NewBuffer(jsonBytes),
142
+	)
143
+	if err != nil {
144
+		return err
145
+	}
146
+	defer resp.Body.Close()
147
+
148
+	if resp.StatusCode != http.StatusOK {
149
+		return errors.New("HTTP error: " + resp.Status)
150
+	}
151
+
152
+	respBody, err := io.ReadAll(resp.Body)
153
+	if err != nil {
154
+		return err
155
+	}
156
+
157
+	if result != nil {
158
+		return json.Unmarshal(respBody, result)
159
+	}
160
+	return nil
161
+}

+ 26
- 9
config/config.go Bestand weergeven

@@ -20,9 +20,11 @@ type IConfig interface {
20 20
 	GetServiceConfig(name string) *subconfigs.ServiceConfig //获取微服务配置
21 21
 
22 22
 	// 其他配置(保持不变)
23
-	GetRedis() *subconfigs.RedisConfig
24
-	GetDoris() *subconfigs.DorisConfig
25
-	GetRabbitMQ() *subconfigs.RabbitMQConfig
23
+	GetRedisConfig() *subconfigs.RedisConfig
24
+	GetDorisConfig() *subconfigs.DorisConfig
25
+	GetRabbitMQConfig() *subconfigs.RabbitMQConfig
26
+
27
+	GetConsulConfig() *subconfigs.ConsulConfig
26 28
 
27 29
 	GetHTTP() *subconfigs.HTTPConfig
28 30
 	GetMicro() *subconfigs.MicroConfig
@@ -101,21 +103,28 @@ func (c *Config) IsDatabaseConfiguredByName(name string) bool {
101 103
 
102 104
 // ========== 其他配置方法(保持不变) ==========
103 105
 
104
-func (c *Config) GetRedis() *subconfigs.RedisConfig {
106
+func (c *Config) GetRedisConfig() *subconfigs.RedisConfig {
105 107
 	if config := subconfigs.GetRegisteredConfig("redis"); config != nil {
106 108
 		return config.(*subconfigs.RedisConfig)
107 109
 	}
108 110
 	return nil
109 111
 }
110 112
 
111
-func (c *Config) GetDoris() *subconfigs.DorisConfig {
113
+func (c *Config) GetConsulConfig() *subconfigs.ConsulConfig {
114
+	if config := subconfigs.GetRegisteredConfig("consul"); config != nil {
115
+		return config.(*subconfigs.ConsulConfig)
116
+	}
117
+	return nil
118
+}
119
+
120
+func (c *Config) GetDorisConfig() *subconfigs.DorisConfig {
112 121
 	if config := subconfigs.GetRegisteredConfig("doris"); config != nil {
113 122
 		return config.(*subconfigs.DorisConfig)
114 123
 	}
115 124
 	return nil
116 125
 }
117 126
 
118
-func (c *Config) GetRabbitMQ() *subconfigs.RabbitMQConfig {
127
+func (c *Config) GetRabbitMQConfig() *subconfigs.RabbitMQConfig {
119 128
 	if config := subconfigs.GetRegisteredConfig("rabbitmq"); config != nil {
120 129
 		return config.(*subconfigs.RabbitMQConfig)
121 130
 	}
@@ -180,12 +189,12 @@ func (c *Config) GetInitError() error {
180 189
 
181 190
 // 实现 IConfig 接口的其他方法
182 191
 func (c *Config) IsDorisConfigured() bool {
183
-	doris := c.GetDoris()
192
+	doris := c.GetDorisConfig()
184 193
 	return doris != nil && doris.IsConfigured()
185 194
 }
186 195
 
187 196
 func (c *Config) IsRedisConfigured() bool {
188
-	redis := c.GetRedis()
197
+	redis := c.GetRedisConfig()
189 198
 	return redis != nil && redis.IsConfigured()
190 199
 }
191 200
 
@@ -258,7 +267,15 @@ func GetRedis() *subconfigs.RedisConfig {
258 267
 	if cfgInstance == nil {
259 268
 		return &subconfigs.RedisConfig{}
260 269
 	}
261
-	return cfgInstance.GetRedis()
270
+	return cfgInstance.GetRedisConfig()
271
+}
272
+
273
+// GetRedis 包级便捷函数 - 获取Redis配置
274
+func GetConsul() *subconfigs.ConsulConfig {
275
+	if cfgInstance == nil {
276
+		return &subconfigs.ConsulConfig{}
277
+	}
278
+	return cfgInstance.GetConsulConfig()
262 279
 }
263 280
 
264 281
 // GetHTTP 包级便捷函数 - 获取HTTP配置

+ 40
- 0
config/subconfigs/consul_config.go Bestand weergeven

@@ -0,0 +1,40 @@
1
+package subconfigs
2
+
3
+import "fmt"
4
+
5
+// Config Consul客户端配置
6
+type ConsulConfig struct {
7
+	BaseConfig
8
+	Address string `yaml:"address"` // Consul服务器地址,如:"localhost:8500"
9
+	Token   string `yaml:"token"`   // ACL token(可选)
10
+	Scheme  string `yaml:"scheme"`  // "http" 或 "https"
11
+}
12
+
13
+func NewConsulConfig() *ConsulConfig {
14
+	return &ConsulConfig{}
15
+}
16
+
17
+func (c *ConsulConfig) SetDefaults() {
18
+	c.Address = "localhost:8500"
19
+	c.Scheme = "http"
20
+}
21
+
22
+func (c *ConsulConfig) Load(data map[string]interface{}) error {
23
+	return c.LoadFromYAML(data, c)
24
+}
25
+
26
+func (c *ConsulConfig) Validate() error {
27
+	if c.Address == "" {
28
+		return fmt.Errorf("consul address must be configured")
29
+	}
30
+	return nil
31
+}
32
+
33
+func (c *ConsulConfig) IsConfigured() bool {
34
+	return c.Address != ""
35
+}
36
+
37
+// 自动注册
38
+func init() {
39
+	Register("consul", &ConsulConfig{})
40
+}

+ 80
- 0
consul/register_consul.go Bestand weergeven

@@ -0,0 +1,80 @@
1
+// consul/register.go
2
+package consul
3
+
4
+import (
5
+	"fmt"
6
+	"log"
7
+
8
+	"git.x2erp.com/qdy/go-base/client"
9
+	"git.x2erp.com/qdy/go-base/config/subconfigs"
10
+	"github.com/hashicorp/consul/api"
11
+)
12
+
13
+// Register 注册服务到Consul
14
+func Register(serviceName, configHostname string, port int, consulConfig *subconfigs.ConsulConfig) error {
15
+	// 1. 获取IP
16
+	ip := client.GetServiceIP(configHostname)
17
+	log.Printf("注册服务 %s -> %s:%d 到 %s", serviceName, ip, port, consulConfig.Address)
18
+
19
+	// 2. 创建Consul客户端配置
20
+	apiConfig := api.DefaultConfig()
21
+	if consulConfig.Address != "" {
22
+		apiConfig.Address = consulConfig.Address
23
+	}
24
+	if consulConfig.Token != "" {
25
+		apiConfig.Token = consulConfig.Token
26
+	}
27
+	if consulConfig.Scheme != "" {
28
+		apiConfig.Scheme = consulConfig.Scheme
29
+	}
30
+
31
+	// 3. 创建客户端
32
+	client, err := api.NewClient(apiConfig)
33
+	if err != nil {
34
+		return fmt.Errorf("创建Consul客户端失败: %v", err)
35
+	}
36
+
37
+	// 4. 注册服务
38
+	registration := &api.AgentServiceRegistration{
39
+		ID:      fmt.Sprintf("%s-%s-%d", serviceName, ip, port),
40
+		Name:    serviceName,
41
+		Address: ip,
42
+		Port:    port,
43
+		Check: &api.AgentServiceCheck{
44
+			HTTP:     fmt.Sprintf("http://%s:%d/health", ip, port),
45
+			Interval: "10s",
46
+		},
47
+	}
48
+
49
+	err = client.Agent().ServiceRegister(registration)
50
+	if err != nil {
51
+		return fmt.Errorf("consul注册失败: %v", err)
52
+	}
53
+
54
+	log.Printf("✅ 服务已注册到Consul服务器: %s", consulConfig.Address)
55
+	return nil
56
+}
57
+
58
+// Deregister 注销服务
59
+// Deregister 注销服务
60
+func Deregister(serviceName, ip string, port int) {
61
+	// 获取IP
62
+	//ip := netutil.GetServiceIP(configHostname)
63
+	serviceID := fmt.Sprintf("%s-%s-%d", serviceName, ip, port)
64
+
65
+	// 创建客户端
66
+	client, err := api.NewClient(api.DefaultConfig())
67
+	if err != nil {
68
+		log.Printf("创建consul客户端失败: %v", err)
69
+		return
70
+	}
71
+
72
+	// 注销服务
73
+	err = client.Agent().ServiceDeregister(serviceID)
74
+	if err != nil {
75
+		log.Printf("从consul注销服务失败 (ID: %s): %v", serviceID, err)
76
+		return
77
+	}
78
+
79
+	log.Printf("✅ 已从consul注销服务: %s", serviceID)
80
+}

Laden…
Annuleren
Opslaan