package svc import ( "fmt" "net" "strconv" "sync" "time" "lone-services/pkg/discovery" "lone-services/pkg/utils" "lone-services/services/order/internal/config" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/zrpc" "gorm.io/gorm" ) // 缓存条目 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 } cacheKey := serviceName rpcCacheLock.Lock() entry, ok := rpcCache[cacheKey] if ok && time.Now().Before(entry.expireAt) { rpcCacheLock.Unlock() return entry.cli, nil } delete(rpcCache, cacheKey) 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, //rpc调用超时5s }) rpcCacheLock.Lock() rpcCache[cacheKey] = &rpcClientCacheEntry{ cli: cli, target: target, expireAt: time.Now().Add(rpcClientCacheTTL), } rpcCacheLock.Unlock() return cli, nil } type ServiceContext struct { Config config.Config DB *gorm.DB Prefix string ProductSvcName string //服务名 } func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { //启动仅读取配置,不建立rpc连接 多个服务就多个 productSvc := utils.GetConfigString("services.product") if productSvc == utils.StringEmpty { logx.Error("config services.product empty") } svcCtx := &ServiceContext{ Config: c, DB: db, Prefix: utils.GetConfigString("mysql.prefix"), ProductSvcName: productSvc, } return svcCtx }