mirror of
https://github.com/go-kratos/kratos.git
synced 2025-03-31 22:05:08 +02:00
consul: support WithServiceResolver option (#1693)
* consul: add endpoints resolver option * consul: resolver []*api.ServiceEntry -> []*registry.ServiceInstance * consul: rename Resolver -> ServiceResolver
This commit is contained in:
parent
2e045c3e42
commit
03f5ee015c
@ -18,38 +18,29 @@ type Client struct {
|
|||||||
cli *api.Client
|
cli *api.Client
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
|
|
||||||
|
// resolve service entry endpoints
|
||||||
|
resolver ServiceResolver
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient creates consul client
|
// NewClient creates consul client
|
||||||
func NewClient(cli *api.Client) *Client {
|
func NewClient(cli *api.Client) *Client {
|
||||||
c := &Client{cli: cli}
|
c := &Client{cli: cli, resolver: defaultResolver}
|
||||||
c.ctx, c.cancel = context.WithCancel(context.Background())
|
c.ctx, c.cancel = context.WithCancel(context.Background())
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Service get services from consul
|
func defaultResolver(_ context.Context, entries []*api.ServiceEntry) []*registry.ServiceInstance {
|
||||||
func (d *Client) Service(ctx context.Context, service string, index uint64, passingOnly bool) ([]*registry.ServiceInstance, uint64, error) {
|
services := make([]*registry.ServiceInstance, 0, len(entries))
|
||||||
opts := &api.QueryOptions{
|
|
||||||
WaitIndex: index,
|
|
||||||
WaitTime: time.Second * 55,
|
|
||||||
}
|
|
||||||
opts = opts.WithContext(ctx)
|
|
||||||
entries, meta, err := d.cli.Health().Service(service, "", passingOnly, opts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
services := make([]*registry.ServiceInstance, 0)
|
|
||||||
|
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
var version string
|
var version string
|
||||||
for _, tag := range entry.Service.Tags {
|
for _, tag := range entry.Service.Tags {
|
||||||
strs := strings.SplitN(tag, "=", 2)
|
ss := strings.SplitN(tag, "=", 2)
|
||||||
if len(strs) == 2 && strs[0] == "version" {
|
if len(ss) == 2 && ss[0] == "version" {
|
||||||
version = strs[1]
|
version = ss[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var endpoints []string
|
var endpoints []string //nolint:prealloc
|
||||||
for scheme, addr := range entry.Service.TaggedAddresses {
|
for scheme, addr := range entry.Service.TaggedAddresses {
|
||||||
if scheme == "lan_ipv4" || scheme == "wan_ipv4" || scheme == "lan_ipv6" || scheme == "wan_ipv6" {
|
if scheme == "lan_ipv4" || scheme == "wan_ipv4" || scheme == "lan_ipv6" || scheme == "wan_ipv6" {
|
||||||
continue
|
continue
|
||||||
@ -64,11 +55,29 @@ func (d *Client) Service(ctx context.Context, service string, index uint64, pass
|
|||||||
Endpoints: endpoints,
|
Endpoints: endpoints,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return services, meta.LastIndex, nil
|
|
||||||
|
return services
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register register service instacen to consul
|
// ServiceResolver is used to resolve service endpoints
|
||||||
func (d *Client) Register(ctx context.Context, svc *registry.ServiceInstance, enableHealthCheck bool) error {
|
type ServiceResolver func(ctx context.Context, entries []*api.ServiceEntry) []*registry.ServiceInstance
|
||||||
|
|
||||||
|
// Service get services from consul
|
||||||
|
func (c *Client) Service(ctx context.Context, service string, index uint64, passingOnly bool) ([]*registry.ServiceInstance, uint64, error) {
|
||||||
|
opts := &api.QueryOptions{
|
||||||
|
WaitIndex: index,
|
||||||
|
WaitTime: time.Second * 55,
|
||||||
|
}
|
||||||
|
opts = opts.WithContext(ctx)
|
||||||
|
entries, meta, err := c.cli.Health().Service(service, "", passingOnly, opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
return c.resolver(ctx, entries), meta.LastIndex, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register register service instance to consul
|
||||||
|
func (c *Client) Register(_ context.Context, svc *registry.ServiceInstance, enableHealthCheck bool) error {
|
||||||
addresses := make(map[string]api.ServiceAddress)
|
addresses := make(map[string]api.ServiceAddress)
|
||||||
checkAddresses := make([]string, 0, len(svc.Endpoints))
|
checkAddresses := make([]string, 0, len(svc.Endpoints))
|
||||||
for _, endpoint := range svc.Endpoints {
|
for _, endpoint := range svc.Endpoints {
|
||||||
@ -103,7 +112,7 @@ func (d *Client) Register(ctx context.Context, svc *registry.ServiceInstance, en
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := d.cli.Agent().ServiceRegister(asr)
|
err := c.cli.Agent().ServiceRegister(asr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -113,8 +122,8 @@ func (d *Client) Register(ctx context.Context, svc *registry.ServiceInstance, en
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
_ = d.cli.Agent().UpdateTTL("service:"+svc.ID, "pass", "pass")
|
_ = c.cli.Agent().UpdateTTL("service:"+svc.ID, "pass", "pass")
|
||||||
case <-d.ctx.Done():
|
case <-c.ctx.Done():
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,7 +132,7 @@ func (d *Client) Register(ctx context.Context, svc *registry.ServiceInstance, en
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Deregister deregister service by service ID
|
// Deregister deregister service by service ID
|
||||||
func (d *Client) Deregister(ctx context.Context, serviceID string) error {
|
func (c *Client) Deregister(_ context.Context, serviceID string) error {
|
||||||
d.cancel()
|
c.cancel()
|
||||||
return d.cli.Agent().ServiceDeregister(serviceID)
|
return c.cli.Agent().ServiceDeregister(serviceID)
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,15 @@ func WithHealthCheck(enable bool) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithServiceResolver with endpoint function option.
|
||||||
|
func WithServiceResolver(fn ServiceResolver) Option {
|
||||||
|
return func(o *Registry) {
|
||||||
|
if o.cli != nil {
|
||||||
|
o.cli.resolver = fn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Config is consul registry config
|
// Config is consul registry config
|
||||||
type Config struct {
|
type Config struct {
|
||||||
*api.Config
|
*api.Config
|
||||||
|
Loading…
x
Reference in New Issue
Block a user