原创分享 go-kit 微服务 服务注册与发现 (etcd 实现)

hwholiday · 2020年02月12日 · 1447 次阅读

etcd

简介

服务注册

  • 使用 go-kit 初始化一个 etcdV3 客户端
options := etcdv3.ClientOptions{
    DialTimeout:   ttl,
    DialKeepAlive: ttl,
}
etcdClient, err := etcdv3.NewClient(context.Background(), etcdAddrs, options)
if err != nil {
    utils.GetLogger().Error("[user_agent]  NewClient", zap.Error(err))
    return
}
Registar := etcdv3.NewRegistrar(etcdClient, etcdv3.Service{
    Key:   fmt.Sprintf("%s/%s",serName,grpcAddr),
    Value: grpcAddr,
}, log.NewNopLogger())
  • 将节点注册到服务器
Registar.Register()
  • 将节点注销
Registar.Deregister()

服务发现与负载均衡

  • 在基于《go-kit 微服务 使用 Grpc(并传递请求 ID)》 我们已经实现了一个 grpc 客户端,现在我们只需要为这个客户端添加服务发现,与负载均衡等相关操作

  • 创建一个 UserAgent 结构体,里面包含一个 etcdv3.Instancer 对象和一个 log.Logger 对象

type UserAgent struct {
    instancerm *etcdv3.Instancer
    logger     log.Logger
}
  • 初始化 UserAgent
    • 服务发现:通过 etcd 去查询对应服务的服务地址
  func NewUserAgentClient(addr []string, logger log.Logger) (*UserAgent, error) {
    var (
        etcdAddrs = addr
        serName   = "svc.user.agent"
        ttl       = 5 * time.Second
    )
    options := etcdv3.ClientOptions{
        DialTimeout:   ttl,
        DialKeepAlive: ttl,
    }
    etcdClient, err := etcdv3.NewClient(context.Background(), etcdAddrs, options)
    if err != nil {
        return nil, err
    }
    instancerm, err := etcdv3.NewInstancer(etcdClient, serName, logger)
    if err != nil {
        return nil, err
    }
    return &UserAgent{
        instancerm: instancerm,
        logger:     logger,
    }, err
}
  • 负载均衡:把取到的服务地址按照自己需求进行处理(Random,RoundRobin 等)
  func (u *UserAgent) UserAgentClient() (src.Service, error) {
    var (
        retryMax     = 3
        retryTimeout = 500 * time.Millisecond
    )
    var (
        endpoints src.EndPointServer
    )
    {
        factory := u.factoryFor(src.MakeLoginEndPoint)
        endpointer := sd.NewEndpointer(u.instancerm, factory, u.logger)
        balancer := lb.NewRandom(endpointer, time.Now().UnixNano())
        retry := lb.Retry(retryMax, retryTimeout, balancer)
        endpoints.LoginEndPoint = retry
    }
    return endpoints, nil
}

func (u *UserAgent) factoryFor(makeEndpoint func(src.Service) endpoint.Endpoint) sd.Factory {
    return func(instance string) (endpoint.Endpoint, io.Closer, error) {
        conn, err := grpc.Dial(instance, grpc.WithInsecure())
        if err != nil {
            return nil, nil, err
        }
        srv := u.NewGRPCClient(conn)
        endpoints := makeEndpoint(srv)
        return endpoints, conn, err
    }
}

运行日志

  • 我们启动 3 个服务地址分别为(127.0.0.1:8881,127.0.0.1:8882,127.0.0.1:8883)
./user_agent -g 127.0.0.1:8881
2020-01-08 16:28:45     INFO    logtool/log.go:89       [NewLogger] success
2020-01-08 16:28:45     INFO    user_agent/main.go:75   [user_agent] run 127.0.0.1:8881


./user_agent -g 127.0.0.1:8882
2020-01-08 16:28:45     INFO    logtool/log.go:89       [NewLogger] success
2020-01-08 16:28:45     INFO    user_agent/main.go:75   [user_agent] run 127.0.0.1:8882


./user_agent -g 127.0.0.1:8883
2020-01-08 16:28:45     INFO    logtool/log.go:89       [NewLogger] success
2020-01-08 16:28:45     INFO    user_agent/main.go:75   [user_agent] run 127.0.0.1:8883


  • 运行 TestNewUserAgentClient 方法 查选 3 个服务器的日志输入
./user_agent -g 127.0.0.1:8881
2020-01-08 16:28:36     INFO    logtool/log.go:89       [NewLogger] success
2020-01-08 16:28:36     INFO    user_agent/main.go:75   [user_agent] run 127.0.0.1:8881
2020-01-08 16:30:00     DEBUG   src/middleware_server.go:31     [ee92f353-5e8f-526e-b0b4-970d7507e5f6]  {"调用 Login logMiddlewareServer": "Login", "req": "Account:\"hwholiday\" Password:\"123456\" ", "res": "Token:\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJO1lIjoiaHdob2xpZGF5IiwiRGNJZCI6MSwiZXhwIjoxNTc4NDcyMjMwLCJpYXQiOjE1Nzg0NzIyMDAsImlzcyI6ImtpdF92NCIsIm5iZiI6MTU3ODQ3MjIwMCwic3ViIjoibG9naW4ifQ.q6lveFqZbgl-10VcaPm4dRrwA4m9FN4i7Fqc82inclY\" ", "time": "272.061µs", "err": null}
2020-01-08 16:30:02     DEBUG   src/middleware_server.go:31     [63f4ddb2-dc6b-503a-85aa-bdf99027f91e]  {"调用 Login logMiddlewareServer": "Login", "req": "Account:\"hwholiday\" Password:\"123456\" ", "res": "Token:\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJO1lIjoiaHdob2xpZGF5IiwiRGNJZCI6MSwiZXhwIjoxNTc4NDcyMjMyLCJpYXQiOjE1Nzg0NzIyMDIsImlzcyI6ImtpdF92NCIsIm5iZiI6MTU3ODQ3MjIwMiwic3ViIjoibG9naW4ifQ.Td_pBMlkGpK-RjpIOikn1N4BF9q0nID1munt7SvN-0E\" ", "time": "105.5µs", "err": null}
2020-01-08 16:30:03     DEBUG   src/middleware_server.go:31     [fe1a7185-cf9b-5bff-91c7-58271f9eecc8]  {"调用 Login logMiddlewareServer": "Login", "req": "Account:\"hwholiday\" Password:\"123456\" ", "res": "Token:\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJO1lIjoiaHdob2xpZGF5IiwiRGNJZCI6MSwiZXhwIjoxNTc4NDcyMjMzLCJpYXQiOjE1Nzg0NzIyMDMsImlzcyI6ImtpdF92NCIsIm5iZiI6MTU3ODQ3MjIwMywic3ViIjoibG9naW4ifQ.d7yyFAH70CJvMpK1hIU-rBya0bjwNapP89j_-43liSQ\" ", "time": "40.564µs", "err": null}
2020-01-08 16:30:31     DEBUG   src/middleware_server.go:31     [eed06439-bc47-5f17-9329-9fdb3dfbce5f]  {"调用 Login logMiddlewareServer": "Login", "req": "Account:\"hwholiday\" Password:\"123456\" ", "res": "Token:\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJO1lIjoiaHdob2xpZGF5IiwiRGNJZCI6MSwiZXhwIjoxNTc4NDcyMjYxLCJpYXQiOjE1Nzg0NzIyMzEsImlzcyI6ImtpdF92NCIsIm5iZiI6MTU3ODQ3MjIzMSwic3ViIjoibG9naW4ifQ.jAbaiEPM5QZKY_bHHVb8a_WyflKHKn34l2MPHIarly4\" ", "time": "111.298µs", "err": null}
2020-01-08 16:30:33     DEBUG   src/middleware_server.go:31     [21deba8a-2de6-5c44-bd01-633225e652c2]  {"调用 Login logMiddlewareServer": "Login", "req": "Account:\"hwholiday\" Password:\"123456\" ", "res": "Token:\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJO1lIjoiaHdob2xpZGF5IiwiRGNJZCI6MSwiZXhwIjoxNTc4NDcyMjYzLCJpYXQiOjE1Nzg0NzIyMzMsImlzcyI6ImtpdF92NCIsIm5iZiI6MTU3ODQ3MjIzMywic3ViIjoibG9naW4ifQ.wJWduZ42o99DTUF6Nkhr9h4ddVCiY7G4jZtuhoHIqwE\" ", "time": "59.499µs", "err": null}
2020-01-08 16:30:36     DEBUG   src/middleware_server.go:31     [02e304ff-8ef1-5f9a-8ed6-cdd64814ea52]  {"调用 Login logMiddlewareServer": "Login", "req": "Account:\"hwholiday\" Password:\"123456\" ", "res": "Token:\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJO1lIjoiaHdob2xpZGF5IiwiRGNJZCI6MSwiZXhwIjoxNTc4NDcyMjY2LCJpYXQiOjE1Nzg0NzIyMzYsImlzcyI6ImtpdF92NCIsIm5iZiI6MTU3ODQ3MjIzNiwic3ViIjoibG9naW4ifQ._Rvw4NwSeDrSFIKkzbSVcx0k6YvFVZqGPt3bYFmJUjg\" ", "time": "71.755µs", "err": null}

./user_agent -g 127.0.0.1:8882
2020-01-08 16:28:42     INFO    logtool/log.go:89       [NewLogger] success
2020-01-08 16:28:42     INFO    user_agent/main.go:75   [user_agent] run 127.0.0.1:8882
2020-01-08 16:30:32     DEBUG   src/middleware_server.go:31     [759c5214-ec26-5788-840d-1387f6cce9be]  {"调用 Login logMiddlewareServer": "Login", "req": "Account:\"hwholiday\" Password:\"123456\" ", "res": "Token:\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJO1lIjoiaHdob2xpZGF5IiwiRGNJZCI6MSwiZXhwIjoxNTc4NDcyMjYyLCJpYXQiOjE1Nzg0NzIyMzIsImlzcyI6ImtpdF92NCIsIm5iZiI6MTU3ODQ3MjIzMiwic3ViIjoibG9naW4ifQ.QQyA9Pt3eDVRBAXc764eIX7MBZYoW8Wr-Tlvw8boyxI\" ", "time": "196.996µs", "err": null}
2020-01-08 16:30:35     DEBUG   src/middleware_server.go:31     [ec3826e3-09e6-55f6-9998-baff941a8042]  {"调用 Login logMiddlewareServer": "Login", "req": "Account:\"hwholiday\" Password:\"123456\" ", "res": "Token:\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJO1lIjoiaHdob2xpZGF5IiwiRGNJZCI6MSwiZXhwIjoxNTc4NDcyMjY1LCJpYXQiOjE1Nzg0NzIyMzUsImlzcyI6ImtpdF92NCIsIm5iZiI6MTU3ODQ3MjIzNSwic3ViIjoibG9naW4ifQ.ZljiQVypRaBrmPgzGK_aKpBbQueJdAPRAKdkzvhi0Yk\" ", "time": "858.642µs", "err": null}

./user_agent -g 127.0.0.1:8883
2020-01-08 16:28:45     INFO    logtool/log.go:89       [NewLogger] success
2020-01-08 16:28:45     INFO    user_agent/main.go:75   [user_agent] run 127.0.0.1:8883
2020-01-08 16:30:01     DEBUG   src/middleware_server.go:31     [e68ec443-5f38-58de-a874-e8ff8ed127c0]  {"调用 Login logMiddlewareServer": "Login", "req": "Account:\"hwholiday\" Password:\"123456\" ", "res": "Token:\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJO1lIjoiaHdob2xpZGF5IiwiRGNJZCI6MSwiZXhwIjoxNTc4NDcyMjMxLCJpYXQiOjE1Nzg0NzIyMDEsImlzcyI6ImtpdF92NCIsIm5iZiI6MTU3ODQ3MjIwMSwic3ViIjoibG9naW4ifQ.taUS3LxS8uTAA3loIGEeBfHuYVMgImBBNUnYvgygnVE\" ", "time": "271.665µs", "err": null}
2020-01-08 16:30:34     DEBUG   src/middleware_server.go:31     [cabaf11b-4b34-5a4c-98ca-6cc6e31b6da9]  {"调用 Login logMiddlewareServer": "Login", "req": "Account:\"hwholiday\" Password:\"123456\" ", "res": "Token:\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJO1lIjoiaHdob2xpZGF5IiwiRGNJZCI6MSwiZXhwIjoxNTc4NDcyMjY0LCJpYXQiOjE1Nzg0NzIyMzQsImlzcyI6ImtpdF92NCIsIm5iZiI6MTU3ODQ3MjIzNCwic3ViIjoibG9naW4ifQ.yE1Lb51Ov6z-NmJRSrMAMHR1rdReflH5ngslbEttTmo\" ", "time": "114.162µs", "err": null}

结语

  • 观察日志看到 client 请求地址平均分布在 3 台服务器上,现在已经基本实现了服务注册,发现,负载均衡
  • 欢迎添加 QQ 一起讨论

完整代码地址

联系 QQ: 3355168235

更多原创文章干货分享,请关注公众号
  • 加微信实战群请加微信(注明:实战群):gocnio
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册