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 }