update
This commit is contained in:
153
myregistry/consul/consul.go
Normal file
153
myregistry/consul/consul.go
Normal file
@@ -0,0 +1,153 @@
|
||||
package consul
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.makemake.in/kzkzzzz/mycommon/myconf"
|
||||
"git.makemake.in/kzkzzzz/mycommon/myregistry"
|
||||
"github.com/google/uuid"
|
||||
api "github.com/hashicorp/consul/api"
|
||||
"log"
|
||||
"net"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ myregistry.IRegister = (*Consul)(nil)
|
||||
|
||||
type Consul struct {
|
||||
client *api.Client
|
||||
serviceIds map[string][]string
|
||||
serviceTags []string
|
||||
}
|
||||
|
||||
func (c *Consul) Name() string {
|
||||
return "consul"
|
||||
}
|
||||
|
||||
func (c *Consul) Register(service *myregistry.ServiceInfo) error {
|
||||
// 健康检查
|
||||
serviceId := uuid.New().String()
|
||||
|
||||
c.serviceIds[service.ServiceName] = append(c.serviceIds[service.ServiceName], serviceId)
|
||||
|
||||
check := &api.AgentServiceCheck{
|
||||
CheckID: serviceId,
|
||||
TCP: fmt.Sprintf("%s:%d", service.Ip, service.Port),
|
||||
Timeout: "5s", // 超时时间
|
||||
Interval: "20s", // 运行检查的频率
|
||||
// 指定时间后自动注销不健康的服务节点
|
||||
// 最小超时时间为1分钟,收获不健康服务的进程每30秒运行一次,因此触发注销的时间可能略长于配置的超时时间。
|
||||
DeregisterCriticalServiceAfter: "5m",
|
||||
Status: "passing",
|
||||
}
|
||||
srv := &api.AgentServiceRegistration{
|
||||
ID: serviceId, // 服务唯一ID
|
||||
Name: service.ServiceName, // 服务名称
|
||||
Tags: c.serviceTags, // 为服务打标签
|
||||
Address: service.Ip,
|
||||
Port: service.Port,
|
||||
Check: check,
|
||||
}
|
||||
|
||||
return c.client.Agent().ServiceRegister(srv)
|
||||
}
|
||||
|
||||
func (c *Consul) Deregister(service *myregistry.ServiceInfo) error {
|
||||
for _, svcId := range c.serviceIds[service.ServiceName] {
|
||||
err := c.client.Agent().ServiceDeregister(svcId)
|
||||
if err != nil {
|
||||
log.Printf("Failed to deregister service %s: %s\n", service, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Conf struct {
|
||||
Addr string
|
||||
Token string
|
||||
}
|
||||
|
||||
func MustNew(conf *myconf.Config) *Consul {
|
||||
consul, err := New(conf)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return consul
|
||||
}
|
||||
|
||||
func New(conf *myconf.Config) (*Consul, error) {
|
||||
cfg := api.DefaultConfig()
|
||||
cfg.Address = conf.GetString("addr")
|
||||
cfg.Transport.DialContext = (&net.Dialer{
|
||||
Timeout: 3 * time.Second,
|
||||
KeepAlive: 20 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext
|
||||
cfg.Token = conf.GetString("token")
|
||||
|
||||
username := conf.GetString("username")
|
||||
password := conf.GetString("password")
|
||||
|
||||
if username != "" && password != "" {
|
||||
cfg.HttpAuth = &api.HttpBasicAuth{
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
}
|
||||
|
||||
client, err := api.NewClient(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cl := &Consul{
|
||||
client: client,
|
||||
serviceIds: make(map[string][]string),
|
||||
serviceTags: make([]string, 0),
|
||||
}
|
||||
|
||||
if v := conf.GetStringSlice("serviceTags"); len(v) > 0 {
|
||||
cl.serviceTags = v
|
||||
} else {
|
||||
cl.serviceTags = []string{}
|
||||
}
|
||||
|
||||
return cl, nil
|
||||
}
|
||||
|
||||
func (c *Consul) Client() *api.Client {
|
||||
return c.client
|
||||
}
|
||||
|
||||
func GrpcUrl(serviceName string, conf *myconf.Config) string {
|
||||
return GrpcUrlWithTag("", serviceName, conf)
|
||||
}
|
||||
|
||||
func GrpcUrlWithTag(tag string, serviceName string, conf *myconf.Config) string {
|
||||
u := &url.URL{
|
||||
Scheme: schemeName,
|
||||
Host: conf.GetString("addr"),
|
||||
Path: serviceName,
|
||||
}
|
||||
|
||||
query := u.Query()
|
||||
query.Set("healthy", "true")
|
||||
|
||||
if v := conf.GetString("token"); v != "" {
|
||||
query.Set("token", v)
|
||||
}
|
||||
|
||||
if tag != "" {
|
||||
query.Set("tag", tag)
|
||||
}
|
||||
|
||||
username := conf.GetString("username")
|
||||
password := conf.GetString("password")
|
||||
|
||||
if username != "" && password != "" {
|
||||
u.User = url.UserPassword(username, password)
|
||||
}
|
||||
|
||||
u.RawQuery = query.Encode()
|
||||
|
||||
return u.String()
|
||||
}
|
||||
Reference in New Issue
Block a user