92 lines
2.3 KiB
Go
92 lines
2.3 KiB
Go
package gfetcd
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"unitech/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...)
|
|
}
|