Skip to content

Commit

Permalink
[ISSUE #148] support zero protect (#149)
Browse files Browse the repository at this point in the history
  • Loading branch information
chuntaojun authored May 25, 2023
1 parent 743d96f commit 0be9eb9
Show file tree
Hide file tree
Showing 49 changed files with 1,651 additions and 413 deletions.
2 changes: 1 addition & 1 deletion examples/activehealthcheck/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/polarismesh/polaris-go-active-healthcheck

go 1.17

require github.com/polarismesh/polaris-go v1.2.0-beta.3
require github.com/polarismesh/polaris-go v1.4.3

require (
github.com/beorn7/perks v1.0.1 // indirect
Expand Down
2 changes: 1 addition & 1 deletion examples/circuitbreaker/consumer/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/polarismesh/polaris-go-circuitbreaker-consumer

go 1.17

require github.com/polarismesh/polaris-go v1.2.0-beta.3
require github.com/polarismesh/polaris-go v1.4.3

require (
github.com/beorn7/perks v1.0.1 // indirect
Expand Down
2 changes: 1 addition & 1 deletion examples/circuitbreaker/provider/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/polarismesh/polaris-go-circuitbreaker-provider

go 1.17

require github.com/polarismesh/polaris-go v1.2.0-beta.3
require github.com/polarismesh/polaris-go v1.4.3

require (
github.com/beorn7/perks v1.0.1 // indirect
Expand Down
2 changes: 1 addition & 1 deletion examples/configuration/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/polarismesh/polaris-go-configuration

go 1.17

require github.com/polarismesh/polaris-go v1.2.0-beta.3
require github.com/polarismesh/polaris-go v1.4.3

require (
github.com/beorn7/perks v1.0.1 // indirect
Expand Down
38 changes: 38 additions & 0 deletions examples/extensions/zeroprotect/go.mod
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
)
580 changes: 580 additions & 0 deletions examples/extensions/zeroprotect/go.sum

Large diffs are not rendered by default.

223 changes: 223 additions & 0 deletions examples/extensions/zeroprotect/main.go
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
}
27 changes: 27 additions & 0 deletions examples/extensions/zeroprotect/polaris.yaml
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
2 changes: 1 addition & 1 deletion examples/quickstart/consumer/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/polarismesh/polaris-go-quickstart-consumer

go 1.17

require github.com/polarismesh/polaris-go v1.2.0-beta.3
require github.com/polarismesh/polaris-go v1.4.3

require (
github.com/beorn7/perks v1.0.1 // indirect
Expand Down
2 changes: 1 addition & 1 deletion examples/quickstart/provider/polaris.yaml
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:
Expand Down
2 changes: 1 addition & 1 deletion examples/ratelimit/consumer/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/polarismesh/polaris-go-ratelimit-consumer

go 1.17

require github.com/polarismesh/polaris-go v1.2.0-beta.3
require github.com/polarismesh/polaris-go v1.4.3

require (
github.com/beorn7/perks v1.0.1 // indirect
Expand Down
2 changes: 1 addition & 1 deletion examples/ratelimit/provider/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/polarismesh/polaris-go-ratelimit-provider

go 1.17

require github.com/polarismesh/polaris-go v1.2.0-beta.3
require github.com/polarismesh/polaris-go v1.4.3

require (
github.com/beorn7/perks v1.0.1 // indirect
Expand Down
2 changes: 1 addition & 1 deletion examples/route/dynamic/consumer/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/polarismesh/polaris-go-dynamic-consumer

go 1.17

require github.com/polarismesh/polaris-go v1.2.0-beta.3
require github.com/polarismesh/polaris-go v1.4.3

require (
github.com/beorn7/perks v1.0.1 // indirect
Expand Down
2 changes: 1 addition & 1 deletion examples/route/dynamic/provider/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/polarismesh/polaris-go-dynamic-provider

go 1.17

require github.com/polarismesh/polaris-go v1.2.0-beta.3
require github.com/polarismesh/polaris-go v1.4.3

require (
github.com/beorn7/perks v1.0.1 // indirect
Expand Down
2 changes: 1 addition & 1 deletion examples/route/nearby/consumer/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/polarismesh/polaris-go-nearby-consumer

go 1.17

require github.com/polarismesh/polaris-go v1.2.0-beta.3
require github.com/polarismesh/polaris-go v1.4.3

replace github.com/polarismesh/polaris-go => ../../../../

Expand Down
2 changes: 1 addition & 1 deletion examples/route/nearby/provider/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/polarismesh/polaris-go-nearby-provider

go 1.17

require github.com/polarismesh/polaris-go v1.2.0-beta.3
require github.com/polarismesh/polaris-go v1.4.3

require (
github.com/beorn7/perks v1.0.1 // indirect
Expand Down
Loading

0 comments on commit 0be9eb9

Please sign in to comment.