• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Go源码解读-registry配置

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本次解读的源码是go-micro框架中registry仓库的配置,我们通常用以下这段代码来配置etcd

newRegistry := etcdv3.NewRegistry(func (options *registry.Options) {
	options.Addrs = []string{"192.168.100.151:2379"}
})

service := micro.NewService(
	micro.Registry(newRegistry),
)

这段代码内部的实现本质在于,创建Registry对象完成,返回对象之前,给该对象配置相关属性。

解读分析

我根据源码重新写了一段类似的代码,实现的原理是相同的。这段源码使用函数参数的形式来给生成的实例注入属性。

package main

import "fmt"

type Animal struct {
	name string
}

type Dog struct {
	animal Animal
	action string
}

type AniFunc func (*Animal)

func configure(d *Dog, af ...AniFunc)  {
    /*
    	不断遍历传入的函数,每个函数中的赋值语句都会作用于传参的对象中,更新对应属性
    */
	for _, o := range af {
        /*
        	核心代码:此时o为对应的函数
        	o := func(animal *Animal) {
                animal.name = "animal"
            }
            那么此时 &d.animal取到了实例化对象的地址,传给了指针对象参数
            通过指针对象参数,可以直接操作该实例化参数的属性,也就实现了配置信息的注入
        */
		o(&d.animal)
	}
	fmt.Printf("type:%T, value:%+v", d, d)
}

func NewDog(af ...AniFunc) *Dog {
	a := &Dog{
		animal: Animal{},
	}

	configure(a, af...)

	return a
}

func main() {
	NewDog(func(animal *Animal) {
		animal.name = "animal"
	}, func(animal *Animal) {  // 后面的属性会覆盖前面相同的属性,即name=lion
		animal.name = "lion"
	})
}

框架源码

type Option func(*Options)

type etcdRegistry struct {
	client  *clientv3.Client
	options registry.Options

	sync.RWMutex
	register map[string]uint64
	leases   map[string]clientv3.LeaseID
}

func NewRegistry(opts ...registry.Option) registry.Registry {
	e := &etcdRegistry{
		options:  registry.Options{},
		register: make(map[string]uint64),
		leases:   make(map[string]clientv3.LeaseID),
	}
	configure(e, opts...)
	return e
}

func configure(e *etcdRegistry, opts ...registry.Option) error {
	config := clientv3.Config{
		Endpoints: []string{"127.0.0.1:2379"},
	}

	for _, o := range opts {
		o(&e.options)
	}

	if e.options.Timeout == 0 {
		e.options.Timeout = 5 * time.Second
	}

	if e.options.Secure || e.options.TLSConfig != nil {
		tlsConfig := e.options.TLSConfig
		if tlsConfig == nil {
			tlsConfig = &tls.Config{
				InsecureSkipVerify: true,
			}
		}

		config.TLS = tlsConfig
	}

	if e.options.Context != nil {
		u, ok := e.options.Context.Value(authKey{}).(*authCreds)
		if ok {
			config.Username = u.Username
			config.Password = u.Password
		}
	}

	var cAddrs []string

	for _, address := range e.options.Addrs {
		if len(address) == 0 {
			continue
		}
		addr, port, err := net.SplitHostPort(address)
		if ae, ok := err.(*net.AddrError); ok && ae.Err == "missing port in address" {
			port = "2379"
			addr = address
			cAddrs = append(cAddrs, net.JoinHostPort(addr, port))
		} else if err == nil {
			cAddrs = append(cAddrs, net.JoinHostPort(addr, port))
		}
	}

	// if we got addrs then we'll update
	if len(cAddrs) > 0 {
		config.Endpoints = cAddrs
	}

	cli, err := clientv3.New(config)
	if err != nil {
		return err
	}
	e.client = cli
	return nil
}



鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Ubuntu10.04下安装谷歌GO编程语言发布时间:2022-07-10
下一篇:
Go Ethereum P2P: Kademlia 简介(2)发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap