github.com/polarismesh/polaris@v1.17.8/apiserver/grpcserver/discover/server.go (about)

     1  /**
     2   * Tencent is pleased to support the open source community by making Polaris available.
     3   *
     4   * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
     5   *
     6   * Licensed under the BSD 3-Clause License (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   * https://opensource.org/licenses/BSD-3-Clause
    11   *
    12   * Unless required by applicable law or agreed to in writing, software distributed
    13   * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    14   * CONDITIONS OF ANY KIND, either express or implied. See the License for the
    15   * specific language governing permissions and limitations under the License.
    16   */
    17  
    18  package discover
    19  
    20  import (
    21  	"context"
    22  	"fmt"
    23  
    24  	apimodel "github.com/polarismesh/specification/source/go/api/v1/model"
    25  	apiservice "github.com/polarismesh/specification/source/go/api/v1/service_manage"
    26  	"go.uber.org/zap"
    27  	"google.golang.org/grpc"
    28  
    29  	"github.com/polarismesh/polaris/apiserver"
    30  	"github.com/polarismesh/polaris/apiserver/grpcserver"
    31  	v1 "github.com/polarismesh/polaris/apiserver/grpcserver/discover/v1"
    32  	"github.com/polarismesh/polaris/apiserver/grpcserver/utils"
    33  	commonlog "github.com/polarismesh/polaris/common/log"
    34  	"github.com/polarismesh/polaris/common/model"
    35  	"github.com/polarismesh/polaris/service"
    36  	"github.com/polarismesh/polaris/service/healthcheck"
    37  )
    38  
    39  var (
    40  	namingLog = commonlog.GetScopeOrDefaultByName(commonlog.NamingLoggerName)
    41  
    42  	cacheTypes = map[string]struct{}{
    43  		apiservice.DiscoverResponse_INSTANCE.String():        {},
    44  		apiservice.DiscoverResponse_ROUTING.String():         {},
    45  		apiservice.DiscoverResponse_RATE_LIMIT.String():      {},
    46  		apiservice.DiscoverResponse_CIRCUIT_BREAKER.String(): {},
    47  		apiservice.DiscoverResponse_FAULT_DETECTOR.String():  {},
    48  		apiservice.DiscoverResponse_SERVICES.String():        {},
    49  	}
    50  )
    51  
    52  // GRPCServer GRPC API服务器
    53  type GRPCServer struct {
    54  	grpcserver.BaseGrpcServer
    55  	namingServer      service.DiscoverServer
    56  	healthCheckServer *healthcheck.Server
    57  	openAPI           map[string]apiserver.APIConfig
    58  
    59  	v1server *v1.DiscoverServer
    60  }
    61  
    62  // GetPort 获取端口
    63  func (g *GRPCServer) GetPort() uint32 {
    64  	return g.BaseGrpcServer.GetPort()
    65  }
    66  
    67  // GetProtocol 获取Server的协议
    68  func (g *GRPCServer) GetProtocol() string {
    69  	return "grpc"
    70  }
    71  
    72  // Initialize 初始化GRPC API服务器
    73  func (g *GRPCServer) Initialize(ctx context.Context, option map[string]interface{},
    74  	apiConf map[string]apiserver.APIConfig) error {
    75  	g.openAPI = apiConf
    76  	if err := g.BaseGrpcServer.Initialize(ctx, option, g.buildInitOptions(option)...); err != nil {
    77  		return err
    78  	}
    79  
    80  	// 引入功能模块和插件
    81  	var err error
    82  	if g.namingServer, err = service.GetServer(); err != nil {
    83  		namingLog.Errorf("%v", err)
    84  		return err
    85  	}
    86  
    87  	if g.healthCheckServer, err = healthcheck.GetServer(); err != nil {
    88  		namingLog.Errorf("%v", err)
    89  		return err
    90  	}
    91  
    92  	g.v1server = v1.NewDiscoverServer(
    93  		v1.WithAllowAccess(g.allowAccess),
    94  		v1.WithEnterRateLimit(g.enterRateLimit),
    95  		v1.WithHealthCheckerServer(g.healthCheckServer),
    96  		v1.WithNamingServer(g.namingServer),
    97  	)
    98  	return nil
    99  }
   100  
   101  // Run 启动GRPC API服务器
   102  func (g *GRPCServer) Run(errCh chan error) {
   103  	g.BaseGrpcServer.Run(errCh, g.GetProtocol(), func(server *grpc.Server) error {
   104  		for name, config := range g.openAPI {
   105  			switch name {
   106  			case "client":
   107  				if config.Enable {
   108  					// 注册 v1 版本的 spec discover server
   109  					apiservice.RegisterPolarisGRPCServer(server, g.v1server)
   110  					apiservice.RegisterPolarisHeartbeatGRPCServer(server, g.v1server)
   111  					openMethod, getErr := utils.GetClientOpenMethod(config.Include, g.GetProtocol())
   112  					if getErr != nil {
   113  						return getErr
   114  					}
   115  					g.BaseGrpcServer.OpenMethod = openMethod
   116  				}
   117  			default:
   118  				namingLog.Errorf("[Grpc][Discover] api %s does not exist in grpcserver", name)
   119  				return fmt.Errorf("api %s does not exist in grpcserver", name)
   120  			}
   121  		}
   122  		return nil
   123  	})
   124  }
   125  
   126  // Stop 关闭GRPC
   127  func (g *GRPCServer) Stop() {
   128  	g.BaseGrpcServer.Stop(g.GetProtocol())
   129  }
   130  
   131  // Restart 重启Server
   132  func (g *GRPCServer) Restart(option map[string]interface{}, api map[string]apiserver.APIConfig,
   133  	errCh chan error) error {
   134  	initFunc := func() error {
   135  		return g.Initialize(context.Background(), option, api)
   136  	}
   137  	runFunc := func() {
   138  		g.Run(errCh)
   139  	}
   140  	return g.BaseGrpcServer.Restart(initFunc, runFunc, g.GetProtocol(), option)
   141  }
   142  
   143  // enterRateLimit 限流
   144  func (g *GRPCServer) enterRateLimit(ip string, method string) uint32 {
   145  	return g.BaseGrpcServer.EnterRatelimit(ip, method)
   146  }
   147  
   148  // allowAccess 限制访问
   149  func (g *GRPCServer) allowAccess(method string) bool {
   150  	return g.BaseGrpcServer.AllowAccess(method)
   151  }
   152  
   153  func (g *GRPCServer) buildInitOptions(option map[string]interface{}) []grpcserver.InitOption {
   154  	initOptions := []grpcserver.InitOption{
   155  		grpcserver.WithModule(model.DiscoverModule),
   156  		grpcserver.WithProtocol(g.GetProtocol()),
   157  		grpcserver.WithLogger(commonlog.FindScope(commonlog.APIServerLoggerName)),
   158  		grpcserver.WithMessageToCacheObject(discoverCacheConvert),
   159  	}
   160  
   161  	types := make([]string, 0, len(cacheTypes))
   162  	for k := range cacheTypes {
   163  		types = append(types, k)
   164  	}
   165  
   166  	cache, err := grpcserver.NewCache(option, types)
   167  	if err != nil {
   168  		namingLog.Warn("[Grpc][Discover] new protobuf cache", zap.Error(err))
   169  	}
   170  
   171  	if cache != nil {
   172  		initOptions = append(initOptions, grpcserver.WithProtobufCache(cache))
   173  	}
   174  
   175  	return initOptions
   176  }
   177  
   178  // discoverCacheConvert 将 DiscoverResponse 转换为 grpcserver.CacheObject
   179  func discoverCacheConvert(m interface{}) *grpcserver.CacheObject {
   180  	resp, ok := m.(*apiservice.DiscoverResponse)
   181  	if !ok {
   182  		return nil
   183  	}
   184  
   185  	if resp.Code.GetValue() != uint32(apimodel.Code_ExecuteSuccess) {
   186  		return nil
   187  	}
   188  	if resp.GetService().GetRevision().GetValue() == "" {
   189  		return nil
   190  	}
   191  	if _, ok := cacheTypes[resp.GetType().String()]; !ok {
   192  		return nil
   193  	}
   194  
   195  	keyProto := fmt.Sprintf("%s-%s-%s", resp.GetService().GetNamespace().GetValue(),
   196  		resp.GetService().GetName().GetValue(), resp.GetService().GetRevision().GetValue())
   197  
   198  	return &grpcserver.CacheObject{
   199  		OriginVal: resp,
   200  		CacheType: resp.Type.String(),
   201  		Key:       keyProto,
   202  	}
   203  }