From 35e590e0a39f483d33a089ce54090de2e0a8fcf4 Mon Sep 17 00:00:00 2001 From: chuntaojun Date: Mon, 26 Aug 2024 11:59:35 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E5=8C=B9=E9=85=8D=E5=A4=B1=E8=B4=A5=E9=BB=98=E8=AE=A4=E8=BD=AC?= =?UTF-8?q?=E4=B8=BA=E8=BF=94=E5=9B=9E=E5=85=A8=E9=83=A8=E5=AE=9E=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/plugin/servicerouter/servicerouter.go | 10 ++++ plugin/servicerouter/rulebase/rule.go | 62 +++++++++++++++-------- 2 files changed, 50 insertions(+), 22 deletions(-) diff --git a/pkg/plugin/servicerouter/servicerouter.go b/pkg/plugin/servicerouter/servicerouter.go index b4f91c48..ce39dd62 100644 --- a/pkg/plugin/servicerouter/servicerouter.go +++ b/pkg/plugin/servicerouter/servicerouter.go @@ -27,6 +27,14 @@ import ( "github.com/polarismesh/polaris-go/pkg/plugin/common" ) +type FailOverType int32 + +const ( + _ FailOverType = iota + FailOverAll + FailOverNone +) + // RouteInfo 路由信息 type RouteInfo struct { // 源服务信息 @@ -57,6 +65,8 @@ type RouteInfo struct { Canary string // 进行匹配的规则类型,如规则路由有入规则和出规则之分 MatchRuleType RuleType + // 规则路由失败降级类型 + FailOverType *FailOverType } // Init 初始化map diff --git a/plugin/servicerouter/rulebase/rule.go b/plugin/servicerouter/rulebase/rule.go index 571d9224..46065257 100644 --- a/plugin/servicerouter/rulebase/rule.go +++ b/plugin/servicerouter/rulebase/rule.go @@ -19,7 +19,6 @@ package rulebase import ( "encoding/json" - "fmt" "sync" "github.com/golang/protobuf/jsonpb" @@ -28,7 +27,6 @@ import ( "github.com/polarismesh/polaris-go/pkg/algorithm/rand" "github.com/polarismesh/polaris-go/pkg/config" - "github.com/polarismesh/polaris-go/pkg/log" "github.com/polarismesh/polaris-go/pkg/model" "github.com/polarismesh/polaris-go/pkg/plugin" "github.com/polarismesh/polaris-go/pkg/plugin/common" @@ -44,6 +42,7 @@ type RuleBasedInstancesFilter struct { recoverAll bool prioritySubsetPool *sync.Pool systemCfg config.SystemConfig + routerConf *RuleRouterConfig } // Type 插件类型 @@ -66,6 +65,10 @@ func (g *RuleBasedInstancesFilter) Init(ctx *plugin.InitContext) error { g.valueCtx = ctx.ValueCtx g.prioritySubsetPool = &sync.Pool{} g.systemCfg = ctx.Config.GetGlobal().GetSystem() + routerConf := ctx.Config.GetConsumer().GetServiceRouter().GetPluginConfig(g.Name()) + if routerConf != nil { + g.routerConf = routerConf.(*RuleRouterConfig) + } return nil } @@ -144,27 +147,20 @@ finally: case dstRuleSuccess: targetCluster = dstFilteredInstances default: - checkRule := routeInfo.DestService.GetNamespace() + ":" + routeInfo.DestService.GetService() - if ruleStatus == sourceRuleFail { - checkRule = routeInfo.SourceService.GetNamespace() + ":" + routeInfo.SourceService.GetService() + failoverType := routeInfo.FailOverType + if failoverType == nil { + failoverType = &g.routerConf.failoverType + } + if *failoverType == servicerouter.FailOverNone { + emptyCluster := model.NewServiceClusters(model.NewDefaultServiceInstancesWithRegistryValue(model.ServiceInfo{ + Service: withinCluster.GetClusters().GetServiceInstances().GetService(), + Namespace: withinCluster.GetClusters().GetServiceInstances().GetNamespace(), + Metadata: withinCluster.GetClusters().GetServiceInstances().GetMetadata(), + }, withinCluster.GetClusters().GetServiceInstances(), []model.Instance{})) + targetCluster = model.NewCluster(emptyCluster, withinCluster) + } else { + targetCluster = model.NewCluster(clusters, withinCluster) } - // 如果规则匹配失败, 返回错误 - notMatchedSrcText := getSourcesText(summary.notMatchedSources) - matchedSrcText := getSourcesText(summary.matchedSource) - invalidRegexSourceText := getSourcesText(summary.invalidRegexSources) - notMatchedDstText := getNotMatchedDestinationText(summary.notMatchedDestinations) - invalidRegexDstText := getNotMatchedDestinationText(summary.invalidRegexDestinations) - weightZeroDstText := getNotMatchedDestinationText(summary.weightZeroDestinations) - regexCompileErrText := getErrorRegexText(summary.errorRegexes) - errorText := fmt.Sprintf("route rule not match, rule status: %s, sourceService %s, used variables %v,"+ - " dstService %s, notMatchedSource is %s, invalidRegexSource is %s, matchedSource is %s,"+ - " notMatchedDestination is %s, invalidRegexDestination is %s, zeroWeightDestination is %s,"+ - " regexCompileErrors is %s, please check your route rule of service %s", - ruleStatus.String(), model.ToStringService(routeInfo.SourceService, true), routeInfo.EnvironmentVariables, - model.ToStringService(routeInfo.DestService, false), notMatchedSrcText, invalidRegexSourceText, - matchedSrcText, notMatchedDstText, invalidRegexDstText, weightZeroDstText, regexCompileErrText, checkRule) - log.GetBaseLogger().Errorf(errorText) - return nil, model.NewSDKError(model.ErrCodeRouteRuleNotMatch, nil, errorText) } result := servicerouter.PoolGetRouteResult(g.valueCtx) result.OutputCluster = targetCluster @@ -237,3 +233,25 @@ func checkRouteRule(routeRule model.ServiceRule) error { func init() { plugin.RegisterPlugin(&RuleBasedInstancesFilter{}) } + +func init() { + plugin.RegisterConfigurablePlugin(&RuleBasedInstancesFilter{}, &RuleRouterConfig{}) +} + +type RuleRouterConfig struct { + failoverType servicerouter.FailOverType + FailoverType string `yaml:"failoverType"` +} + +// Verify 校验配置是否OK +func (rc *RuleRouterConfig) Verify() error { + return nil +} + +// SetDefault 对关键值设置默认值 +func (rc *RuleRouterConfig) SetDefault() { + rc.failoverType = servicerouter.FailOverAll + if rc.FailoverType == "none" { + rc.failoverType = servicerouter.FailOverNone + } +}