gitee.com/woood2/luca@v1.0.4/cmd/micro/pkg/sdk.go (about)

     1  package pkg
     2  
     3  import (
     4  	"context"
     5  	"gitee.com/woood2/luca/cmd/micro/internal/middleware/auth"
     6  	"gitee.com/woood2/luca/internal/discovery"
     7  	"gitee.com/woood2/luca/internal/trace"
     8  	"github.com/go-kit/kit/endpoint"
     9  	"github.com/go-kit/kit/sd"
    10  	consulsd "github.com/go-kit/kit/sd/consul"
    11  	"github.com/go-kit/kit/sd/lb"
    12  	grpctransport "github.com/go-kit/kit/transport/grpc"
    13  	"github.com/go-playground/validator/v10"
    14  	"go.uber.org/zap"
    15  	gr "google.golang.org/grpc"
    16  	"io"
    17  	"time"
    18  )
    19  
    20  var globalLucaClient *LucaClient
    21  
    22  func SetGlobal(c *LucaClient) {
    23  	globalLucaClient = c
    24  }
    25  
    26  func Global() *LucaClient {
    27  	return globalLucaClient
    28  }
    29  
    30  func NewSD(client consulsd.Client, appkey, appSecret string,
    31  	zLogger *zap.Logger, options ...grpctransport.ClientOption) *LucaClient {
    32  	instancer := consulsd.NewInstancer(client, discovery.Logger(), "luca", []string{"luca"}, true)
    33  	options = append(options, auth.ClientAuth())
    34  	return &LucaClient{
    35  		validate:           validator.New(),
    36  		zapLogger:          zLogger.WithOptions(zap.AddCallerSkip(3)), //由于在defer中调用,需要skip+1
    37  		clientAppkey:       appkey,
    38  		clientAppSecret:    appSecret,
    39  		checkPermEndpoint:  makeEndpoint(instancer, makeCheckPermClientEndpoint, options...),
    40  		checkTokenEndpoint: makeEndpoint(instancer, makeCheckTokenClientEndpoint, options...),
    41  	}
    42  }
    43  
    44  func NewDirect(instance, appkey, appSecret string,
    45  	zLogger *zap.Logger, options ...grpctransport.ClientOption) (*LucaClient, error) {
    46  	options = append(options, auth.ClientAuth())
    47  	conn, err := gr.Dial(instance, gr.WithInsecure())
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  	return &LucaClient{
    52  		validate:           validator.New(),
    53  		zapLogger:          zLogger.WithOptions(zap.AddCallerSkip(3)), //由于在defer中调用,需要skip+1
    54  		clientAppkey:       appkey,
    55  		clientAppSecret:    appSecret,
    56  		checkPermEndpoint:  makeCheckPermClientEndpoint(conn, instance, options...),
    57  		checkTokenEndpoint: makeCheckTokenClientEndpoint(conn, instance, options...),
    58  	}, nil
    59  }
    60  
    61  type LucaClient struct {
    62  	validate *validator.Validate
    63  
    64  	zapLogger       *zap.Logger
    65  	clientAppkey    string
    66  	clientAppSecret string
    67  
    68  	checkPermEndpoint  endpoint.Endpoint
    69  	checkTokenEndpoint endpoint.Endpoint
    70  }
    71  
    72  func (c *LucaClient) log(ctx context.Context, begin time.Time, req interface{}, error error, returnValues ...interface{}) {
    73  	if error != nil {
    74  		if !isEnumeratedError(error) {
    75  			c.zapLogger.Error("luca:CheckPerm non-enumerated error",
    76  				zap.String("traceID", trace.ID(ctx)),
    77  				zap.Duration("took", time.Since(begin)),
    78  				zap.Any("req", req),
    79  				zap.Any("err", error),
    80  			)
    81  		} else {
    82  			c.zapLogger.Debug("luca:CheckPerm enumerated error",
    83  				zap.String("traceID", trace.ID(ctx)),
    84  				zap.Duration("took", time.Since(begin)),
    85  				zap.Any("req", req),
    86  				zap.String("err", error.Error()),
    87  			)
    88  		}
    89  	} else {
    90  		c.zapLogger.Debug("luca:CheckPerm succeed",
    91  			zap.String("traceID", trace.ID(ctx)),
    92  			zap.Duration("took", time.Since(begin)),
    93  			zap.Any("req", req),
    94  			zap.Any("returnValues", returnValues),
    95  		)
    96  	}
    97  }
    98  
    99  type EndpointMakerFunc func(conn *gr.ClientConn, instance string, options ...grpctransport.ClientOption) endpoint.Endpoint
   100  
   101  func makeEndpoint(instancer *consulsd.Instancer, maker EndpointMakerFunc, options ...grpctransport.ClientOption) endpoint.Endpoint {
   102  	var (
   103  		retryMax     = 1
   104  		retryTimeout = 60 * time.Second
   105  	)
   106  
   107  	logger := discovery.Logger()
   108  
   109  	fac := factory(maker, options...)
   110  	endpointer := sd.NewEndpointer(instancer, fac, logger)
   111  	balancer := lb.NewRoundRobin(endpointer)
   112  
   113  	// 经测试,timeout与retry是并列的
   114  	// timeout是多次retry的总计超时,达到timeout意味着整组retry结束
   115  	// retryMax 相当于总计执行次数
   116  	// retryMax=1,总计执行1次,重试0次
   117  	// retryMax=3,总计执行3次,重试2次
   118  	retry := lb.Retry(retryMax, retryTimeout, balancer)
   119  
   120  	return retry
   121  }
   122  
   123  func factory(maker EndpointMakerFunc, options ...grpctransport.ClientOption) sd.Factory {
   124  	return func(instance string) (endpoint.Endpoint, io.Closer, error) {
   125  		conn, err := gr.Dial(instance, gr.WithInsecure())
   126  		if err != nil {
   127  			return nil, nil, err
   128  		}
   129  		return maker(conn, instance, options...), nil, nil
   130  	}
   131  }