package svc import ( "fmt" "net" "strconv" "sync" "time" "lone-services/pkg/discovery" "lone-services/pkg/utils" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/zrpc" ) type rpcClientCacheEntry struct { cli zrpc.Client target string expireAt time.Time } const rpcClientCacheTTL = 30 * time.Second var ( rpcCacheLock sync.Mutex rpcCache = make(map[string]*rpcClientCacheEntry) ) func GetRpcClient(serviceName string) (zrpc.Client, error) { if serviceName == utils.StringEmpty { err := fmt.Errorf("rpc serviceName is empty") logx.Error(err) return nil, err } rpcCacheLock.Lock() entry, ok := rpcCache[serviceName] if ok && time.Now().Before(entry.expireAt) { rpcCacheLock.Unlock() return entry.cli, nil } delete(rpcCache, serviceName) rpcCacheLock.Unlock() inst, err := discovery.Pick(serviceName) if err != nil { err = fmt.Errorf("discovery pick %s failed: %w", serviceName, err) logx.Error(err) return nil, err } target := net.JoinHostPort(inst.IP, strconv.FormatUint(inst.Port, utils.NumberTen)) cli := zrpc.MustNewClient(zrpc.RpcClientConf{ Target: target, Timeout: utils.RpcTimeOut, }) rpcCacheLock.Lock() rpcCache[serviceName] = &rpcClientCacheEntry{ cli: cli, target: target, expireAt: time.Now().Add(rpcClientCacheTTL), } rpcCacheLock.Unlock() return cli, nil }