-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
743d96f
commit 0be9eb9
Showing
49 changed files
with
1,651 additions
and
413 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
module github.com/polarismesh/polaris-go-zeroprotect | ||
|
||
go 1.17 | ||
|
||
replace github.com/polarismesh/polaris-go => ../../../ | ||
|
||
require github.com/polarismesh/polaris-go v0.0.0-00010101000000-000000000000 | ||
|
||
require ( | ||
github.com/beorn7/perks v1.0.1 // indirect | ||
github.com/cespare/xxhash/v2 v2.1.2 // indirect | ||
github.com/dlclark/regexp2 v1.7.0 // indirect | ||
github.com/golang/protobuf v1.5.2 // indirect | ||
github.com/google/uuid v1.3.0 // indirect | ||
github.com/hashicorp/errwrap v1.0.0 // indirect | ||
github.com/hashicorp/go-multierror v1.1.1 // indirect | ||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect | ||
github.com/mitchellh/go-homedir v1.1.0 // indirect | ||
github.com/modern-go/reflect2 v1.0.2 // indirect | ||
github.com/natefinch/lumberjack v2.0.0+incompatible // indirect | ||
github.com/pkg/errors v0.9.1 // indirect | ||
github.com/polarismesh/specification v1.2.1 // indirect | ||
github.com/prometheus/client_golang v1.12.1 // indirect | ||
github.com/prometheus/client_model v0.2.0 // indirect | ||
github.com/prometheus/common v0.32.1 // indirect | ||
github.com/prometheus/procfs v0.7.3 // indirect | ||
github.com/spaolacci/murmur3 v1.1.0 // indirect | ||
go.uber.org/atomic v1.7.0 // indirect | ||
go.uber.org/multierr v1.6.0 // indirect | ||
go.uber.org/zap v1.21.0 // indirect | ||
golang.org/x/net v0.2.0 // indirect | ||
golang.org/x/sys v0.2.0 // indirect | ||
golang.org/x/text v0.4.0 // indirect | ||
google.golang.org/genproto v0.0.0-20220504150022-98cd25cafc72 // indirect | ||
google.golang.org/grpc v1.51.0 // indirect | ||
google.golang.org/protobuf v1.28.1 // indirect | ||
gopkg.in/yaml.v2 v2.4.0 // indirect | ||
) |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,223 @@ | ||
/** | ||
* Tencent is pleased to support the open source community by making polaris-go available. | ||
* | ||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. | ||
* | ||
* Licensed under the BSD 3-Clause License (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://opensource.org/licenses/BSD-3-Clause | ||
* | ||
* 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 main | ||
|
||
import ( | ||
"encoding/json" | ||
"flag" | ||
"log" | ||
"strconv" | ||
"sync" | ||
"time" | ||
|
||
"github.com/polarismesh/polaris-go" | ||
"github.com/polarismesh/polaris-go/pkg/config" | ||
"github.com/polarismesh/polaris-go/plugin/servicerouter/zeroprotect" | ||
) | ||
|
||
var ( | ||
namespace string | ||
service string | ||
token string | ||
insCount int64 | ||
basePort = 8080 | ||
) | ||
|
||
func initArgs() { | ||
flag.StringVar(&namespace, "namespace", "default", "namespace") | ||
flag.StringVar(&service, "service", "DiscoverEchoServer", "service") | ||
// 当北极星开启鉴权时,需要配置此参数完成相关的权限检查 | ||
flag.StringVar(&token, "token", "", "token") | ||
flag.Int64Var(&insCount, "ins_count", 10, "ins_count") | ||
} | ||
|
||
func main() { | ||
initArgs() | ||
|
||
sdkCtx, err := polaris.NewSDKContext() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
provider := polaris.NewProviderAPIByContext(sdkCtx) | ||
consumer := polaris.NewConsumerAPIByContext(sdkCtx) | ||
router := polaris.NewRouterAPIByContext(sdkCtx) | ||
|
||
wait, _ := createInstances(provider) | ||
// 等待 | ||
wait.Wait() | ||
// 等待 SDK 和 服务端的数据同步,等待两个周期确保一定可以获取到最新的数据 | ||
time.Sleep(5 * time.Second) | ||
|
||
zeroprotectIns := map[string]struct{}{} | ||
allReq := &polaris.GetAllInstancesRequest{} | ||
allReq.Service = service | ||
allReq.Namespace = namespace | ||
resp, err := consumer.GetAllInstances(allReq) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
lastHeartbeatTime := int64(0) | ||
// 实例全部不健康 | ||
for i := range resp.GetInstances() { | ||
ins := resp.GetInstances()[i] | ||
if ins.IsHealthy() { | ||
log.Fatalf("ins: %s still health", ins.GetId()) | ||
} | ||
beatTime := ins.GetMetadata()[zeroprotect.MetadataInstanceLastHeartbeatTime] | ||
sec, _ := strconv.ParseInt(beatTime, 10, 64) | ||
if lastHeartbeatTime <= sec { | ||
lastHeartbeatTime = sec | ||
} | ||
} | ||
for i := range resp.GetInstances() { | ||
ins := resp.GetInstances()[i] | ||
beatTime := ins.GetMetadata()[zeroprotect.MetadataInstanceLastHeartbeatTime] | ||
sec, _ := strconv.ParseInt(beatTime, 10, 64) | ||
if zeroprotect.NeedZeroProtect(lastHeartbeatTime, sec, 2) { | ||
zeroprotectIns[ins.GetId()] = struct{}{} | ||
} | ||
} | ||
|
||
log.Printf("====== expect zero protect ======\n%s\n====== expect zero protect ======", zeroprotectIns) | ||
|
||
useConsumerAPI(consumer, zeroprotectIns) | ||
useRouterAPI(consumer, router, zeroprotectIns) | ||
} | ||
|
||
func useConsumerAPI(consumer polaris.ConsumerAPI, zeroprotectIns map[string]struct{}) { | ||
insReq := &polaris.GetInstancesRequest{} | ||
insReq.Service = service | ||
insReq.Namespace = namespace | ||
|
||
// 由于 polaris.yaml afterChain 配置的为 zeroProtectRouter,因此这里不会在走原先默认的全死全活路由策略 | ||
resp, err := consumer.GetInstances(insReq) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
insJson, _ := json.Marshal(resp.GetInstances()) | ||
log.Printf("====== useConsumerAPI zero protect ======\n%s\n====== useConsumerAPI zero protect ======", string(insJson)) | ||
|
||
if len(resp.GetInstances()) == int(insCount) { | ||
log.Fatal("zero protect fail") | ||
} | ||
|
||
if len(zeroprotectIns) != len(resp.GetInstances()) { | ||
log.Fatalf("zero protect recover instance count:%d not expect:%d", len(resp.GetInstances()), len(zeroprotectIns)) | ||
} | ||
} | ||
|
||
func useRouterAPI(consumer polaris.ConsumerAPI, router polaris.RouterAPI, zeroprotectIns map[string]struct{}) { | ||
allReq := &polaris.GetAllInstancesRequest{} | ||
allReq.Service = service | ||
allReq.Namespace = namespace | ||
resp, err := consumer.GetAllInstances(allReq) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
// 实例全部不健康 | ||
for i := range resp.GetInstances() { | ||
ins := resp.GetInstances()[i] | ||
if ins.IsHealthy() { | ||
log.Fatalf("ins: %s still health", ins.GetId()) | ||
} | ||
} | ||
|
||
routeReq := &polaris.ProcessRoutersRequest{} | ||
routeReq.DstInstances = resp | ||
// 默认配置文件走 zeroProtectRouter | ||
routeReq.Routers = []string{} | ||
routeResp, err := router.ProcessRouters(routeReq) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
insJson, _ := json.Marshal(routeResp.GetInstances()) | ||
log.Printf("====== useRouterAPI zero protect ======\n%s\n====== useRouterAPI zero protect ======", string(insJson)) | ||
|
||
if len(routeResp.GetInstances()) == int(insCount) { | ||
log.Fatal("zero protect fail") | ||
} | ||
|
||
if len(zeroprotectIns) != len(routeResp.GetInstances()) { | ||
log.Fatalf("zero protect recover instance count:%d not expect:%d", len(routeResp.GetInstances()), len(zeroprotectIns)) | ||
} | ||
routeReq = &polaris.ProcessRoutersRequest{} | ||
routeReq.DstInstances = resp | ||
// 显示设置走全死全活路由 | ||
routeReq.Routers = []string{config.DefaultServiceRouterFilterOnly} | ||
routeResp, err = router.ProcessRouters(routeReq) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
insJson, _ = json.Marshal(routeResp.GetInstances()) | ||
log.Printf("====== useRouterAPI not zero protect ======\n%s\n====== useRouterAPI not zero protect ======", string(insJson)) | ||
if len(routeResp.GetInstances()) != int(insCount) { | ||
log.Fatal("filterOnly fail") | ||
} | ||
|
||
if len(zeroprotectIns) == len(routeResp.GetInstances()) { | ||
log.Fatal("can't use zero protect recover instance") | ||
} | ||
} | ||
|
||
func createInstances(provider polaris.ProviderAPI) (*sync.WaitGroup, *sync.Map) { | ||
wait := &sync.WaitGroup{} | ||
wait.Add(int(insCount)) | ||
|
||
beatTime := &sync.Map{} | ||
for i := 0; i < int(insCount); i++ { | ||
registerRequest := &polaris.InstanceRegisterRequest{} | ||
registerRequest.Service = service | ||
registerRequest.Namespace = namespace | ||
registerRequest.Host = "127.0.0.1" | ||
registerRequest.Port = basePort + i | ||
registerRequest.ServiceToken = token | ||
registerRequest.SetTTL(2) | ||
resp, err := provider.Register(registerRequest) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
// 维持三次心跳 | ||
go func(id string, port, a int) { | ||
defer wait.Done() | ||
for tick := 0; tick < 2*a; tick++ { | ||
beatRequest := &polaris.InstanceHeartbeatRequest{} | ||
beatRequest.InstanceID = id | ||
beatRequest.Service = service | ||
beatRequest.Namespace = namespace | ||
beatRequest.Host = "127.0.0.1" | ||
beatRequest.Port = port | ||
|
||
if err := provider.Heartbeat(beatRequest); err != nil { | ||
log.Printf("%s heartbeat fail : %+v", beatRequest, err) | ||
} | ||
|
||
beatTime.Store(id, time.Now().Unix()) | ||
time.Sleep(2 * time.Second) | ||
} | ||
// 等待实例转为不健康 | ||
for tick := 0; tick < 3; tick++ { | ||
time.Sleep(3 * time.Second) | ||
} | ||
}(resp.InstanceID, basePort+i, i) | ||
} | ||
|
||
return wait, beatTime | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
global: | ||
serverConnector: | ||
addresses: | ||
- 127.0.0.1:8091 | ||
statReporter: | ||
enable: true | ||
chain: | ||
- prometheus | ||
# - pushgateway | ||
plugin: | ||
prometheus: | ||
type: pull | ||
metricPort: 0 | ||
consumer: | ||
#描述:服务路由相关配置 | ||
serviceRouter: | ||
# 服务路由链 | ||
chain: | ||
# 基于主调和被调服务规则的路由策略(默认的路由策略) | ||
- ruleBasedRouter | ||
# 就近路由策略 | ||
- nearbyBasedRouter | ||
afterChain: | ||
# 兜底路由,默认存在 | ||
# - filterOnlyRouter | ||
# 开启零实例保护路由,和 filterOnlyRouter 互斥 | ||
- zeroProtectRouter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
global: | ||
serverConnector: | ||
addresses: | ||
- 127.0.0.1:8091 | ||
- 139.186.249.101:8091 | ||
statReporter: | ||
enable: false | ||
chain: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.