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.
80 lines
1.7 KiB
80 lines
1.7 KiB
package discovery |
|
|
|
import ( |
|
"context" |
|
"encoding/json" |
|
"fmt" |
|
clientv3 "go.etcd.io/etcd/client/v3" |
|
"go.etcd.io/etcd/client/v3/naming/endpoints" |
|
"sonet/pkg/utils/logger" |
|
"sonet/pkg/utils/shutdown" |
|
"time" |
|
) |
|
|
|
func EtcdDialUrl(serviceName string) string { |
|
return fmt.Sprintf("etcd:///%s", serviceName) |
|
} |
|
|
|
func EtcdRegistry(client *clientv3.Client, server *Server) (err error) { |
|
em, err := endpoints.NewManager(client, server.Name) |
|
if err != nil { |
|
return |
|
} |
|
ip, port, err := RegisterIpPort(server.Addr) |
|
if err != nil { |
|
return |
|
} |
|
|
|
server.Addr = fmt.Sprintf("%s:%d", ip, port) |
|
// 序列化 metadata 信息 |
|
meta := "{}" |
|
if server.Attrs != nil { |
|
bytes, e := json.Marshal(server.Attrs) |
|
if e != nil { |
|
err = e |
|
return |
|
} |
|
meta = string(bytes) |
|
} |
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) |
|
defer cancel() |
|
|
|
lease, err := client.Grant(ctx, DefaultRegisterTTL) // 使用租约注册端点确保如果主机无法维持保活心跳, 从服务中删除 |
|
if err != nil { |
|
return |
|
} |
|
endpointKey := fmt.Sprintf("%s/%s", server.Name, ip) |
|
err = em.AddEndpoint(ctx, |
|
endpointKey, |
|
endpoints.Endpoint{ |
|
Addr: server.Addr, |
|
Metadata: meta, |
|
}, |
|
clientv3.WithLease(lease.ID), |
|
) |
|
|
|
// keepalive lease |
|
keepAliveCh, err := client.KeepAlive(context.Background(), lease.ID) |
|
doneCh := make(chan bool) |
|
c := func() { |
|
doneCh <- true |
|
<-doneCh |
|
} |
|
shutdown.AddShutdownHook(c) |
|
go func() { |
|
for { |
|
select { |
|
case <-doneCh: // async... not done |
|
logger.Info("keepalive done") |
|
ctx, c := context.WithTimeout(context.Background(), time.Second*5) |
|
_, _ = client.Revoke(ctx, lease.ID) |
|
c() |
|
doneCh <- true |
|
return |
|
case _ = <-keepAliveCh: |
|
} |
|
} |
|
}() |
|
return |
|
}
|
|
|