Skip to content

Commit

Permalink
chore: 🤖 删除 debugGrayWeight字段,同时按照比例灰度优先支持 grayKey 的用户粘滞
Browse files Browse the repository at this point in the history
  • Loading branch information
heimanba committed Sep 12, 2024
1 parent 230710a commit 102f5f6
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 39 deletions.
7 changes: 4 additions & 3 deletions plugins/wasm-go/extensions/frontend-gray/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
| `baseDeployment` | object | 非必填 | - | 配置Base基线规则的配置 |
| `grayDeployments` | array of object | 非必填 | - | 配置Gray灰度的生效规则,以及生效版本 |
| `backendGrayTag` | string | 非必填 | `x-mse-tag` | 后端灰度版本Tag,如果配置了,cookie中将携带值为`${backendGrayTag}:${grayDeployments[].backendVersion}` |
| `debugGrayWeight` | boolean | 非必填 | - | 开启按照比例灰度的Debug模式,用于观测按比例灰度效果, |
| `injection` | object | 非必填 | - | 往首页HTML中注入全局信息,比如`<script>window.global = {...}</script>` |


Expand Down Expand Up @@ -52,7 +51,9 @@
| `backendVersion` | string | 必填 | - | 后端灰度版本,配合`key``${backendGrayTag}`,写入cookie中 |
| `name` | string | 必填 | - | 规则名称和`rules[].name`关联, |
| `enabled` | boolean | 必填 | - | 是否启动当前灰度规则 |
| `weight` | int | 非必填 | - | 按照比例灰度,比如`50`。注意:灰度规则权重总和不能超过100,如果配置了`weight`,则优先生效 |
| `weight` | int | 非必填 | - | 按照比例灰度,比如`50`。注意:灰度规则权重总和不能超过100,如果同时配置了`grayKey`以及`grayDeployments[0].weight`按照比例灰度优先生效 |
> 为了实现按比例(weight) 进行灰度发布,并确保用户粘滞,我们需要确认客户端的唯一性。如果配置了 grayKey,则将其用作唯一标识;如果未配置 grayKey,则使用客户端的访问 IP 地址作为唯一标识。

`injection`字段配置说明:

Expand Down Expand Up @@ -119,7 +120,7 @@ grayDeployments:
enabled: true
weight: 80
```
总的灰度规则为100%,其中灰度版本的权重为`80%`,基线版本为`20%`。一旦用户命中了灰度规则,会根据IP固定这个用户的灰度版本(否则会在下次请求时随机选择一个灰度版本)。如果需要观测按比例灰度是否生效,使用`debugGrayWeight`开启Debug模式。
总的灰度规则为100%,其中灰度版本的权重为`80%`,基线版本为`20%`。一旦用户命中了灰度规则,会根据IP固定这个用户的灰度版本(否则会在下次请求时随机选择一个灰度版本)。

### 用户信息存在JSON中

Expand Down
4 changes: 1 addition & 3 deletions plugins/wasm-go/extensions/frontend-gray/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

const (
XHigressTag = "x-higress-tag"
XForwardedFor = "x-forwarded-for"
XUniqueClient = "x-unique-client"
XPreHigressTag = "x-pre-higress-tag"
IsIndex = "is-index"
IsNotFound = "is-not-found"
Expand Down Expand Up @@ -58,7 +58,6 @@ type GrayConfig struct {
Rewrite *Rewrite
BaseDeployment *Deployment
GrayDeployments []*Deployment
DebugGrayWeight bool
BackendGrayTag string
Injection *Injection
}
Expand All @@ -84,7 +83,6 @@ func JsonToGrayConfig(json gjson.Result, grayConfig *GrayConfig) {
// 解析 GrayKey
grayConfig.GrayKey = json.Get("grayKey").String()
grayConfig.GraySubKey = json.Get("graySubKey").String()
grayConfig.DebugGrayWeight = json.Get("debugGrayWeight").Bool()
grayConfig.BackendGrayTag = json.Get("backendGrayTag").String()

if grayConfig.BackendGrayTag == "" {
Expand Down
4 changes: 2 additions & 2 deletions plugins/wasm-go/extensions/frontend-gray/envoy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ static_resources:
{
"name": "beta-user",
"version": "0.0.1",
"enabled": true
"enabled": true,
"weight": 50
}
],
"debugGrayWeight": true,
"injection": {
"head": [
"<script>console.log('Header')</script>"
Expand Down
16 changes: 11 additions & 5 deletions plugins/wasm-go/extensions/frontend-gray/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,18 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, grayConfig config.GrayConfig,
xPreHigressVersion := util.ExtractCookieValueByKey(cookies, config.XPreHigressTag)
preVersions := strings.Split(xPreHigressVersion, ",")

xForwardedFor, _ := proxywasm.GetHttpRequestHeader("X-Forwarded-For")
// 客户端唯一ID,用于在按照比率灰度时候 客户访问黏贴
uniqueClientId := grayKeyValue
if uniqueClientId == "" {
xForwardedFor, _ := proxywasm.GetHttpRequestHeader("X-Forwarded-For")
uniqueClientId = util.GetRealIpFromXff(xForwardedFor)
}

// 如果没有配置比例,则进行灰度规则匹配
if isIndex {
log.Infof("grayConfig.TotalGrayWeight==== %v", grayConfig.TotalGrayWeight)
if grayConfig.TotalGrayWeight > 0 {
deployment = util.FilterGrayWeight(&grayConfig, preVersions, xForwardedFor)
deployment = util.FilterGrayWeight(&grayConfig, preVersions, uniqueClientId)
} else {
deployment = util.FilterGrayRule(&grayConfig, grayKeyValue)
}
Expand All @@ -80,7 +86,7 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, grayConfig config.GrayConfig,
ctx.SetContext(config.XPreHigressTag, deployment.Version)
ctx.SetContext(grayConfig.BackendGrayTag, deployment.BackendVersion)
ctx.SetContext(config.IsIndex, isIndex)
ctx.SetContext(config.XForwardedFor, xForwardedFor)
ctx.SetContext(config.XUniqueClient, uniqueClientId)

rewrite := grayConfig.Rewrite
if rewrite.Host != "" {
Expand Down Expand Up @@ -154,10 +160,10 @@ func onHttpResponseHeader(ctx wrapper.HttpContext, grayConfig config.GrayConfig,
proxywasm.ReplaceHttpResponseHeader("Cache-Control", "no-cache, no-store")

frontendVersion := ctx.GetContext(config.XPreHigressTag).(string)
xForwardedFor := ctx.GetContext(config.XForwardedFor).(string)
xUniqueClient := ctx.GetContext(config.XUniqueClient).(string)

// 设置前端的版本
proxywasm.AddHttpResponseHeader("Set-Cookie", fmt.Sprintf("%s=%s,%s; Max-Age=%s; Path=/;", config.XPreHigressTag, frontendVersion, util.GetRealIpFromXff(xForwardedFor), config.MaxAgeCookie))
proxywasm.AddHttpResponseHeader("Set-Cookie", fmt.Sprintf("%s=%s,%s; Max-Age=%s; Path=/;", config.XPreHigressTag, frontendVersion, xUniqueClient, config.MaxAgeCookie))
// 设置后端的版本
if util.IsBackendGrayEnabled(grayConfig) {
backendVersion := ctx.GetContext(grayConfig.BackendGrayTag).(string)
Expand Down
39 changes: 13 additions & 26 deletions plugins/wasm-go/extensions/frontend-gray/util/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"math/rand"
"net/url"
"os"
"path"
"path/filepath"
"sort"
Expand All @@ -20,9 +19,7 @@ import (

func LogInfof(format string, args ...interface{}) {
format = fmt.Sprintf("[%s] %s", "frontend-gray", format)
if os.Getenv("TEST_MODE") != "" {
proxywasm.LogInfof(format, args...)
}
proxywasm.LogInfof(format, args...)
}

// 从xff中获取真实的IP
Expand Down Expand Up @@ -234,31 +231,21 @@ func FilterGrayRule(grayConfig *config.GrayConfig, grayKeyValue string) *config.
return grayConfig.BaseDeployment
}

func FilterGrayWeight(grayConfig *config.GrayConfig, preVersions []string, xForwardedFor string) *config.Deployment {
deployments := append(grayConfig.GrayDeployments, grayConfig.BaseDeployment)
realIp := GetRealIpFromXff(xForwardedFor)

LogInfof("DebugGrayWeight enabled: %s, realIp: %s, preVersions: %v", grayConfig.DebugGrayWeight, realIp, preVersions)
// 开启Debug模式,否则无法观测到效果
if !grayConfig.DebugGrayWeight {
// 如果没有获取到真实IP,则返回不走灰度规则
if realIp == "" {
return grayConfig.BaseDeployment
}

// 确保每个用户每次访问的都是走同一版本
if len(preVersions) > 1 && preVersions[1] != "" && realIp == preVersions[1] {
for _, deployment := range deployments {
if deployment.Version == strings.Trim(preVersions[0], " ") {
return deployment
}
}
}
func FilterGrayWeight(grayConfig *config.GrayConfig, preVersions []string, uniqueClientId string) *config.Deployment {
// 如果没有灰度权重,直接返回基础版本
if grayConfig.TotalGrayWeight == 0 {
return grayConfig.BaseDeployment
}

if grayConfig.TotalGrayWeight == 0 {
return grayConfig.BaseDeployment
deployments := append(grayConfig.GrayDeployments, grayConfig.BaseDeployment)
LogInfof("uniqueClientId: %s, preVersions: %v", uniqueClientId, preVersions)
// 用户粘滞,确保每个用户每次访问的都是走同一版本
if len(preVersions) > 1 && preVersions[1] != "" && uniqueClientId == preVersions[1] {
for _, deployment := range deployments {
if deployment.Version == strings.Trim(preVersions[0], " ") {
return deployment
}
}
}

totalWeight := 100
Expand Down

0 comments on commit 102f5f6

Please sign in to comment.