Files
unitech-golib/gfetcd/client.go
2020-04-18 22:47:25 +08:00

92 lines
2.3 KiB
Go

package gfetcd
import (
"context"
"fmt"
"unitechdev/golib/tlog"
"os"
"strings"
"time"
"github.com/coreos/etcd/clientv3"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/keepalive"
)
// 客户端配置
type ResolverConfig struct {
BasicConfig
WatchServers []string `toml:"watch_servers"` // 依赖的服务名称
}
type Resolver struct {
userCfg *ResolverConfig
etcdCli *clientv3.Client
rpcServers map[string]*grpc.ClientConn
}
func NewResolver(cfg *ResolverConfig) (resolver *Resolver, err error) {
if cfg.Debug {
clientv3.SetLogger(grpclog.NewLoggerV2WithVerbosity(os.Stderr, os.Stderr, os.Stderr, 4))
}
cli, err := etcdDial(&cfg.BasicConfig)
if err != nil {
return nil, err
}
resolver = &Resolver{
userCfg: cfg,
etcdCli: cli,
rpcServers: make(map[string]*grpc.ClientConn),
}
for _, serviceName := range cfg.WatchServers {
service := ServiceKey(cfg.Prefix, serviceName)
tlog.Debugf("ETCD RESOLVER||service: %s", service)
//r := &etcdnaming.GRPCResolver{Client: cli} // todo: 全部更新为新版后,改为这种方式
r := &GFgrpcResolver{Client: cli}
b := grpc.RoundRobin(r)
resolver.rpcServers[service], err = grpc.Dial(service, grpc.WithInsecure(),
grpc.WithTimeout(time.Second*5),
grpc.WithKeepaliveParams(keepalive.ClientParameters{Time: time.Duration(2) * time.Second}),
grpc.WithBalancer(b),
grpc.WithBlock())
if err != nil {
tlog.Errorf("ETCD RESOLVER||service: %s ||grpc dial err:%s", service, err)
return nil, fmt.Errorf("grpc dial err")
}
}
return resolver, nil
}
func (self *Resolver) Call(ctx context.Context, method string, args, reply interface{}, opts ...grpc.CallOption) error {
// method format: /<serviceName>/<methodName>
// eg. "/case_expire.CaseExpire/ExpireCase"
t := strings.Split(method, "/")
if len(t) < 3 {
tlog.Errorf("ETCD RESOLVER||method name: %s incorrect format", method)
return fmt.Errorf("invalid method format")
}
serviceKey := ServiceKey(self.userCfg.Prefix, t[1], "")
tlog.Debugf("ETCD RESOLVER||Call(serviceKey: %s, method: %s)",
serviceKey, method)
conn, ok := self.rpcServers[serviceKey]
if !ok {
tlog.Errorf("ETCD RESOLVER||method: %s||no grpc client available", method)
return fmt.Errorf("no grpc client available")
}
return grpc.Invoke(ctx, method, args, reply, conn, opts...)
}