/** 客户端封装 */ package util import ( "app.yhyue.com/BP/servicerd/proto" "context" "errors" "google.golang.org/grpc" "log" "time" ) const ( //TODO 目前实现前2中 ERROR_ERTRY_TYPE_FIRST = iota //1次,找到第一个服务提供者,出错即返回 ERROR_ERTRY_TYPE_FIRST_5 //5次尝试,找到第一个服务提供者 ERROR_ERTRY_TYPE_OVER_ALL //尝试遍历所有服务,直至又一个提供正常返回 ) //调用 type CallFn func(conn *grpc.ClientConn, args ...interface{}) (interface{}, error) type ClientUtil struct { RdServer string serviceConn *grpc.ClientConn serviceClient proto.ServiceClient } func NewClient(rdServer string) (*ClientUtil, error) { c := &ClientUtil{RdServer: rdServer} conn, err := grpc.Dial(rdServer, grpc.WithInsecure()) if err != nil { return nil, err } client := proto.NewServiceClient(conn) c.serviceConn = conn c.serviceClient = client return c, nil } func (cu *ClientUtil) Run(serviceName string, errRetryTime int, fn CallFn, args ...interface{}) (interface{}, error) { defer func() { if err := recover(); err != nil { log.Println("捕获异常:", err) } }() for i := 0; i < errRetryTime; i++ { repl, err := cu.serviceClient.Apply(context.Background(), &proto.ApplyReqData{Name: serviceName, Balance: 0}) if err != nil { log.Println("client-util", "无可用服务", err.Error()) time.Sleep(1 * time.Second) continue } //TODO 业务调用 conn, err := grpc.Dial(repl.Addr, grpc.WithInsecure()) if err != nil { log.Println("client-util", "连接到服务节点失败:", repl.Addr, err.Error()) time.Sleep(1 * time.Second) continue } ret, err := fn(conn, args...) conn.Close() return ret, err } return nil, errors.New("远程服务调用失败") }