This is an automated email from the ASF dual-hosted git repository.

wuxinfan pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git


The following commit(s) were added to refs/heads/develop by this push:
     new 7dc58203d Revert "delete all polaris (#2920)" (#2924)
7dc58203d is described below

commit 7dc58203d0dd789370a1802c54ed2063d15a8db9
Author: marsevilspirit <[email protected]>
AuthorDate: Fri Jun 27 22:38:15 2025 +0800

    Revert "delete all polaris (#2920)" (#2924)
    
    This reverts commit 941fde77c099f99728baa4aa17a1124decaf6753.
---
 README.md                              |   2 +-
 cluster/router/polaris/default.go      |  27 +++
 cluster/router/polaris/factory.go      |  35 ++++
 cluster/router/polaris/router.go       | 331 +++++++++++++++++++++++++++++++
 common/constant/polaris_key.go         |  42 ++++
 filter/filter_impl/import.go           |   1 +
 filter/polaris/limit/default.go        |  30 +++
 filter/polaris/limit/limiter.go        | 173 ++++++++++++++++
 go.mod                                 |   5 +
 go.sum                                 |  24 +++
 imports/imports.go                     |   3 +
 registry/options.go                    |   6 +
 registry/polaris/core.go               | 131 +++++++++++++
 registry/polaris/doc.go                |  19 ++
 registry/polaris/listener.go           | 123 ++++++++++++
 registry/polaris/registry.go           | 287 +++++++++++++++++++++++++++
 registry/polaris/service_discovery.go  | 348 +++++++++++++++++++++++++++++++++
 registry/polaris/utils.go              |  45 +++++
 remoting/polaris/builder.go            | 160 +++++++++++++++
 remoting/polaris/builder_test.go       |  45 +++++
 remoting/polaris/parser/parser.go      | 125 ++++++++++++
 remoting/polaris/parser/parser_test.go | 168 ++++++++++++++++
 remoting/polaris/polaris.yaml          |  84 ++++++++
 tools/dubbo-go-schema/dubbo-go.json    |   1 +
 24 files changed, 2214 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 4a448da6c..c2966f506 100644
--- a/README.md
+++ b/README.md
@@ -76,7 +76,7 @@ See the [samples](https://github.com/apache/dubbo-go-samples) 
for detailed infor
 ![dubbo-go-architecture](./doc/imgs/arc.png)
 
 - **RPC Protocols**: Triple, gRPC compatible and HTTP-friendly
-- **Service Discovery**: Nacos, Zookeeper, Etcd, Consul.
+- **Service Discovery**: Nacos, Zookeeper, Etcd, Polaris-mesh, Consul.
 - **Load Balance**: Adaptive, Random, RoundRobin, LeastActive, ConsistentHash
 - **Traffic Management**: traffic split, timeout, rate limiting, canary release
 - **Configuration**: yaml file, dynamic configuration(Nacos, Zookeeper, etc.).
diff --git a/cluster/router/polaris/default.go 
b/cluster/router/polaris/default.go
new file mode 100644
index 000000000..2797a648b
--- /dev/null
+++ b/cluster/router/polaris/default.go
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package polaris
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/common/constant"
+       "dubbo.apache.org/dubbo-go/v3/common/extension"
+)
+
+func init() {
+       extension.SetRouterFactory(constant.PluginPolarisRouterFactory, 
NewPolarisRouterFactory)
+}
diff --git a/cluster/router/polaris/factory.go 
b/cluster/router/polaris/factory.go
new file mode 100644
index 000000000..76d9cae36
--- /dev/null
+++ b/cluster/router/polaris/factory.go
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package polaris
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/cluster/router"
+)
+
+// RouteFactory router factory
+type RouteFactory struct{}
+
+// NewPolarisRouterFactory constructs a new PriorityRouterFactory
+func NewPolarisRouterFactory() router.PriorityRouterFactory {
+       return &RouteFactory{}
+}
+
+// NewPriorityRouter construct a new PriorityRouter
+func (f *RouteFactory) NewPriorityRouter() (router.PriorityRouter, error) {
+       return newPolarisRouter()
+}
diff --git a/cluster/router/polaris/router.go b/cluster/router/polaris/router.go
new file mode 100644
index 000000000..6bcb1f9ce
--- /dev/null
+++ b/cluster/router/polaris/router.go
@@ -0,0 +1,331 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package polaris
+
+import (
+       "context"
+       "errors"
+       "fmt"
+       "strings"
+       "sync"
+       "time"
+)
+
+import (
+       "github.com/dubbogo/gost/log/logger"
+
+       "github.com/polarismesh/polaris-go"
+       "github.com/polarismesh/polaris-go/pkg/model"
+       v1 "github.com/polarismesh/polaris-go/pkg/model/pb/v1"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/cluster/router"
+       "dubbo.apache.org/dubbo-go/v3/common"
+       "dubbo.apache.org/dubbo-go/v3/common/constant"
+       "dubbo.apache.org/dubbo-go/v3/config"
+       "dubbo.apache.org/dubbo-go/v3/protocol/base"
+       remotingpolaris "dubbo.apache.org/dubbo-go/v3/remoting/polaris"
+       "dubbo.apache.org/dubbo-go/v3/remoting/polaris/parser"
+)
+
+var (
+       _ router.PriorityRouter = (*polarisRouter)(nil)
+)
+
+var (
+       ErrorPolarisServiceRouteRuleEmpty = errors.New("service route rule is 
empty")
+)
+
+func newPolarisRouter() (*polarisRouter, error) {
+       if err := remotingpolaris.Check(); errors.Is(err, 
remotingpolaris.ErrorNoOpenPolarisAbility) {
+               return &polarisRouter{
+                       openRoute: false,
+               }, nil
+       }
+
+       routerAPI, err := remotingpolaris.GetRouterAPI()
+       if err != nil {
+               return nil, err
+       }
+       consumerAPI, err := remotingpolaris.GetConsumerAPI()
+       if err != nil {
+               return nil, err
+       }
+
+       return &polarisRouter{
+               openRoute:   true,
+               routerAPI:   routerAPI,
+               consumerAPI: consumerAPI,
+       }, nil
+}
+
+type polarisRouter struct {
+       openRoute bool
+
+       routerAPI   polaris.RouterAPI
+       consumerAPI polaris.ConsumerAPI
+
+       cancel context.CancelFunc
+
+       lock      sync.RWMutex
+       instances map[string]model.Instance
+}
+
+// Route Determine the target invokers list.
+func (p *polarisRouter) Route(invokers []base.Invoker, url *common.URL,
+       invoaction base.Invocation) []base.Invoker {
+
+       if !p.openRoute {
+               logger.Debug("[Router][Polaris] not open polaris route ability")
+               return invokers
+       }
+
+       if len(invokers) == 0 {
+               logger.Warn("[Router][Polaris] invokers from previous router is 
empty")
+               return invokers
+       }
+
+       service := getService(url)
+       instanceMap := p.buildInstanceMap(service)
+       if len(instanceMap) == 0 {
+               return invokers
+       }
+
+       invokersMap := make(map[string]base.Invoker, len(invokers))
+       targetIns := make([]model.Instance, 0, len(invokers))
+       for i := range invokers {
+               invoker := invokers[i]
+               instanceID := 
invoker.GetURL().GetParam(constant.PolarisInstanceID, "")
+               if len(instanceID) == 0 {
+                       continue
+               }
+               invokersMap[instanceID] = invoker
+               if val, ok := instanceMap[instanceID]; ok {
+                       targetIns = append(targetIns, val)
+               }
+       }
+
+       req, err := p.buildRouteRequest(service, url, invoaction)
+       if err != nil {
+               return invokers
+       }
+       req.DstInstances = model.NewDefaultServiceInstances(model.ServiceInfo{
+               Service:   service,
+               Namespace: remotingpolaris.GetNamespace(),
+       }, targetIns)
+
+       resp, err := p.routerAPI.ProcessRouters(&req)
+       if err != nil {
+               return invokers
+       }
+
+       ret := make([]base.Invoker, 0, len(resp.GetInstances()))
+       for i := range resp.GetInstances() {
+               if val, ok := invokersMap[resp.GetInstances()[i].GetId()]; ok {
+                       ret = append(ret, val)
+               }
+       }
+
+       return ret
+}
+
+func getService(url *common.URL) string {
+       applicationMode := false
+       for _, item := range config.GetRootConfig().Registries {
+               if item.Protocol == constant.PolarisKey {
+                       applicationMode = item.RegistryType == 
constant.ServiceKey
+               }
+       }
+
+       service := url.Interface()
+       if applicationMode {
+               service = config.GetApplicationConfig().Name
+       }
+
+       return service
+}
+
+func (p *polarisRouter) buildRouteRequest(svc string, url *common.URL,
+       invocation base.Invocation) (polaris.ProcessRoutersRequest, error) {
+
+       routeReq := polaris.ProcessRoutersRequest{
+               ProcessRoutersRequest: model.ProcessRoutersRequest{
+                       SourceService: model.ServiceInfo{
+                               Metadata: map[string]string{},
+                       },
+               },
+       }
+
+       attachement := invocation.Attachments()
+       arguments := invocation.Arguments()
+
+       labels, err := p.buildTrafficLabels(svc)
+       if err != nil {
+               return polaris.ProcessRoutersRequest{}, err
+       }
+
+       for i := range labels {
+               label := labels[i]
+               if strings.Compare(label, model.LabelKeyPath) == 0 {
+                       
routeReq.AddArguments(model.BuildPathArgument(getInvokeMethod(url, invocation)))
+                       continue
+               }
+               if strings.HasPrefix(label, model.LabelKeyHeader) {
+                       if val, ok := attachement[strings.TrimPrefix(label, 
model.LabelKeyHeader)]; ok {
+                               routeReq.SourceService.Metadata[label] = 
fmt.Sprintf("%+v", val)
+                               
routeReq.AddArguments(model.BuildArgumentFromLabel(label, fmt.Sprintf("%+v", 
val)))
+                       }
+               }
+               if strings.HasPrefix(label, model.LabelKeyQuery) {
+                       if val := parser.ParseArgumentsByExpression(label, 
arguments); val != nil {
+                               
routeReq.AddArguments(model.BuildArgumentFromLabel(label, fmt.Sprintf("%+v", 
val)))
+                       }
+               }
+       }
+
+       return routeReq, nil
+}
+
+func (p *polarisRouter) buildTrafficLabels(svc string) ([]string, error) {
+       req := &model.GetServiceRuleRequest{}
+       req.Namespace = remotingpolaris.GetNamespace()
+       req.Service = svc
+       req.SetTimeout(time.Second)
+       engine := p.routerAPI.SDKContext().GetEngine()
+       resp, err := engine.SyncGetServiceRule(model.EventRouting, req)
+       if err != nil {
+               logger.Errorf("[Router][Polaris] ns:%s svc:%s get route rule 
fail : %+v", req.GetNamespace(), req.GetService(), err)
+               return nil, err
+       }
+
+       if resp == nil || resp.GetValue() == nil {
+               logger.Errorf("[Router][Polaris] ns:%s svc:%s get route rule 
empty", req.GetNamespace(), req.GetService())
+               return nil, ErrorPolarisServiceRouteRuleEmpty
+       }
+
+       routeRule := resp.GetValue().(*v1.Routing)
+       labels := make([]string, 0, 4)
+       labels = append(labels, collectRouteLabels(routeRule.GetInbounds())...)
+       labels = append(labels, collectRouteLabels(routeRule.GetInbounds())...)
+
+       return labels, nil
+}
+
+func getInvokeMethod(url *common.URL, invoaction base.Invocation) string {
+       applicationMode := false
+       for _, item := range config.GetRootConfig().Registries {
+               if item.Protocol == constant.PolarisKey {
+                       applicationMode = item.RegistryType == 
constant.ServiceKey
+               }
+       }
+
+       method := invoaction.MethodName()
+       if applicationMode {
+               method = url.Interface() + "/" + invoaction.MethodName()
+       }
+
+       return method
+}
+
+func collectRouteLabels(routings []*v1.Route) []string {
+       ret := make([]string, 0, 4)
+
+       for i := range routings {
+               route := routings[i]
+               sources := route.GetSources()
+               for p := range sources {
+                       source := sources[p]
+                       for k := range source.GetMetadata() {
+                               ret = append(ret, k)
+                       }
+               }
+       }
+
+       return ret
+}
+
+func (p *polarisRouter) buildInstanceMap(svc string) map[string]model.Instance 
{
+       resp, err := 
p.consumerAPI.GetAllInstances(&polaris.GetAllInstancesRequest{
+               GetAllInstancesRequest: model.GetAllInstancesRequest{
+                       Service:   svc,
+                       Namespace: remotingpolaris.GetNamespace(),
+               },
+       })
+       if err != nil {
+               logger.Errorf("[Router][Polaris] ns:%s svc:%s get all instances 
fail : %+v", remotingpolaris.GetNamespace(), svc, err)
+               return nil
+       }
+
+       ret := make(map[string]model.Instance, len(resp.GetInstances()))
+
+       for i := range resp.GetInstances() {
+               ret[resp.GetInstances()[i].GetId()] = resp.GetInstances()[i]
+       }
+
+       return ret
+}
+
+// URL Return URL in router
+func (p *polarisRouter) URL() *common.URL {
+       return nil
+}
+
+// Priority Return Priority in router
+// 0 to ^int(0) is better
+func (p *polarisRouter) Priority() int64 {
+       return 0
+}
+
+// Notify the router the invoker list
+func (p *polarisRouter) Notify(invokers []base.Invoker) {
+       if !p.openRoute {
+               return
+       }
+       if len(invokers) == 0 {
+               return
+       }
+       service := getService(invokers[0].GetURL())
+       if service == "" {
+               logger.Error("url service is empty")
+               return
+       }
+
+       req := &model.GetServiceRuleRequest{}
+       req.Namespace = remotingpolaris.GetNamespace()
+       req.Service = service
+       req.SetTimeout(time.Second)
+
+       engine := p.routerAPI.SDKContext().GetEngine()
+       _, err := engine.SyncGetServiceRule(model.EventRouting, req)
+       if err != nil {
+               logger.Errorf("[Router][Polaris] ns:%s svc:%s get route rule 
fail : %+v", req.GetNamespace(), req.GetService(), err)
+               return
+       }
+
+       _, err = p.consumerAPI.GetAllInstances(&polaris.GetAllInstancesRequest{
+               GetAllInstancesRequest: model.GetAllInstancesRequest{
+                       Service:   service,
+                       Namespace: remotingpolaris.GetNamespace(),
+               },
+       })
+       if err != nil {
+               logger.Errorf("[Router][Polaris] ns:%s svc:%s get all instances 
fail : %+v", req.GetNamespace(), req.GetService(), err)
+               return
+       }
+}
diff --git a/common/constant/polaris_key.go b/common/constant/polaris_key.go
new file mode 100644
index 000000000..ea7d0fa23
--- /dev/null
+++ b/common/constant/polaris_key.go
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package constant
+
+const (
+       PolarisKey                  = "polaris"
+       PolarisDefaultRoleType      = 3
+       PolarisServiceToken         = "token"
+       PolarisServiceNameSeparator = ":"
+       PolarisDubboPath            = "DUBBOPATH"
+       PolarisInstanceID           = "polaris.instanceID"
+       PolarisDefaultNamespace     = "default"
+       PolarisDubboGroup           = "dubbo.group"
+       PolarisClientName           = "polaris-client"
+)
+
+const (
+       PolarisInstanceHealthStatus   = "healthstatus"
+       PolarisInstanceIsolatedStatus = "isolated"
+       PolarisCIrcuirbreakerStatus   = "circuitbreaker"
+)
+
+const (
+       PluginPolarisTpsLimiter    = "polaris-limit"
+       PluginPolarisRouterFactory = "polaris-router"
+       PluginPolarisReportFilter  = "polaris-report"
+)
diff --git a/filter/filter_impl/import.go b/filter/filter_impl/import.go
index a647242db..277b5f56e 100644
--- a/filter/filter_impl/import.go
+++ b/filter/filter_impl/import.go
@@ -31,6 +31,7 @@ import (
        _ "dubbo.apache.org/dubbo-go/v3/filter/graceful_shutdown"
        _ "dubbo.apache.org/dubbo-go/v3/filter/hystrix"
        _ "dubbo.apache.org/dubbo-go/v3/filter/metrics"
+       _ "dubbo.apache.org/dubbo-go/v3/filter/polaris/limit"
        _ "dubbo.apache.org/dubbo-go/v3/filter/seata"
        _ "dubbo.apache.org/dubbo-go/v3/filter/sentinel"
        _ "dubbo.apache.org/dubbo-go/v3/filter/token"
diff --git a/filter/polaris/limit/default.go b/filter/polaris/limit/default.go
new file mode 100644
index 000000000..5f40295c4
--- /dev/null
+++ b/filter/polaris/limit/default.go
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package limit
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/common/constant"
+       "dubbo.apache.org/dubbo-go/v3/common/extension"
+       "dubbo.apache.org/dubbo-go/v3/filter"
+)
+
+func init() {
+       extension.SetTpsLimiter(constant.PluginPolarisTpsLimiter, func() 
filter.TpsLimiter {
+               return &polarisTpsLimiter{}
+       })
+}
diff --git a/filter/polaris/limit/limiter.go b/filter/polaris/limit/limiter.go
new file mode 100644
index 000000000..d482aa11a
--- /dev/null
+++ b/filter/polaris/limit/limiter.go
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package limit
+
+import (
+       "errors"
+       "fmt"
+       "time"
+)
+
+import (
+       "github.com/dubbogo/gost/log/logger"
+
+       "github.com/polarismesh/polaris-go"
+       "github.com/polarismesh/polaris-go/pkg/flow/data"
+       "github.com/polarismesh/polaris-go/pkg/model"
+       v1 "github.com/polarismesh/polaris-go/pkg/model/pb/v1"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/common"
+       "dubbo.apache.org/dubbo-go/v3/common/constant"
+       "dubbo.apache.org/dubbo-go/v3/config"
+       "dubbo.apache.org/dubbo-go/v3/protocol/base"
+       remotingpolaris "dubbo.apache.org/dubbo-go/v3/remoting/polaris"
+       "dubbo.apache.org/dubbo-go/v3/remoting/polaris/parser"
+)
+
+type polarisTpsLimiter struct {
+       limitAPI polaris.LimitAPI
+}
+
+func (pl *polarisTpsLimiter) IsAllowable(url *common.URL, invocation 
base.Invocation) bool {
+       if err := remotingpolaris.Check(); errors.Is(err, 
remotingpolaris.ErrorNoOpenPolarisAbility) {
+               logger.Debug("[TpsLimiter][Polaris] not open polaris ratelimit 
ability")
+               return true
+       }
+
+       var err error
+
+       pl.limitAPI, err = remotingpolaris.GetLimiterAPI()
+       if err != nil {
+               logger.Error("[TpsLimiter][Polaris] create polaris LimitAPI 
fail : %+v", err)
+               return true
+       }
+
+       req := pl.buildQuotaRequest(url, invocation)
+       if req == nil {
+               return true
+       }
+       logger.Debugf("[TpsLimiter][Polaris] quota req : %+v", req)
+
+       resp, err := pl.limitAPI.GetQuota(req)
+       if err != nil {
+               logger.Error("[TpsLimiter][Polaris] ns:%s svc:%s get quota fail 
: %+v", remotingpolaris.GetNamespace(), url.Service(), err)
+               return true
+       }
+
+       return resp.Get().Code == model.QuotaResultOk
+}
+
+func (pl *polarisTpsLimiter) buildQuotaRequest(url *common.URL, invoaction 
base.Invocation) polaris.QuotaRequest {
+       ns := remotingpolaris.GetNamespace()
+       applicationMode := false
+       for _, item := range config.GetRootConfig().Registries {
+               if item.Protocol == constant.PolarisKey {
+                       applicationMode = item.RegistryType == 
constant.ServiceKey
+               }
+       }
+
+       svc := url.Interface()
+       method := invoaction.MethodName()
+       if applicationMode {
+               svc = config.GetApplicationConfig().Name
+               method = url.Interface() + "/" + invoaction.MethodName()
+       }
+
+       req := polaris.NewQuotaRequest()
+       req.SetNamespace(ns)
+       req.SetService(svc)
+       req.SetMethod(method)
+
+       matchs, ok := pl.buildArguments(req.(*model.QuotaRequestImpl))
+       if !ok {
+               return nil
+       }
+
+       attachement := invoaction.Attachments()
+       arguments := invoaction.Arguments()
+
+       for i := range matchs {
+               item := matchs[i]
+               switch item.GetType() {
+               case v1.MatchArgument_HEADER:
+                       if val, ok := attachement[item.GetKey()]; ok {
+                               
req.AddArgument(model.BuildHeaderArgument(item.GetKey(), fmt.Sprintf("%+v", 
val)))
+                       }
+               case v1.MatchArgument_QUERY:
+                       if val := 
parser.ParseArgumentsByExpression(item.GetKey(), arguments); val != nil {
+                               
req.AddArgument(model.BuildQueryArgument(item.GetKey(), fmt.Sprintf("%+v", 
val)))
+                       }
+               case v1.MatchArgument_CALLER_IP:
+                       callerIp := url.GetParam(constant.RemoteAddr, "")
+                       if len(callerIp) != 0 {
+                               
req.AddArgument(model.BuildCallerIPArgument(callerIp))
+                       }
+               case model.ArgumentTypeCallerService:
+               }
+       }
+
+       return req
+}
+
+func (pl *polarisTpsLimiter) buildArguments(req *model.QuotaRequestImpl) 
([]*v1.MatchArgument, bool) {
+       engine := pl.limitAPI.SDKContext().GetEngine()
+
+       getRuleReq := &data.CommonRateLimitRequest{
+               DstService: model.ServiceKey{
+                       Namespace: req.GetNamespace(),
+                       Service:   req.GetService(),
+               },
+               Trigger: model.NotifyTrigger{
+                       EnableDstRateLimit: true,
+               },
+               ControlParam: model.ControlParam{
+                       Timeout: time.Millisecond * 500,
+               },
+       }
+
+       if err := engine.SyncGetResources(getRuleReq); err != nil {
+               logger.Error("[TpsLimiter][Polaris] ns:%s svc:%s get RateLimit 
Rule fail : %+v", req.GetNamespace(), req.GetService(), err)
+               return nil, false
+       }
+
+       svcRule := getRuleReq.RateLimitRule
+       if svcRule == nil || svcRule.GetValue() == nil {
+               logger.Warnf("[TpsLimiter][Polaris] ns:%s svc:%s get RateLimit 
Rule is nil", req.GetNamespace(), req.GetService())
+               return nil, false
+       }
+
+       rules, ok := svcRule.GetValue().(*v1.RateLimit)
+       if !ok {
+               logger.Error("[TpsLimiter][Polaris] ns:%s svc:%s get RateLimit 
Rule invalid", req.GetNamespace(), req.GetService())
+               return nil, false
+       }
+
+       ret := make([]*v1.MatchArgument, 0, 4)
+       for i := range rules.GetRules() {
+               rule := rules.GetRules()[i]
+               if len(rule.GetArguments()) == 0 {
+                       continue
+               }
+
+               ret = append(ret, rule.Arguments...)
+       }
+
+       return ret, true
+}
diff --git a/go.mod b/go.mod
index 342562487..dbc74af64 100644
--- a/go.mod
+++ b/go.mod
@@ -37,8 +37,10 @@ require (
        github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
        github.com/nacos-group/nacos-sdk-go/v2 v2.2.2
        github.com/natefinch/lumberjack v2.0.0+incompatible
+       github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852
        github.com/opentracing/opentracing-go v1.2.0
        github.com/pkg/errors v0.9.1
+       github.com/polarismesh/polaris-go v1.3.0
        github.com/prometheus/client_golang v1.13.0
        github.com/prometheus/common v0.37.0
        github.com/sirupsen/logrus v1.8.1
@@ -89,6 +91,7 @@ require (
        github.com/gorilla/websocket v1.4.2 // indirect
        github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
        github.com/hashicorp/errwrap v1.1.0 // indirect
+       github.com/hashicorp/go-multierror v1.1.1 // indirect
        github.com/jmespath/go-jmespath v0.4.0 // indirect
        github.com/json-iterator/go v1.1.12 // indirect
        github.com/k0kubun/pp v3.0.1+incompatible // indirect
@@ -97,6 +100,7 @@ require (
        github.com/mattn/go-isatty v0.0.16 // indirect
        github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
        github.com/mitchellh/copystructure v1.2.0 // indirect
+       github.com/mitchellh/go-homedir v1.1.0 // indirect
        github.com/mitchellh/reflectwalk v1.0.2 // indirect
        github.com/modern-go/reflect2 v1.0.2 // indirect
        github.com/mschoch/smat v0.2.0 // indirect
@@ -108,6 +112,7 @@ require (
        github.com/prometheus/client_model v0.3.0 // indirect
        github.com/prometheus/procfs v0.8.0 // indirect
        github.com/shirou/gopsutil/v3 v3.22.2 // indirect
+       github.com/spaolacci/murmur3 v1.1.0 // indirect
        github.com/stretchr/objx v0.5.0 // indirect
        github.com/tklauser/go-sysconf v0.3.10 // indirect
        github.com/tklauser/numcpus v0.4.0 // indirect
diff --git a/go.sum b/go.sum
index 661bb6fec..c3bfc201f 100644
--- a/go.sum
+++ b/go.sum
@@ -49,6 +49,8 @@ github.com/Workiva/go-datastructures v1.0.52 
h1:PLSK6pwn8mYdaoaCZEMsXBpBotr4HHn9
 github.com/Workiva/go-datastructures v1.0.52/go.mod 
h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA=
 github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 
h1:rFw4nCn9iMW+Vajsk51NtYIcwSTkXr+JGrMd36kTDJw=
 github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod 
h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
+github.com/agiledragon/gomonkey v2.0.2+incompatible 
h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw=
+github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod 
h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
 github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod 
h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod 
h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod 
h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@@ -306,6 +308,13 @@ github.com/golang/snappy 
v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l
 github.com/golang/snappy v0.0.1/go.mod 
h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 github.com/golang/snappy v0.0.4/go.mod 
h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac/go.mod 
h1:P32wAyui1PQ58Oce/KYkOqQv8cVw1zAapXOl+dRFGbc=
+github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod 
h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg=
+github.com/gonum/integrate v0.0.0-20181209220457-a422b5c0fdf2/go.mod 
h1:pDgmNM6seYpwvPos3q+zxlXMsbve6mOIPucUnUOrI7Y=
+github.com/gonum/internal v0.0.0-20181124074243-f884aa714029/go.mod 
h1:Pu4dmpkhSyOzRwuXkOgAvijx4o+4YMUJJo9OvPYMkks=
+github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9/go.mod 
h1:XA3DeT6rxh2EAE789SSiSJNqxPaC0aE9J8NTOI0Jo/A=
+github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod 
h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw=
+github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b/go.mod 
h1:Z4GIJBJO3Wa4gD4vbwQxXXZ+WHmW6E9ixmNrwvs0iZs=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod 
h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
 github.com/google/btree v1.0.0/go.mod 
h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -385,6 +394,8 @@ github.com/hashicorp/go-immutable-radix v1.0.0/go.mod 
h1:0y9vanUI8NX6FsYoO3zeMjh
 github.com/hashicorp/go-msgpack v0.5.3/go.mod 
h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
 github.com/hashicorp/go-multierror v1.0.0/go.mod 
h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
 github.com/hashicorp/go-multierror v1.1.0/go.mod 
h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
+github.com/hashicorp/go-multierror v1.1.1 
h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
+github.com/hashicorp/go-multierror v1.1.1/go.mod 
h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
 github.com/hashicorp/go-plugin v1.0.1/go.mod 
h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
 github.com/hashicorp/go-retryablehttp v0.5.4/go.mod 
h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
 github.com/hashicorp/go-rootcerts v1.0.0/go.mod 
h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
@@ -521,6 +532,7 @@ github.com/mitchellh/copystructure v1.0.0/go.mod 
h1:SNtv71yrdKgLRyLFxmLdkAbkKEFW
 github.com/mitchellh/copystructure v1.2.0 
h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
 github.com/mitchellh/copystructure v1.2.0/go.mod 
h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
 github.com/mitchellh/go-homedir v1.0.0/go.mod 
h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-homedir v1.1.0 
h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
 github.com/mitchellh/go-homedir v1.1.0/go.mod 
h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
 github.com/mitchellh/go-testing-interface 
v0.0.0-20171004221916-a61a99592b77/go.mod 
h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
 github.com/mitchellh/go-testing-interface v1.0.0/go.mod 
h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
@@ -564,6 +576,8 @@ github.com/oklog/oklog v0.3.2/go.mod 
h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtb
 github.com/oklog/run v1.0.0/go.mod 
h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
 github.com/oklog/ulid v1.3.1/go.mod 
h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
 github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod 
h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
+github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 
h1:Yl0tPBa8QPjGmesFh1D0rDy+q1Twx6FyU7VWHi8wZbI=
+github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod 
h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4=
 github.com/onsi/ginkgo v1.6.0/go.mod 
h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.7.0/go.mod 
h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/gomega v1.4.3/go.mod 
h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@@ -600,6 +614,8 @@ github.com/pkg/errors v0.9.1/go.mod 
h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
 github.com/pkg/profile v1.2.1/go.mod 
h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
 github.com/pmezard/go-difflib v1.0.0 
h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod 
h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/polarismesh/polaris-go v1.3.0 
h1:KZKX//ow4OPPoS5+s7h07ptprg+2AcNVGrN6WakC9QM=
+github.com/polarismesh/polaris-go v1.3.0/go.mod 
h1:HsN0ierETIujHpmnnYJ3qkwQw4QGAECuHvBZTDaw1tI=
 github.com/posener/complete v1.1.1/go.mod 
h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
 github.com/posener/complete v1.2.3/go.mod 
h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
 github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c 
h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
@@ -686,6 +702,8 @@ github.com/soheilhy/cmux 
v0.1.5-0.20210205191134-5ec6847320e5 h1:GJTW+uNMIV1RKwo
 github.com/soheilhy/cmux v0.1.5-0.20210205191134-5ec6847320e5/go.mod 
h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
 github.com/sony/gobreaker v0.4.1/go.mod 
h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod 
h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/spaolacci/murmur3 v1.1.0 
h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
+github.com/spaolacci/murmur3 v1.1.0/go.mod 
h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spf13/afero v1.1.2/go.mod 
h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
 github.com/spf13/cast v1.3.0/go.mod 
h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/cobra v0.0.3/go.mod 
h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
@@ -934,6 +952,7 @@ golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod 
h1:9nx3DQGgdP8bBQD5qx
 golang.org/x/net v0.0.0-20211105192438-b53810dc28af/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod 
h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod 
h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod 
h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod 
h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
 golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
@@ -1033,6 +1052,7 @@ golang.org/x/sys 
v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1191,6 +1211,7 @@ google.golang.org/genproto 
v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6D
 google.golang.org/genproto v0.0.0-20210106152847-07624b53cd92/go.mod 
h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod 
h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
 google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247/go.mod 
h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220504150022-98cd25cafc72/go.mod 
h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
 google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d 
h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY=
 google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod 
h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4=
 google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d 
h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q=
@@ -1221,6 +1242,8 @@ google.golang.org/grpc v1.33.1/go.mod 
h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp
 google.golang.org/grpc v1.36.0/go.mod 
h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/grpc v1.38.0/go.mod 
h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
 google.golang.org/grpc v1.40.0/go.mod 
h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
+google.golang.org/grpc v1.46.0/go.mod 
h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc v1.46.2/go.mod 
h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
 google.golang.org/grpc v1.48.0/go.mod 
h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
 google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
 google.golang.org/grpc v1.59.0/go.mod 
h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
@@ -1237,6 +1260,7 @@ google.golang.org/protobuf v1.25.0/go.mod 
h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
 google.golang.org/protobuf v1.26.0-rc.1/go.mod 
h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod 
h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 google.golang.org/protobuf v1.27.1/go.mod 
h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.0/go.mod 
h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 google.golang.org/protobuf v1.31.0 
h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
 google.golang.org/protobuf v1.31.0/go.mod 
h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod 
h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
diff --git a/imports/imports.go b/imports/imports.go
index 61fd206dc..35743fd88 100644
--- a/imports/imports.go
+++ b/imports/imports.go
@@ -37,6 +37,7 @@ import (
        _ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance/random"
        _ "dubbo.apache.org/dubbo-go/v3/cluster/loadbalance/roundrobin"
        _ "dubbo.apache.org/dubbo-go/v3/cluster/router/condition"
+       _ "dubbo.apache.org/dubbo-go/v3/cluster/router/polaris"
        _ "dubbo.apache.org/dubbo-go/v3/cluster/router/script"
        _ "dubbo.apache.org/dubbo-go/v3/cluster/router/tag"
        _ "dubbo.apache.org/dubbo-go/v3/config_center/nacos"
@@ -53,6 +54,7 @@ import (
        _ "dubbo.apache.org/dubbo-go/v3/filter/hystrix"
        _ "dubbo.apache.org/dubbo-go/v3/filter/metrics"
        _ "dubbo.apache.org/dubbo-go/v3/filter/otel/trace"
+       _ "dubbo.apache.org/dubbo-go/v3/filter/polaris/limit"
        _ "dubbo.apache.org/dubbo-go/v3/filter/seata"
        _ "dubbo.apache.org/dubbo-go/v3/filter/sentinel"
        _ "dubbo.apache.org/dubbo-go/v3/filter/token"
@@ -80,6 +82,7 @@ import (
        _ "dubbo.apache.org/dubbo-go/v3/registry/directory"
        _ "dubbo.apache.org/dubbo-go/v3/registry/etcdv3"
        _ "dubbo.apache.org/dubbo-go/v3/registry/nacos"
+       _ "dubbo.apache.org/dubbo-go/v3/registry/polaris"
        _ "dubbo.apache.org/dubbo-go/v3/registry/protocol"
        _ "dubbo.apache.org/dubbo-go/v3/registry/servicediscovery"
        _ "dubbo.apache.org/dubbo-go/v3/registry/zookeeper"
diff --git a/registry/options.go b/registry/options.go
index eac366886..e9f1fb285 100644
--- a/registry/options.go
+++ b/registry/options.go
@@ -70,6 +70,12 @@ func WithNacos() Option {
        }
 }
 
+func WithPolaris() Option {
+       return func(opts *Options) {
+               opts.Registry.Protocol = constant.PolarisKey
+       }
+}
+
 func WithXDS() Option {
        return func(opts *Options) {
                opts.Registry.Protocol = constant.XDSRegistryKey
diff --git a/registry/polaris/core.go b/registry/polaris/core.go
new file mode 100644
index 000000000..1db3ef04f
--- /dev/null
+++ b/registry/polaris/core.go
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package polaris
+
+import (
+       "sync"
+       "time"
+)
+
+import (
+       api "github.com/polarismesh/polaris-go"
+       internalapi "github.com/polarismesh/polaris-go/api"
+       "github.com/polarismesh/polaris-go/pkg/model"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/config_center"
+       "dubbo.apache.org/dubbo-go/v3/remoting"
+)
+
+type item func(remoting.EventType, []model.Instance)
+
+type PolarisServiceWatcher struct {
+       consumer       api.ConsumerAPI
+       subscribeParam *api.WatchServiceRequest
+       lock           *sync.RWMutex
+       subscribers    []item
+       execOnce       *sync.Once
+}
+
+// newPolarisWatcher create PolarisServiceWatcher to do watch service action
+func newPolarisWatcher(param *api.WatchServiceRequest, consumer 
api.ConsumerAPI) (*PolarisServiceWatcher, error) {
+       watcher := &PolarisServiceWatcher{
+               subscribeParam: param,
+               consumer:       consumer,
+               lock:           &sync.RWMutex{},
+               subscribers:    make([]item, 0),
+               execOnce:       &sync.Once{},
+       }
+       return watcher, nil
+}
+
+// AddSubscriber add subscriber into watcher's subscribers
+func (watcher *PolarisServiceWatcher) AddSubscriber(subscriber 
func(remoting.EventType, []model.Instance)) {
+
+       watcher.lock.Lock()
+       watcher.lazyRun()
+       defer watcher.lock.Unlock()
+
+       watcher.subscribers = append(watcher.subscribers, subscriber)
+}
+
+// lazyRun Delayed execution, only triggered when AddSubscriber is called, and 
will only be executed once
+func (watcher *PolarisServiceWatcher) lazyRun() {
+       watcher.execOnce.Do(func() {
+               go watcher.startWatch()
+       })
+}
+
+// startWatch start run work to watch target service by polaris
+func (watcher *PolarisServiceWatcher) startWatch() {
+       for {
+               resp, err := 
watcher.consumer.WatchService(watcher.subscribeParam)
+               if err != nil {
+                       time.Sleep(time.Duration(500 * time.Millisecond))
+                       continue
+               }
+               watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{
+                       Value:      resp.GetAllInstancesResp.Instances,
+                       ConfigType: remoting.EventTypeAdd,
+               })
+
+               for event := range resp.EventChannel {
+                       eType := event.GetSubScribeEventType()
+                       if eType == internalapi.EventInstance {
+                               insEvent := event.(*model.InstanceEvent)
+
+                               if insEvent.AddEvent != nil {
+                                       
watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{
+                                               Value:      
insEvent.AddEvent.Instances,
+                                               ConfigType: 
remoting.EventTypeAdd,
+                                       })
+                               }
+                               if insEvent.UpdateEvent != nil {
+                                       instances := make([]model.Instance, 
len(insEvent.UpdateEvent.UpdateList))
+                                       for i := range 
insEvent.UpdateEvent.UpdateList {
+                                               instances[i] = 
insEvent.UpdateEvent.UpdateList[i].After
+                                       }
+                                       
watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{
+                                               Value:      instances,
+                                               ConfigType: 
remoting.EventTypeUpdate,
+                                       })
+                               }
+                               if insEvent.DeleteEvent != nil {
+                                       
watcher.notifyAllSubscriber(&config_center.ConfigChangeEvent{
+                                               Value:      
insEvent.DeleteEvent.Instances,
+                                               ConfigType: 
remoting.EventTypeDel,
+                                       })
+                               }
+                       }
+               }
+
+       }
+}
+
+// notifyAllSubscriber notify config_center.ConfigChangeEvent to all subscriber
+func (watcher *PolarisServiceWatcher) notifyAllSubscriber(event 
*config_center.ConfigChangeEvent) {
+       watcher.lock.RLock()
+       defer watcher.lock.RUnlock()
+
+       for i := 0; i < len(watcher.subscribers); i++ {
+               subscriber := watcher.subscribers[i]
+               subscriber(event.ConfigType, event.Value.([]model.Instance))
+       }
+
+}
diff --git a/registry/polaris/doc.go b/registry/polaris/doc.go
new file mode 100644
index 000000000..4645a2776
--- /dev/null
+++ b/registry/polaris/doc.go
@@ -0,0 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Package polaris implements registry around polaris.
+package polaris
diff --git a/registry/polaris/listener.go b/registry/polaris/listener.go
new file mode 100644
index 000000000..e39ca995d
--- /dev/null
+++ b/registry/polaris/listener.go
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package polaris
+
+import (
+       "fmt"
+       "net/url"
+       "strconv"
+)
+
+import (
+       gxchan "github.com/dubbogo/gost/container/chan"
+       "github.com/dubbogo/gost/log/logger"
+
+       perrors "github.com/pkg/errors"
+
+       "github.com/polarismesh/polaris-go/pkg/model"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/common"
+       "dubbo.apache.org/dubbo-go/v3/common/constant"
+       "dubbo.apache.org/dubbo-go/v3/config_center"
+       "dubbo.apache.org/dubbo-go/v3/registry"
+       "dubbo.apache.org/dubbo-go/v3/remoting"
+)
+
+type polarisListener struct {
+       watcher *PolarisServiceWatcher
+       events  *gxchan.UnboundedChan
+       closeCh chan struct{}
+}
+
+// NewPolarisListener new polaris listener
+func NewPolarisListener(watcher *PolarisServiceWatcher) (*polarisListener, 
error) {
+       listener := &polarisListener{
+               watcher: watcher,
+               events:  gxchan.NewUnboundedChan(32),
+               closeCh: make(chan struct{}),
+       }
+       listener.startListen()
+       return listener, nil
+}
+func (pl *polarisListener) startListen() {
+       pl.watcher.AddSubscriber(func(et remoting.EventType, ins 
[]model.Instance) {
+               for i := range ins {
+                       pl.events.In() <- 
&config_center.ConfigChangeEvent{Value: ins[i], ConfigType: et}
+               }
+       })
+}
+
+// Next returns next service event once received
+func (pl *polarisListener) Next() (*registry.ServiceEvent, error) {
+       for {
+               select {
+               case <-pl.closeCh:
+                       logger.Warnf("polaris listener is close")
+                       return nil, perrors.New("listener stopped")
+               case val := <-pl.events.Out():
+                       e, _ := val.(*config_center.ConfigChangeEvent)
+                       logger.Debugf("got polaris event %s", e)
+                       instance := e.Value.(model.Instance)
+                       return &registry.ServiceEvent{Action: e.ConfigType, 
Service: generateUrl(instance)}, nil
+               }
+       }
+}
+
+// Close closes this listener
+func (pl *polarisListener) Close() {
+       // TODO need to add UnWatch in polaris
+       close(pl.closeCh)
+}
+
+func generateUrl(instance model.Instance) *common.URL {
+       if instance.GetMetadata() == nil {
+               logger.Errorf("polaris instance metadata is 
empty,instance:%+v", instance)
+               return nil
+       }
+       path := instance.GetMetadata()["path"]
+       myInterface := instance.GetMetadata()["interface"]
+       if len(path) == 0 && len(myInterface) == 0 {
+               logger.Errorf("polaris instance metadata does not have  both 
path key and interface key,instance:%+v", instance)
+               return nil
+       }
+       if len(path) == 0 && len(myInterface) != 0 {
+               path = "/" + myInterface
+       }
+       protocol := instance.GetProtocol()
+       if len(protocol) == 0 {
+               logger.Errorf("polaris instance metadata does not have protocol 
key,instance:%+v", instance)
+               return nil
+       }
+       urlMap := url.Values{}
+       for k, v := range instance.GetMetadata() {
+               urlMap.Set(k, v)
+       }
+       urlMap.Set(constant.PolarisInstanceID, instance.GetId())
+       urlMap.Set(constant.PolarisInstanceHealthStatus, fmt.Sprintf("%+v", 
instance.IsHealthy()))
+       urlMap.Set(constant.PolarisInstanceIsolatedStatus, fmt.Sprintf("%+v", 
instance.IsIsolated()))
+       instance.GetCircuitBreakerStatus()
+       return common.NewURLWithOptions(
+               common.WithIp(instance.GetHost()),
+               common.WithPort(strconv.Itoa(int(instance.GetPort()))),
+               common.WithProtocol(protocol),
+               common.WithParams(urlMap),
+               common.WithPath(path),
+       )
+}
diff --git a/registry/polaris/registry.go b/registry/polaris/registry.go
new file mode 100644
index 000000000..41f754f10
--- /dev/null
+++ b/registry/polaris/registry.go
@@ -0,0 +1,287 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package polaris
+
+import (
+       "fmt"
+       "strconv"
+       "sync"
+       "time"
+)
+
+import (
+       "github.com/dubbogo/gost/log/logger"
+
+       perrors "github.com/pkg/errors"
+
+       api "github.com/polarismesh/polaris-go"
+       "github.com/polarismesh/polaris-go/pkg/model"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/common"
+       "dubbo.apache.org/dubbo-go/v3/common/constant"
+       "dubbo.apache.org/dubbo-go/v3/common/extension"
+       "dubbo.apache.org/dubbo-go/v3/registry"
+       "dubbo.apache.org/dubbo-go/v3/remoting"
+       "dubbo.apache.org/dubbo-go/v3/remoting/polaris"
+)
+
+const (
+       RegistryConnDelay           = 3
+       defaultHeartbeatIntervalSec = 5
+)
+
+func init() {
+       extension.SetRegistry(constant.PolarisKey, newPolarisRegistry)
+}
+
+// newPolarisRegistry will create new instance
+func newPolarisRegistry(url *common.URL) (registry.Registry, error) {
+       if err := polaris.InitSDKContext(url); err != nil {
+               return &polarisRegistry{}, err
+       }
+
+       providerApi, err := polaris.GetProviderAPI()
+       if err != nil {
+               return nil, err
+       }
+
+       consumerApi, err := polaris.GetConsumerAPI()
+       if err != nil {
+               return nil, err
+       }
+
+       pRegistry := &polarisRegistry{
+               url:          url,
+               namespace:    url.GetParam(constant.RegistryNamespaceKey, 
constant.PolarisDefaultNamespace),
+               provider:     providerApi,
+               consumer:     consumerApi,
+               registryUrls: make([]*common.URL, 0, 4),
+               watchers:     map[string]*PolarisServiceWatcher{},
+       }
+
+       return pRegistry, nil
+}
+
+type polarisRegistry struct {
+       namespace    string
+       url          *common.URL
+       consumer     api.ConsumerAPI
+       provider     api.ProviderAPI
+       lock         sync.RWMutex
+       registryUrls []*common.URL
+       listenerLock sync.RWMutex
+       watchers     map[string]*PolarisServiceWatcher
+}
+
+// Register will register the service @url to its polaris registry center.
+func (pr *polarisRegistry) Register(url *common.URL) error {
+       if getCategory(url) != "providers" {
+               return nil
+       }
+
+       serviceName := url.Interface()
+       request := createRegisterParam(url, serviceName)
+       request.Namespace = pr.namespace
+       resp, err := pr.provider.RegisterInstance(request)
+       if err != nil {
+               return err
+       }
+
+       if resp.Existed {
+               logger.Warnf("instance already regist, namespace:%+v, 
service:%+v, host:%+v, port:%+v",
+                       request.Namespace, request.Service, request.Host, 
request.Port)
+       }
+       url.SetParam(constant.PolarisInstanceID, resp.InstanceID)
+
+       pr.lock.Lock()
+       pr.registryUrls = append(pr.registryUrls, url)
+       pr.lock.Unlock()
+
+       return nil
+}
+
+// UnRegister returns nil if unregister successfully. If not, returns an error.
+func (pr *polarisRegistry) UnRegister(url *common.URL) error {
+       request := createDeregisterParam(url, url.Interface())
+       request.Namespace = pr.namespace
+       if err := pr.provider.Deregister(request); err != nil {
+               return perrors.WithMessagef(err, "fail to 
deregister(conf:%+v)", url)
+       }
+       return nil
+}
+
+// Subscribe returns nil if subscribing registry successfully. If not returns 
an error.
+func (pr *polarisRegistry) Subscribe(url *common.URL, notifyListener 
registry.NotifyListener) error {
+
+       role, _ := strconv.Atoi(url.GetParam(constant.RegistryRoleKey, ""))
+       if role != common.CONSUMER {
+               return nil
+       }
+       timer := time.NewTimer(time.Duration(RegistryConnDelay) * time.Second)
+       defer timer.Stop()
+
+       for {
+               serviceName := url.Interface()
+               watcher, err := pr.createPolarisWatcher(serviceName)
+               if err != nil {
+                       logger.Warnf("getwatcher() = err:%v", 
perrors.WithStack(err))
+                       <-timer.C
+                       timer.Reset(time.Duration(RegistryConnDelay) * 
time.Second)
+                       continue
+               }
+
+               listener, err := NewPolarisListener(watcher)
+               if err != nil {
+                       logger.Warnf("getListener() = err:%v", 
perrors.WithStack(err))
+                       <-timer.C
+                       timer.Reset(time.Duration(RegistryConnDelay) * 
time.Second)
+                       continue
+               }
+
+               for {
+                       serviceEvent, err := listener.Next()
+
+                       if err != nil {
+                               logger.Warnf("Selector.watch() = error{%v}", 
perrors.WithStack(err))
+                               listener.Close()
+                               return err
+                       }
+                       logger.Infof("update begin, service event: %v", 
serviceEvent.String())
+                       notifyListener.Notify(serviceEvent)
+               }
+       }
+}
+
+// UnSubscribe returns nil if unsubscribing registry successfully. If not 
returns an error.
+func (pr *polarisRegistry) UnSubscribe(url *common.URL, notifyListener 
registry.NotifyListener) error {
+       // TODO wait polaris support it
+       return perrors.New("UnSubscribe not support in polarisRegistry")
+}
+
+// LoadSubscribeInstances load subscribe instance
+func (pr *polarisRegistry) LoadSubscribeInstances(url *common.URL, notify 
registry.NotifyListener) error {
+       serviceName := url.Interface()
+       resp, err := pr.consumer.GetInstances(&api.GetInstancesRequest{
+               GetInstancesRequest: model.GetInstancesRequest{
+                       Service:   serviceName,
+                       Namespace: pr.namespace,
+               },
+       })
+       if err != nil {
+               return perrors.New(fmt.Sprintf("could not query the instances 
for serviceName=%s,namespace=%s,error=%v",
+                       serviceName, pr.namespace, err))
+       }
+       for i := range resp.Instances {
+               if newUrl := generateUrl(resp.Instances[i]); newUrl != nil {
+                       notify.Notify(&registry.ServiceEvent{Action: 
remoting.EventTypeAdd, Service: newUrl})
+               }
+       }
+       return nil
+}
+
+// GetURL returns polaris registry's url.
+func (pr *polarisRegistry) GetURL() *common.URL {
+       return pr.url
+}
+
+func (pr *polarisRegistry) createPolarisWatcher(serviceName string) 
(*PolarisServiceWatcher, error) {
+
+       pr.listenerLock.Lock()
+       defer pr.listenerLock.Unlock()
+
+       if _, exist := pr.watchers[serviceName]; !exist {
+               subscribeParam := &api.WatchServiceRequest{
+                       WatchServiceRequest: model.WatchServiceRequest{
+                               Key: model.ServiceKey{
+                                       Namespace: pr.namespace,
+                                       Service:   serviceName,
+                               },
+                       },
+               }
+
+               watcher, err := newPolarisWatcher(subscribeParam, pr.consumer)
+               if err != nil {
+                       return nil, err
+               }
+               pr.watchers[serviceName] = watcher
+       }
+
+       return pr.watchers[serviceName], nil
+}
+
+// Destroy stop polaris registry.
+func (pr *polarisRegistry) Destroy() {
+       for i := range pr.registryUrls {
+               url := pr.registryUrls[i]
+               err := pr.UnRegister(url)
+               logger.Infof("DeRegister Polaris URL:%+v", url)
+               if err != nil {
+                       logger.Errorf("Deregister Polaris URL:%+v err:%v", url, 
err.Error())
+               }
+       }
+}
+
+// IsAvailable always return true when use polaris
+func (pr *polarisRegistry) IsAvailable() bool {
+       return true
+}
+
+// createRegisterParam convert dubbo url to polaris instance register request
+func createRegisterParam(url *common.URL, serviceName string) 
*api.InstanceRegisterRequest {
+       common.HandleRegisterIPAndPort(url)
+       port, _ := strconv.Atoi(url.Port)
+
+       metadata := make(map[string]string, len(url.GetParams()))
+       url.RangeParams(func(key, value string) bool {
+               metadata[key] = value
+               return true
+       })
+       metadata[constant.PolarisDubboPath] = url.Path
+
+       ver := url.GetParam("version", "")
+
+       req := &api.InstanceRegisterRequest{
+               InstanceRegisterRequest: model.InstanceRegisterRequest{
+                       Service:  serviceName,
+                       Host:     url.Ip,
+                       Port:     port,
+                       Protocol: &url.Protocol,
+                       Version:  &ver,
+                       Metadata: metadata,
+               },
+       }
+
+       req.SetTTL(defaultHeartbeatIntervalSec)
+
+       return req
+}
+
+// createDeregisterParam convert dubbo url to polaris instance deregister 
request
+func createDeregisterParam(url *common.URL, serviceName string) 
*api.InstanceDeRegisterRequest {
+       common.HandleRegisterIPAndPort(url)
+       port, _ := strconv.Atoi(url.Port)
+       return &api.InstanceDeRegisterRequest{
+               InstanceDeRegisterRequest: model.InstanceDeRegisterRequest{
+                       Service: serviceName,
+                       Host:    url.Ip,
+                       Port:    port,
+               },
+       }
+}
diff --git a/registry/polaris/service_discovery.go 
b/registry/polaris/service_discovery.go
new file mode 100644
index 000000000..f294b0b8b
--- /dev/null
+++ b/registry/polaris/service_discovery.go
@@ -0,0 +1,348 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package polaris
+
+import (
+       "fmt"
+       "sync"
+)
+
+import (
+       gxset "github.com/dubbogo/gost/container/set"
+       gxpage "github.com/dubbogo/gost/hash/page"
+       "github.com/dubbogo/gost/log/logger"
+
+       perrors "github.com/pkg/errors"
+
+       api "github.com/polarismesh/polaris-go"
+       "github.com/polarismesh/polaris-go/pkg/model"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/common"
+       "dubbo.apache.org/dubbo-go/v3/common/constant"
+       "dubbo.apache.org/dubbo-go/v3/common/extension"
+       "dubbo.apache.org/dubbo-go/v3/registry"
+       "dubbo.apache.org/dubbo-go/v3/remoting"
+       "dubbo.apache.org/dubbo-go/v3/remoting/polaris"
+)
+
+func init() {
+       extension.SetServiceDiscovery(constant.PolarisKey, 
newPolarisServiceDiscovery)
+}
+
+// newPolarisServiceDiscovery will create new service discovery instance
+func newPolarisServiceDiscovery(url *common.URL) (registry.ServiceDiscovery, 
error) {
+       discoveryURL := common.NewURLWithOptions(
+               common.WithParams(url.GetParams()),
+               common.WithParamsValue(constant.TimeoutKey, 
url.GetParam(constant.RegistryTimeoutKey, constant.DefaultRegTimeout)),
+               common.WithParamsValue(constant.PolarisServiceToken, 
url.Password),
+               common.WithParamsValue(constant.RegistryNamespaceKey, 
url.GetParam(constant.RegistryNamespaceKey, constant.PolarisDefaultNamespace)))
+       discoveryURL.Location = url.Location
+       discoveryURL.Password = url.Password
+
+       if err := polaris.InitSDKContext(url); err != nil {
+               return nil, err
+       }
+
+       providerApi, err := polaris.GetProviderAPI()
+       if err != nil {
+               return nil, err
+       }
+
+       consumerApi, err := polaris.GetConsumerAPI()
+       if err != nil {
+               return nil, err
+       }
+
+       if err != nil {
+               return nil, perrors.WithMessage(err, "create polaris 
namingClient failed.")
+       }
+
+       descriptor := fmt.Sprintf("polaris-service-discovery[%s]", 
discoveryURL.Location)
+
+       newInstance := &polarisServiceDiscovery{
+               namespace:         
discoveryURL.GetParam(constant.RegistryNamespaceKey, 
constant.PolarisDefaultNamespace),
+               descriptor:        descriptor,
+               consumer:          consumerApi,
+               provider:          providerApi,
+               services:          gxset.NewSet(),
+               registryInstances: make(map[string]*PolarisInstanceInfo),
+               watchers:          make(map[string]*PolarisServiceWatcher),
+       }
+       return newInstance, nil
+}
+
+type polarisServiceDiscovery struct {
+       namespace         string
+       descriptor        string
+       provider          api.ProviderAPI
+       consumer          api.ConsumerAPI
+       services          *gxset.HashSet
+       instanceLock      sync.RWMutex
+       registryInstances map[string]*PolarisInstanceInfo
+       watchers          map[string]*PolarisServiceWatcher
+       listenerLock      sync.RWMutex
+}
+
+// Destroy destroy polarisServiceDiscovery, will do unregister all 
ServiceInstance
+// and close polaris.ConsumerAPI and polaris.ProviderAPI
+func (polaris *polarisServiceDiscovery) Destroy() error {
+       for _, inst := range polaris.registryInstances {
+               err := polaris.Unregister(inst.instance)
+               logger.Infof("Unregister polaris instance:%+v", inst)
+               if err != nil {
+                       logger.Errorf("Unregister polaris instance:%+v, 
err:%+v", inst, err)
+               }
+       }
+       polaris.provider.Destroy()
+       polaris.consumer.Destroy()
+       return nil
+}
+
+// Register do register for ServiceInstance
+func (polaris *polarisServiceDiscovery) Register(instance 
registry.ServiceInstance) error {
+
+       ins := convertToRegisterInstance(polaris.namespace, instance)
+       resp, err := polaris.provider.RegisterInstance(ins)
+       if err != nil {
+               return perrors.WithMessage(err, "could not register the 
instance. "+instance.GetServiceName())
+       }
+
+       if resp.Existed {
+               logger.Warnf("instance already regist, namespace:%+v, 
service:%+v, host:%+v, port:%+v",
+                       polaris.namespace, instance.GetServiceName(), 
instance.GetHost(), instance.GetPort())
+       }
+
+       polaris.instanceLock.Lock()
+       defer polaris.instanceLock.Unlock()
+
+       polaris.registryInstances[getInstanceKey(polaris.namespace, instance)] 
= &PolarisInstanceInfo{
+               instance: instance,
+       }
+       polaris.services.Add(instance.GetServiceName())
+
+       return nil
+}
+
+// Update update ServiceInstance info
+func (polaris *polarisServiceDiscovery) Update(instance 
registry.ServiceInstance) error {
+       err := polaris.Unregister(instance)
+       if err != nil {
+               return perrors.WithStack(err)
+       }
+       polaris.services.Add(instance.GetServiceName())
+       return polaris.Register(instance)
+}
+
+// Unregister do Unregister for ServiceInstance
+func (polaris *polarisServiceDiscovery) Unregister(instance 
registry.ServiceInstance) error {
+
+       func() {
+               polaris.instanceLock.Lock()
+               defer polaris.instanceLock.Unlock()
+               key := getInstanceKey(polaris.namespace, instance)
+               delete(polaris.registryInstances, key)
+       }()
+
+       err := 
polaris.provider.Deregister(convertToDeregisterInstance(polaris.namespace, 
instance))
+       if err != nil {
+               return perrors.WithMessage(err, "Could not unregister the 
instance. "+instance.GetServiceName())
+       }
+
+       polaris.services.Remove(instance.GetServiceName())
+       return nil
+}
+
+func (polaris *polarisServiceDiscovery) GetDefaultPageSize() int {
+       return registry.DefaultPageSize
+}
+
+func (polaris *polarisServiceDiscovery) GetServices() *gxset.HashSet {
+       return polaris.services
+}
+
+// GetInstances will return all service instances with serviceName
+func (polaris *polarisServiceDiscovery) GetInstances(serviceName string) 
[]registry.ServiceInstance {
+       resp, err := 
polaris.consumer.GetAllInstances(&api.GetAllInstancesRequest{
+               GetAllInstancesRequest: model.GetAllInstancesRequest{
+                       Service:   serviceName,
+                       Namespace: polaris.namespace,
+               },
+       })
+
+       if err != nil {
+               logger.Errorf("Could not query the instances for service: %+v . 
It happened err %+v", serviceName, err)
+               return make([]registry.ServiceInstance, 0)
+       }
+       res := make([]registry.ServiceInstance, 0, len(resp.Instances))
+       for _, ins := range resp.Instances {
+               metadata := ins.GetMetadata()
+               res = append(res, &registry.DefaultServiceInstance{
+                       ID:          ins.GetId(),
+                       ServiceName: serviceName,
+                       Host:        ins.GetHost(),
+                       Port:        int(ins.GetPort()),
+                       Enable:      !ins.IsIsolated(),
+                       Healthy:     ins.IsHealthy(),
+                       Metadata:    metadata,
+               })
+       }
+       return res
+}
+
+// GetInstancesByPage will return a page containing instances of 
ServiceInstance with the serviceName
+// the page will start at offset
+func (polaris *polarisServiceDiscovery) GetInstancesByPage(serviceName string, 
offset int, pageSize int) gxpage.Pager {
+       all := polaris.GetInstances(serviceName)
+       res := make([]any, 0, pageSize)
+       for i := offset; i < len(all) && i < offset+pageSize; i++ {
+               res = append(res, all[i])
+       }
+       return gxpage.NewPage(offset, pageSize, res, len(all))
+}
+
+// GetHealthyInstancesByPage will return a page containing instances of 
ServiceInstance.
+// The param healthy indices that the instance should be healthy or not.
+// The page will start at offset
+func (polaris *polarisServiceDiscovery) GetHealthyInstancesByPage(serviceName 
string, offset int, pageSize int, healthy bool) gxpage.Pager {
+       all := polaris.GetInstances(serviceName)
+       res := make([]any, 0, pageSize)
+       // could not use res = all[a:b] here because the res should be []any, 
not []ServiceInstance
+       var (
+               i     = offset
+               count = 0
+       )
+       for i < len(all) && count < pageSize {
+               ins := all[i]
+               if ins.IsHealthy() == healthy {
+                       res = append(res, all[i])
+                       count++
+               }
+               i++
+       }
+       return gxpage.NewPage(offset, pageSize, res, len(all))
+}
+
+// GetRequestInstances get all instances by the specified service names
+func (polaris *polarisServiceDiscovery) GetRequestInstances(serviceNames 
[]string, offset int, requestedSize int) map[string]gxpage.Pager {
+       res := make(map[string]gxpage.Pager, len(serviceNames))
+       for _, name := range serviceNames {
+               res[name] = polaris.GetInstancesByPage(name, offset, 
requestedSize)
+       }
+       return res
+}
+
+// AddListener add listener for ServiceInstancesChangedListener
+func (polaris *polarisServiceDiscovery) AddListener(listener 
registry.ServiceInstancesChangedListener) error {
+
+       for _, val := range listener.GetServiceNames().Values() {
+               serviceName := val.(string)
+               watcher, err := 
polaris.createPolarisWatcherIfAbsent(serviceName)
+               if err != nil {
+                       return err
+               }
+
+               watcher.AddSubscriber(func(et remoting.EventType, instances 
[]model.Instance) {
+                       dubboInstances := make([]registry.ServiceInstance, 0, 
len(instances))
+                       for _, instance := range instances {
+                               dubboInstances = append(dubboInstances, 
&registry.DefaultServiceInstance{
+                                       ID:          instance.GetId(),
+                                       ServiceName: instance.GetService(),
+                                       Host:        instance.GetHost(),
+                                       Port:        int(instance.GetPort()),
+                                       Enable:      !instance.IsIsolated(),
+                                       Healthy:     instance.IsHealthy(),
+                                       Metadata:    instance.GetMetadata(),
+                                       GroupName:   
instance.GetMetadata()[constant.PolarisDubboGroup],
+                               })
+                       }
+
+                       
listener.OnEvent(registry.NewServiceInstancesChangedEvent(serviceName, 
dubboInstances))
+               })
+       }
+
+       return nil
+}
+
+// createPolarisWatcherIfAbsent Calculate whether the corresponding 
PolarisWatcher needs to be created,
+// if it does not exist, create one, otherwise return the existing one
+func (polaris *polarisServiceDiscovery) 
createPolarisWatcherIfAbsent(serviceName string) (*PolarisServiceWatcher, 
error) {
+
+       polaris.listenerLock.Lock()
+       defer polaris.listenerLock.Unlock()
+
+       if _, exist := polaris.watchers[serviceName]; !exist {
+               subscribeParam := &api.WatchServiceRequest{
+                       WatchServiceRequest: model.WatchServiceRequest{
+                               Key: model.ServiceKey{
+                                       Namespace: polaris.namespace,
+                                       Service:   serviceName,
+                               },
+                       },
+               }
+
+               watcher, err := newPolarisWatcher(subscribeParam, 
polaris.consumer)
+               if err != nil {
+                       return nil, err
+               }
+               polaris.watchers[serviceName] = watcher
+       }
+
+       return polaris.watchers[serviceName], nil
+}
+
+// String retuen descriptor
+func (polaris *polarisServiceDiscovery) String() string {
+       return polaris.descriptor
+}
+
+func convertToRegisterInstance(namespace string, instance 
registry.ServiceInstance) *api.InstanceRegisterRequest {
+
+       var (
+               health      = instance.IsHealthy()
+               isolate     = instance.IsEnable()
+               ttl         = 5
+               protocolVal = string(constant.DubboProtocol)
+       )
+
+       return &api.InstanceRegisterRequest{
+               InstanceRegisterRequest: model.InstanceRegisterRequest{
+                       Service:   instance.GetServiceName(),
+                       Namespace: namespace,
+                       Host:      instance.GetHost(),
+                       Port:      instance.GetPort(),
+                       Protocol:  &protocolVal,
+                       Metadata:  instance.GetMetadata(),
+                       Healthy:   &health,
+                       Isolate:   &isolate,
+                       TTL:       &ttl,
+               },
+       }
+}
+
+func convertToDeregisterInstance(namespace string, instance 
registry.ServiceInstance) *api.InstanceDeRegisterRequest {
+       return &api.InstanceDeRegisterRequest{
+               InstanceDeRegisterRequest: model.InstanceDeRegisterRequest{
+                       Service:   instance.GetServiceName(),
+                       Namespace: namespace,
+                       Host:      instance.GetHost(),
+                       Port:      instance.GetPort(),
+               },
+       }
+}
diff --git a/registry/polaris/utils.go b/registry/polaris/utils.go
new file mode 100644
index 000000000..cdd6d97d1
--- /dev/null
+++ b/registry/polaris/utils.go
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package polaris
+
+import (
+       "fmt"
+       "strconv"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/common"
+       "dubbo.apache.org/dubbo-go/v3/common/constant"
+       "dubbo.apache.org/dubbo-go/v3/registry"
+)
+
+type PolarisInstanceInfo struct {
+       instance registry.ServiceInstance
+       url      *common.URL
+}
+
+func getInstanceKey(namespace string, instance registry.ServiceInstance) 
string {
+       return fmt.Sprintf("%s-%s-%s-%d", namespace, instance.GetServiceName(), 
instance.GetHost(), instance.GetPort())
+}
+
+// just copy from dubbo-go for nacos
+func getCategory(url *common.URL) string {
+       role, _ := strconv.Atoi(url.GetParam(constant.RegistryRoleKey, 
strconv.Itoa(constant.PolarisDefaultRoleType)))
+       category := common.DubboNodes[role]
+       return category
+}
diff --git a/remoting/polaris/builder.go b/remoting/polaris/builder.go
new file mode 100644
index 000000000..30ab31d9e
--- /dev/null
+++ b/remoting/polaris/builder.go
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package polaris
+
+import (
+       "errors"
+       "fmt"
+       "net"
+       "strconv"
+       "strings"
+       "sync"
+)
+
+import (
+       perrors "github.com/pkg/errors"
+
+       "github.com/polarismesh/polaris-go"
+       "github.com/polarismesh/polaris-go/api"
+       "github.com/polarismesh/polaris-go/pkg/config"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/common"
+       "dubbo.apache.org/dubbo-go/v3/common/constant"
+)
+
+var (
+       once               sync.Once
+       namesapce          string
+       sdkCtx             api.SDKContext
+       openPolarisAbility bool
+)
+
+var (
+       ErrorNoOpenPolarisAbility = errors.New("polaris ability not open")
+       ErrorSDKContextNotInit    = errors.New("polaris SDKContext not init")
+)
+
+// GetConsumerAPI creates one polaris ConsumerAPI instance
+func GetConsumerAPI() (polaris.ConsumerAPI, error) {
+       if err := Check(); err != nil {
+               return nil, err
+       }
+
+       return polaris.NewConsumerAPIByContext(sdkCtx), nil
+}
+
+// GetProviderAPI creates one polaris ProviderAPI instance
+func GetProviderAPI() (polaris.ProviderAPI, error) {
+       if err := Check(); err != nil {
+               return nil, err
+       }
+
+       return polaris.NewProviderAPIByContext(sdkCtx), nil
+}
+
+// GetRouterAPI create one polaris RouterAPI instance
+func GetRouterAPI() (polaris.RouterAPI, error) {
+       if err := Check(); err != nil {
+               return nil, err
+       }
+
+       return polaris.NewRouterAPIByContext(sdkCtx), nil
+}
+
+// GetLimiterAPI creates one polaris LimiterAPI instance
+func GetLimiterAPI() (polaris.LimitAPI, error) {
+       if err := Check(); err != nil {
+               return nil, err
+       }
+
+       return polaris.NewLimitAPIByContext(sdkCtx), nil
+}
+
+func Check() error {
+       if !openPolarisAbility {
+               return ErrorNoOpenPolarisAbility
+       }
+       if sdkCtx == nil {
+               return ErrorSDKContextNotInit
+       }
+       return nil
+}
+
+// GetNamespace gets user defined namespace info
+func GetNamespace() string {
+       return namesapce
+}
+
+// InitSDKContext inits polaris SDKContext by URL
+func InitSDKContext(url *common.URL) error {
+       if url == nil {
+               return errors.New("url is empty")
+       }
+
+       openPolarisAbility = true
+
+       var rerr error
+       once.Do(func() {
+               addresses := strings.Split(url.Location, ",")
+               serverConfigs := make([]string, 0, len(addresses))
+               for _, addr := range addresses {
+                       ip, portStr, err := net.SplitHostPort(addr)
+                       if err != nil {
+                               rerr = perrors.WithMessagef(err, "split [%s] ", 
addr)
+                       }
+                       port, _ := strconv.Atoi(portStr)
+                       serverConfigs = append(serverConfigs, 
fmt.Sprintf("%s:%d", ip, uint64(port)))
+               }
+
+               polarisConf := config.NewDefaultConfiguration(serverConfigs)
+               _sdkCtx, err := api.InitContextByConfig(polarisConf)
+               rerr = err
+               sdkCtx = _sdkCtx
+               namesapce = url.GetParam(constant.RegistryNamespaceKey, 
constant.PolarisDefaultNamespace)
+       })
+
+       return rerr
+}
+
+func mergePolarisConfiguration(easy, complexConf config.Configuration) {
+
+       easySvrList := easy.GetGlobal().GetServerConnector().GetAddresses()
+
+       complexSvrList := 
complexConf.GetGlobal().GetServerConnector().GetAddresses()
+
+       result := make(map[string]bool)
+
+       for i := range complexSvrList {
+               result[complexSvrList[i]] = true
+       }
+
+       for i := range easySvrList {
+               if _, exist := result[easySvrList[i]]; !exist {
+                       result[easySvrList[i]] = true
+               }
+       }
+
+       finalSvrList := make([]string, 0)
+       for k := range result {
+               finalSvrList = append(finalSvrList, k)
+       }
+
+       complexConf.GetGlobal().GetServerConnector().SetAddresses(finalSvrList)
+}
diff --git a/remoting/polaris/builder_test.go b/remoting/polaris/builder_test.go
new file mode 100644
index 000000000..6a27f3307
--- /dev/null
+++ b/remoting/polaris/builder_test.go
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package polaris
+
+import (
+       "net/url"
+       "testing"
+)
+
+import (
+       "github.com/stretchr/testify/assert"
+)
+
+import (
+       "dubbo.apache.org/dubbo-go/v3/common"
+)
+
+func TestGetPolarisConfigByUrl(t *testing.T) {
+       regurl := getRegUrl()
+       err := InitSDKContext(regurl)
+
+       assert.Nil(t, err)
+       assert.ElementsMatch(t, []string{"127.0.0.1:8091"}, 
sdkCtx.GetConfig().GetGlobal().GetServerConnector().GetAddresses(), "server 
address")
+}
+
+func getRegUrl() *common.URL {
+       regurlMap := url.Values{}
+       regurl, _ := common.NewURL("registry://127.0.0.1:8091", 
common.WithParams(regurlMap))
+       return regurl
+}
diff --git a/remoting/polaris/parser/parser.go 
b/remoting/polaris/parser/parser.go
new file mode 100644
index 000000000..c8bec14f9
--- /dev/null
+++ b/remoting/polaris/parser/parser.go
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package parser
+
+import (
+       "encoding/json"
+       "regexp"
+       "strconv"
+       "strings"
+)
+
+import (
+       "github.com/dubbogo/gost/log/logger"
+
+       "github.com/oliveagle/jsonpath"
+)
+
+const (
+       _pefixParam     = "param"
+       _prefixParamArr = "param["
+)
+
+var (
+       _arrayRegx, _ = regexp.Compile(`"^.+\\[[0-9]+\\]"`)
+)
+
+// ParseArgumentsByExpression follow https://goessner.net/articles/JsonPath/
+//
+//     {
+//         "store":{
+//             "book":[
+//                 {
+//                     "category":"reference",
+//                     "author":"Nigel Rees",
+//                     "title":"Sayings of the Century",
+//                     "price":8.95
+//                 },
+//                 {
+//                     "category":"fiction",
+//                     "author":"Evelyn Waugh",
+//                     "title":"Sword of Honor",
+//                     "price":12.99
+//                 },
+//                 {
+//                     "category":"fiction",
+//                     "author":"Herman Melville",
+//                     "title":"Moby Dick",
+//                     "isbn":"0-553-21311-3",
+//                     "price":8.99
+//                 },
+//                 {
+//                     "category":"fiction",
+//                     "author":"J. R. R. Tolkien",
+//                     "title":"The Lord of the Rings",
+//                     "isbn":"0-395-19395-8",
+//                     "price":22.99
+//                 }
+//             ],
+//             "bicycle":{
+//                 "color":"red",
+//                 "price":19.95
+//             }
+//         }
+//     }
+//
+// examples
+//   - case 1: param.$.store.book[*].author
+func ParseArgumentsByExpression(key string, parameters []any) any {
+       index, key := resolveIndex(key)
+       if index == -1 || index >= len(parameters) {
+               logger.Errorf("[Parser][Polaris] invalid expression for : %s", 
key)
+               return nil
+       }
+
+       data, err := json.Marshal(parameters[index])
+       if err != nil {
+               logger.Errorf("[Parser][Polaris] marshal parameter %+v fail : 
%+v", parameters[index], err)
+               return nil
+       }
+       var searchVal any
+       _ = json.Unmarshal(data, &searchVal)
+       res, err := jsonpath.JsonPathLookup(searchVal, key)
+       if err != nil {
+               logger.Errorf("[Parser][Polaris] invalid do json path lookup by 
key : %s, err : %+v", key, err)
+       }
+
+       return res
+}
+
+func resolveIndex(key string) (int, string) {
+       if strings.HasPrefix(key, _prefixParamArr) {
+               // param[0].$.
+               endIndex := strings.Index(key, "]")
+               indexStr := key[len(_prefixParamArr):endIndex]
+               index, err := strconv.ParseInt(indexStr, 10, 32)
+               if err != nil {
+                       return -1, ""
+               }
+               startIndex := endIndex + 2
+               if rune(key[endIndex+1]) != rune('.') {
+                       startIndex = endIndex + 1
+               }
+               return int(index), key[startIndex:]
+       } else if strings.HasPrefix(key, _pefixParam) {
+               key = strings.TrimPrefix(key, _pefixParam+".")
+               return 0, strings.TrimPrefix(key, _pefixParam+".")
+       }
+
+       return -1, ""
+}
diff --git a/remoting/polaris/parser/parser_test.go 
b/remoting/polaris/parser/parser_test.go
new file mode 100644
index 000000000..bdb4615af
--- /dev/null
+++ b/remoting/polaris/parser/parser_test.go
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package parser
+
+import (
+       "encoding/json"
+       "testing"
+)
+
+import (
+       "github.com/stretchr/testify/assert"
+)
+
+var (
+       testDataStore = `
+       {
+               "book":[
+                       {
+                               "category":"reference",
+                               "author":"Nigel Rees",
+                               "title":"Sayings of the Century",
+                               "price":8.95
+                       },
+                       {
+                               "category":"fiction",
+                               "author":"Evelyn Waugh",
+                               "title":"Sword of Honor",
+                               "price":12.99
+                       },
+                       {
+                               "category":"fiction",
+                               "author":"Herman Melville",
+                               "title":"Moby Dick",
+                               "isbn":"0-553-21311-3",
+                               "price":8.99
+                       },
+                       {
+                               "category":"fiction",
+                               "author":"J. R. R. Tolkien",
+                               "title":"The Lord of the Rings",
+                               "isbn":"0-395-19395-8",
+                               "price":22.99
+                       }
+               ],
+               "bicycle":{
+                       "color":"red",
+                       "price":19.95
+               }
+       }
+       `
+
+       testDataBicyle = `
+       {
+               "color":"red",
+               "price":19.95
+       }
+       `
+)
+
+func TestParseArgumentsByExpression(t *testing.T) {
+
+       var (
+               argStore, argBicyle any
+       )
+
+       json.Unmarshal([]byte(testDataStore), &argStore)
+       json.Unmarshal([]byte(testDataBicyle), &argBicyle)
+
+       t.Run("test-case-1", func(t *testing.T) {
+               ret := ParseArgumentsByExpression("param.$.book[0].category", 
[]any{argStore})
+               assert.Equal(t, "reference", ret)
+       })
+
+       t.Run("test-case-2", func(t *testing.T) {
+               ret := 
ParseArgumentsByExpression("param[0].$.book[0].category", []any{argStore, 
argBicyle})
+               assert.Equal(t, "reference", ret)
+       })
+
+       t.Run("test-case-2", func(t *testing.T) {
+               ret := ParseArgumentsByExpression("param[1].$.color", 
[]any{argStore, argBicyle})
+               assert.Equal(t, "red", ret)
+       })
+
+       t.Run("test-case-3", func(t *testing.T) {
+               ret := ParseArgumentsByExpression("param.$.color", 
[]any{argBicyle})
+               assert.Equal(t, "red", ret)
+       })
+
+}
+
+func Test_resolveIndex(t *testing.T) {
+       type args struct {
+               key string
+       }
+       tests := []struct {
+               name  string
+               args  args
+               want  int
+               want1 string
+       }{
+               {
+                       name: "case-1",
+                       args: args{
+                               key: "param.$.key",
+                       },
+                       want:  0,
+                       want1: "$.key",
+               },
+               {
+                       name: "case-2",
+                       args: args{
+                               key: "param[1].$.key",
+                       },
+                       want:  1,
+                       want1: "$.key",
+               },
+               {
+                       name: "case-3",
+                       args: args{
+                               key: "param[10].$.key",
+                       },
+                       want:  10,
+                       want1: "$.key",
+               },
+               {
+                       name: "case-4",
+                       args: args{
+                               key: "param[11]$.key",
+                       },
+                       want:  11,
+                       want1: "$.key",
+               },
+               {
+                       name: "case-5",
+                       args: args{
+                               key: "param[11]key",
+                       },
+                       want:  11,
+                       want1: "key",
+               },
+       }
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       got, got1 := resolveIndex(tt.args.key)
+                       if got != tt.want {
+                               t.Errorf("resolveIndex() got = %v, want %v", 
got, tt.want)
+                       }
+                       if got1 != tt.want1 {
+                               t.Errorf("resolveIndex() got1 = %v, want %v", 
got1, tt.want1)
+                       }
+               })
+       }
+}
diff --git a/remoting/polaris/polaris.yaml b/remoting/polaris/polaris.yaml
new file mode 100644
index 000000000..2347aad37
--- /dev/null
+++ b/remoting/polaris/polaris.yaml
@@ -0,0 +1,84 @@
+global:
+  system:
+    mode: 0
+    discoverCluster:
+      namespace: Polaris
+      service: polaris.discover
+      refreshInterval: 10m
+    healthCheckCluster:
+      namespace: Polaris
+      service: polaris.healthcheck
+      refreshInterval: 10m
+    monitorCluster:
+      namespace: Polaris
+      service: polaris.monitor
+      refreshInterval: 10m
+  api:
+    timeout: 1s
+    reportInterval: 10m
+    maxRetryTimes: 5
+    retryInterval: 1s
+  serverConnector:
+    protocol: grpc
+    connectTimeout: 500ms
+    messageTimeout: 1s
+    connectionIdleTimeout: 1s
+    requestQueueSize: 1000
+    serverSwitchInterval: 10m
+    plugin:
+      grpc:
+        maxCallRecvMsgSize: 52428800
+  statReporter:
+    enable: false
+consumer:
+  localCache:
+    type: inmemory
+    serviceExpireTime: 24h
+    serviceRefreshInterval: 2s
+    persistDir: $HOME/polaris/backup
+    persistMaxWriteRetry: 5
+    persistMaxReadRetry: 1
+    persistRetryInterval: 1s
+    persistAvailableInterval: 60s
+    startUseFileCache: true
+  serviceRouter:
+    chain:
+      - ruleBasedRouter
+      - nearbyBasedRouter
+    plugin:
+      nearbyBasedRouter:
+        matchLevel: zone
+      ruleBasedRouter: {}
+    percentOfMinInstances: 0
+    enableRecoverAll: true
+  loadbalancer:
+    type: weightedRandom
+    plugin:
+      ringHash:
+        vnodeCount: 500
+  circuitBreaker:
+    enable: true
+    checkPeriod: 30s
+    requestCountAfterHalfOpen: 10
+    sleepWindow: 30s
+    successCountAfterHalfOpen: 8
+    recoverWindow: 60s
+    recoverNumBuckets: 10
+    chain:
+      - errorCount
+      - errorRate
+    plugin:
+      errorCount:
+        continuousErrorThreshold: 10
+        metricNumBuckets: 10
+        metricStatTimeWindow: 1m0s
+      errorRate:
+        errorRateThreshold: 0.5
+        metricNumBuckets: 5
+        metricStatTimeWindow: 1m0s
+        requestVolumeThreshold: 10
+  subscribe:
+    type: subscribeLocalChannel
+    plugin:
+      subscribeLocalChannel:
+        channelBufferSize: 50
\ No newline at end of file
diff --git a/tools/dubbo-go-schema/dubbo-go.json 
b/tools/dubbo-go-schema/dubbo-go.json
index 292d201ef..870a2ed3a 100644
--- a/tools/dubbo-go-schema/dubbo-go.json
+++ b/tools/dubbo-go-schema/dubbo-go.json
@@ -93,6 +93,7 @@
           "enum": [
             "nacos",
             "etcdv3",
+            "polaris",
             "xds",
             "zookeeper",
             "service-discovery-registry"

Reply via email to