forked from go-kratos/kratos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
register.go
148 lines (128 loc) · 4.09 KB
/
register.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package eureka
import (
"context"
"fmt"
"strconv"
"strings"
"time"
"github.com/go-kratos/kratos/v2/registry"
)
var (
_ registry.Registrar = (*Registry)(nil)
_ registry.Discovery = (*Registry)(nil)
)
type Option func(o *Registry)
// WithContext with registry context.
func WithContext(ctx context.Context) Option {
return func(o *Registry) { o.ctx = ctx }
}
func WithHeartbeat(interval time.Duration) Option {
return func(o *Registry) { o.heartbeatInterval = interval }
}
func WithRefresh(interval time.Duration) Option {
return func(o *Registry) { o.refreshInterval = interval }
}
func WithEurekaPath(path string) Option {
return func(o *Registry) { o.eurekaPath = path }
}
func WithIpAsHostname(ipAsHostname bool) Option {
return func(o *Registry) { o.ipAsHostname = ipAsHostname }
}
type Registry struct {
ctx context.Context
api *API
heartbeatInterval time.Duration
refreshInterval time.Duration
eurekaPath string
ipAsHostname bool
}
func New(eurekaUrls []string, opts ...Option) (*Registry, error) {
r := &Registry{
ctx: context.Background(),
heartbeatInterval: heartbeatTime,
refreshInterval: refreshTime,
eurekaPath: "eureka/v2",
}
for _, o := range opts {
o(r)
}
client := NewClient(eurekaUrls, WithHeartbeatInterval(r.heartbeatInterval), WithClientContext(r.ctx), WithNamespace(r.eurekaPath), WithIpAsHostName(r.ipAsHostname))
r.api = NewAPI(r.ctx, client, r.refreshInterval)
return r, nil
}
// Register 这里的Context是每个注册器独享的
func (r *Registry) Register(ctx context.Context, service *registry.ServiceInstance) error {
return r.api.Register(ctx, service.Name, r.Endpoints(service)...)
}
// Deregister registry service to zookeeper.
func (r *Registry) Deregister(ctx context.Context, service *registry.ServiceInstance) error {
return r.api.Deregister(ctx, r.Endpoints(service))
}
// GetService get services from zookeeper
func (r *Registry) GetService(ctx context.Context, serviceName string) ([]*registry.ServiceInstance, error) {
instances := r.api.GetService(ctx, serviceName)
items := make([]*registry.ServiceInstance, 0, len(instances))
for _, instance := range instances {
items = append(items, ®istry.ServiceInstance{
ID: instance.Metadata["ID"],
Name: instance.Metadata["Name"],
Version: instance.Metadata["Version"],
Endpoints: []string{instance.Metadata["Endpoints"]},
Metadata: instance.Metadata,
})
}
return items, nil
}
// Watch 是独立的ctx
func (r *Registry) Watch(ctx context.Context, serviceName string) (registry.Watcher, error) {
return newWatch(ctx, r.api, serviceName)
}
func (r *Registry) Endpoints(service *registry.ServiceInstance) []Endpoint {
res := make([]Endpoint, 0, len(service.Endpoints))
for _, ep := range service.Endpoints {
start := strings.Index(ep, "//")
end := strings.LastIndex(ep, ":")
appID := strings.ToUpper(service.Name)
ip := ep[start+2 : end]
sport := ep[end+1:]
port, _ := strconv.Atoi(sport)
securePort := 443
homePageURL := fmt.Sprintf("%s/", ep)
statusPageURL := fmt.Sprintf("%s/info", ep)
healthCheckURL := fmt.Sprintf("%s/health", ep)
instanceID := strings.Join([]string{ip, appID, sport}, ":")
metadata := make(map[string]string)
if len(service.Metadata) > 0 {
metadata = service.Metadata
}
if s, ok := service.Metadata["securePort"]; ok {
securePort, _ = strconv.Atoi(s)
}
if s, ok := service.Metadata["homePageURL"]; ok {
homePageURL = s
}
if s, ok := service.Metadata["statusPageURL"]; ok {
statusPageURL = s
}
if s, ok := service.Metadata["healthCheckURL"]; ok {
healthCheckURL = s
}
metadata["ID"] = service.ID
metadata["Name"] = service.Name
metadata["Version"] = service.Version
metadata["Endpoints"] = ep
metadata["agent"] = "go-eureka-client"
res = append(res, Endpoint{
AppID: appID,
IP: ip,
Port: port,
SecurePort: securePort,
HomePageURL: homePageURL,
StatusPageURL: statusPageURL,
HealthCheckURL: healthCheckURL,
InstanceID: instanceID,
MetaData: metadata,
})
}
return res
}