Skip to content

Commit

Permalink
Merge pull request #1 from kitex-contrib/feat/retry
Browse files Browse the repository at this point in the history
Feat(retry): support configure retry policy from nacos
  • Loading branch information
felix021 committed Jul 20, 2023
2 parents aea5640 + fc9eefa commit 311b6d6
Show file tree
Hide file tree
Showing 12 changed files with 1,145 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ output/*

# Vscode files
.vscode

vendor
72 changes: 71 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,71 @@
# .github
# config-nacos (*This is a community driven project*)

[中文](https://github.com/kitex-contrib/config-nacos/blob/main/README_CN.md)

Nacos as config centre.

## How to use?

### Basic

#### Server

TODO

#### Client

```go
import (
// ...
"github.com/cloudwego/kitex-examples/kitex_gen/api/echo"
"github.com/cloudwego/kitex/client"
retry "github.com/kitex-contrib/config-nacos/client"
"github.com/kitex-contrib/config-nacos/nacos"
// ...
)

func main() {
// ...
nacosClient, err := nacos.DefaultClient()
if err != nil {
panic(err)
}
fn := func(cp *vo.ConfigParam) {
cp.Type = vo.TEXT
}
opts := []client.Option{
client.WithHostPorts("0.0.0.0:8888"),
client.WithMiddleware(mymiddleware.CommonMiddleware),
client.WithMiddleware(mymiddleware.ClientMiddleware),
//client.WithResolver(r),
}

opts = append(opts, retry.NewSuite("echo", "test", nacosClient, fn).Options()...)

client, err := echo.NewClient(
"echo",
opts...,
)
// ...
}
```

### Environment Variable

| Environment Variable Name | Environment Variable Default Value | Environment Variable Introduction |
| ------------------------- | ---------------------------------- | --------------------------------- |
| serverAddr | 127.0.0.1 | nacos server address |
| serverPort | 8848 | nacos server port |
| namespace | | the namespaceId of nacos |
| configDataId | {{.ClientServiceName}}.{{.ServerServiceName}}.{{.Category}} | the format of config data id |
| configGroup | DEFAULT_GROUP | the group of config data |

### More Info

Refer to [example](example) for more usage.

## Compatibility
This Package use Nacos1.x client. The Nacos2.0 and Nacos1.0 Server are fully compatible with it. [see](https://nacos.io/en-us/docs/v2/upgrading/2.0.0-compatibility.html)

maintained by: [whalecold](https://github.com/whalecold)

64 changes: 64 additions & 0 deletions README_CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# config-nacos

[English](https://github.com/kitex-contrib/config-nacos/blob/main/README.md)

使用 **nacos** 作为 **Kitex** 的配置中心

## 这个项目应当如何使用?

### 基本使用

#### 客户端

```go
import (
// ...
"github.com/cloudwego/kitex-examples/kitex_gen/api/echo"
"github.com/cloudwego/kitex/client"
retry "github.com/kitex-contrib/config-nacos/client"
"github.com/kitex-contrib/config-nacos/nacos"
// ...
)

func main() {
// ...
nacosClient, err := nacos.DefaultClient()
if err != nil {
panic(err)
}
fn := func(cp *vo.ConfigParam) {
cp.Type = vo.TEXT
}
opts := []client.Option{
client.WithHostPorts("0.0.0.0:8888"),
client.WithMiddleware(mymiddleware.CommonMiddleware),
client.WithMiddleware(mymiddleware.ClientMiddleware),
//client.WithResolver(r),
}

opts = append(opts, retry.NewSuite("echo", "test", nacosClient, fn).Options()...)

client, err := echo.NewClient(
"echo",
opts...,
)
// ...
}
```

### 环境变量

| 变量名 | 变量默认值 | 作用 |
| ------------------------- | ---------------------------------- | --------------------------------- |
| serverAddr | 127.0.0.1 | nacos 服务器地址 |
| serverPort | 8848 | nacos 服务器端口 |
| namespace | | nacos 中的 namespace Id |
| configDataId | {{.ClientServiceName}}.{{.ServerServiceName}}.{{.Category}} | the format of config data id |
| configGroup | DEFAULT_GROUP | the group of config data |

### 更多信息

更多示例请参考 [example](example)

## 兼容性
该包使用 Nacos1.x 客户端,Nacos2.0 和 Nacos1.0 服务端完全兼容该版本. [详情](https://nacos.io/zh-cn/docs/v2/upgrading/2.0.0-compatibility.html)
48 changes: 48 additions & 0 deletions client/client_suite.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2023 CloudWeGo Authors
//
// Licensed 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 client

import (
"github.com/cloudwego/kitex/client"

"github.com/kitex-contrib/config-nacos/nacos"
)

// NacosClientSuite nacos client config suite, configure retry timeout limit and circuitbreak dynamically from nacos.
type NacosClientSuite struct {
nacosClient nacos.Client
service string
client string
fns []nacos.CustomFunction
}

// NewSuite service is the destination service name and client is the local identity.
func NewSuite(service, client string, cli nacos.Client,
cfs ...nacos.CustomFunction,
) *NacosClientSuite {
return &NacosClientSuite{
service: service,
client: client,
nacosClient: cli,
fns: cfs,
}
}

// Options return a list client.Option
func (s *NacosClientSuite) Options() []client.Option {
opts := make([]client.Option, 0, 8)
opts = append(opts, WithRetryPolicy(s.service, s.client, s.nacosClient, s.fns...)...)
return opts
}
87 changes: 87 additions & 0 deletions client/retry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright 2023 CloudWeGo Authors
//
// Licensed 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 client

import (
"github.com/kitex-contrib/config-nacos/nacos"
"github.com/nacos-group/nacos-sdk-go/vo"

"github.com/cloudwego/kitex/client"
"github.com/cloudwego/kitex/pkg/klog"
"github.com/cloudwego/kitex/pkg/retry"
)

const (
retryConfigName = "retry_config"
)

// WithRetryPolicy sets the retry policy from nacos configuration center.
func WithRetryPolicy(dest, src string, nacosClient nacos.Client,
cfs ...nacos.CustomFunction,
) []client.Option {
param := nacos.NaocsConfigParam(&nacos.ConfigParamConfig{
Category: retryConfigName,
ServerServiceName: dest,
ClientServiceName: src,
}, cfs...)

return []client.Option{
client.WithRetryContainer(initRetryContainer(param, dest, nacosClient)),
client.WithCloseCallbacks(func() error {
// cancel the configuration listener when client is closed.
return nacosClient.DeregisterConfig(param)
}),
}
}

// the key is method name, wildcard "*" can match anything.
type retryConfigs map[string]*retry.Policy

func initRetryContainer(param vo.ConfigParam, dest string,
nacosClient nacos.Client,
) *retry.Container {
retryContainer := retry.NewRetryContainer()

onChangeCallback := func(data string, parser nacos.ConfigParser) {
rcs := retryConfigs{}
err := parser.Decode(param.Type, data, rcs)
if err != nil {
klog.Warnf("[nacos] %s client nacos retry: unmarshal data %s failed: %s, skip...", dest, data, err)
return
}

for method, policy := range rcs {
if policy.BackupPolicy != nil && policy.FailurePolicy != nil {
klog.Warnf("[nacos] %s client policy for method %s BackupPolicy and FailurePolicy must not be set at same time",
dest, method)
continue
}
if policy.BackupPolicy == nil && policy.FailurePolicy == nil {
klog.Warnf("[nacos] %s client policy for method %s BackupPolicy and FailurePolicy must not be empty at same time",
dest, method)
continue
}
retryContainer.NotifyPolicyChange(method, *policy)
}
}

nacosClient.RegisterConfigCallback(dest,
retryConfigName,
param,
onChangeCallback,
)

return retryContainer
}
57 changes: 57 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
module github.com/kitex-contrib/config-nacos

go 1.19

require (
github.com/cloudwego/kitex v0.6.1
github.com/nacos-group/nacos-sdk-go v1.1.4
github.com/stretchr/testify v1.8.2
sigs.k8s.io/yaml v1.3.0
)

require (
github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 // indirect
github.com/apache/thrift v0.13.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/bytedance/gopkg v0.0.0-20230531144706-a12972768317 // indirect
github.com/bytedance/sonic v1.8.8 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/chenzhuoyu/iasm v0.0.0-20230222070914-0b1b64b0e762 // indirect
github.com/choleraehyq/pid v0.0.16 // indirect
github.com/cloudwego/configmanager v0.2.0 // indirect
github.com/cloudwego/fastpb v0.0.4 // indirect
github.com/cloudwego/frugal v0.1.6 // indirect
github.com/cloudwego/netpoll v0.4.0 // indirect
github.com/cloudwego/thriftgo v0.2.11 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/go-errors/errors v1.0.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/pprof v0.0.0-20220608213341-c488b8fa1db3 // indirect
github.com/jhump/protoreflect v1.8.2 // indirect
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/oleiade/lane v1.0.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/tidwall/gjson v1.9.3 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
go.uber.org/atomic v1.6.0 // indirect
go.uber.org/multierr v1.5.0 // indirect
go.uber.org/zap v1.15.0 // indirect
golang.org/x/arch v0.2.0 // indirect
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2 // indirect
golang.org/x/text v0.6.0 // indirect
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/ini.v1 v1.42.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit 311b6d6

Please sign in to comment.