package gfetcd import ( "context" "fmt" "globalfintech/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: // // 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...) }