Skip to content

Commit

Permalink
perf: Job 切换 GSE2.0 支持灰度策略 TencentBlueKing#2461
Browse files Browse the repository at this point in the history
  • Loading branch information
wangyu096 committed Sep 20, 2023
1 parent 3c74d36 commit bcf3b98
Show file tree
Hide file tree
Showing 22 changed files with 621 additions and 89 deletions.
2 changes: 2 additions & 0 deletions src/backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ ext {
println "bkjobVersion:" + bkjobVersion
}
set('bkAuditJavaSdkVersion', "1.0.6-SNAPSHOT")
set('mockitoVersion', "4.0.0")
}

group "com.tencent.bk.job"
Expand Down Expand Up @@ -329,6 +330,7 @@ subprojects {
dependency "com.beust:jcommander:$jcommanderVersion"
dependency "com.tencent.bk.sdk:crypto-java-sdk:$cryptoJavaSDKVersion"
dependency "com.tencent.bk.sdk:spring-boot-bk-audit-starter:$bkAuditJavaSdkVersion"
dependency "org.mockito:mockito-inline:$mockitoVersion"
}
}
dependencies {
Expand Down
1 change: 1 addition & 0 deletions src/backend/commons/common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,5 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.mockito:mockito-inline'
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.Data;

import java.util.List;
import java.util.Map;

/**
Expand All @@ -13,6 +14,15 @@ public class ToggleStrategyConfig {
* 策略ID
*/
private String id;
/**
* 策略说明
*/
private String description;
/**
* 组合策略
*/
private List<ToggleStrategyConfig> strategies;

/**
* 策略初始化参数
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.tencent.bk.job.common.util.feature;

import com.tencent.bk.job.common.model.dto.ResourceScope;
import com.tencent.bk.job.common.util.feature.strategy.ToggleStrategyContextParams;

import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;

Expand All @@ -10,19 +14,29 @@ public class FeatureExecutionContext {
/**
* 运行时参数
*/
private final Map<String, Object> params;
private final Map<String, Object> params = new HashMap<>();

public static FeatureExecutionContext builder() {
return new FeatureExecutionContext();
}

public FeatureExecutionContext(Map<String, Object> params) {
this.params = params;
private FeatureExecutionContext() {
}

public Object getParam(String paramName) {
if (params == null) {
return null;
}
return this.params.get(paramName);
}

public FeatureExecutionContext addContextParam(String paramName, Object value) {
this.params.put(paramName, value);
return this;
}

public FeatureExecutionContext addResourceScopeContextParam(ResourceScope resourceScope) {
params.put(ToggleStrategyContextParams.CTX_PARAM_RESOURCE_SCOPE, resourceScope);
return this;
}

@Override
public String toString() {
return new StringJoiner(", ", FeatureExecutionContext.class.getSimpleName() + "[", "]")
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@
import com.tencent.bk.job.common.service.config.ToggleStrategyConfig;
import com.tencent.bk.job.common.util.ApplicationContextRegister;
import com.tencent.bk.job.common.util.feature.strategy.FeatureConfigParseException;
import com.tencent.bk.job.common.util.feature.strategy.ResourceScopeBlackListToggleStrategy;
import com.tencent.bk.job.common.util.feature.strategy.ResourceScopeWhiteListToggleStrategy;
import com.tencent.bk.job.common.util.feature.strategy.ToggleStrategy;
import com.tencent.bk.job.common.util.feature.strategy.WeightToggleStrategy;
import com.tencent.bk.job.common.util.feature.strategy.ToggleStrategyRegister;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.helpers.MessageFormatter;
Expand Down Expand Up @@ -103,23 +101,7 @@ private static Feature parseFeatureConfig(String featureId,
if (featureConfig.isEnabled()) {
ToggleStrategyConfig strategyConfig = featureConfig.getStrategy();
if (strategyConfig != null) {
String strategyId = strategyConfig.getId();
ToggleStrategy toggleStrategy = null;
switch (strategyId) {
case ResourceScopeWhiteListToggleStrategy.STRATEGY_ID:
toggleStrategy = new ResourceScopeWhiteListToggleStrategy(strategyConfig.getParams());
break;
case ResourceScopeBlackListToggleStrategy.STRATEGY_ID:
toggleStrategy = new ResourceScopeBlackListToggleStrategy(strategyConfig.getParams());
break;
case WeightToggleStrategy.STRATEGY_ID:
toggleStrategy = new WeightToggleStrategy(strategyConfig.getParams());
break;
default:
log.error("Unsupported toggle strategy: {} for feature: {}, ignore it!", strategyId,
featureId);
break;
}
ToggleStrategy toggleStrategy = parseToggleStrategy(strategyConfig);
if (toggleStrategy != null) {
feature.setStrategy(toggleStrategy);
}
Expand All @@ -128,6 +110,55 @@ private static Feature parseFeatureConfig(String featureId,
return feature;
}

private static ToggleStrategy parseToggleStrategy(ToggleStrategyConfig strategyConfig) {
String strategyId = strategyConfig.getId();
return ToggleStrategyRegister.getToggleStrategyInitial(strategyId)
.build(strategyConfig);
}

// private static ToggleStrategy parseToggleStrategy(ToggleStrategyConfig strategyConfig) {
// String strategyId = strategyConfig.getId();
// ToggleStrategy toggleStrategy = null;
// ToggleStrategyInitial strategyInitial = ToggleStrategyRegister.getToggleStrategyInitial(strategyId);
// toggleStrategy = strategyInitial.build(strategyConfig);
// switch (strategyId) {
// case ResourceScopeWhiteListToggleStrategy.STRATEGY_ID:
// toggleStrategy = new ResourceScopeWhiteListToggleStrategy(strategyConfig.getDescription(),
// strategyConfig.getParams());
// break;
// case ResourceScopeBlackListToggleStrategy.STRATEGY_ID:
// toggleStrategy = new ResourceScopeBlackListToggleStrategy(strategyConfig.getDescription(),
// strategyConfig.getParams());
// break;
// case WeightToggleStrategy.STRATEGY_ID:
// toggleStrategy = new WeightToggleStrategy(strategyConfig.getDescription(),
// strategyConfig.getParams());
// break;
// case AllMatchToggleStrategy.STRATEGY_ID:
// toggleStrategy = new AllMatchToggleStrategy(
// strategyId,
// strategyConfig.getStrategies()
// .stream()
// .map(FeatureToggle::parseToggleStrategy)
// .collect(Collectors.toList()),
// strategyConfig.getParams());
// break;
// case AnyMatchToggleStrategy.STRATEGY_ID:
// toggleStrategy = new AnyMatchToggleStrategy(
// strategyId,
// strategyConfig.getStrategies()
// .stream()
// .map(FeatureToggle::parseToggleStrategy)
// .collect(Collectors.toList()),
// strategyConfig.getParams());
// break;
// default:
// log.error("Unsupported toggle strategy: {} , ignore it!", strategyId);
// break;
// }
// return toggleStrategy;
// }


/**
* 判断特性是否开启
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,11 @@ public abstract class AbstractResourceScopeToggleStrategy extends AbstractToggle
* 策略初始化参数-资源范围
*/
public static final String INIT_PARAM_RESOURCE_SCOPE_LIST = "resourceScopeList";
/**
* 上下文参数-资源范围
*/
public static final String CTX_PARAM_RESOURCE_SCOPE = "resourceScope";

protected final Set<ResourceScope> resourceScopes = new HashSet<>();

public AbstractResourceScopeToggleStrategy(String strategyId, Map<String, String> initParams) {
super(strategyId, initParams);
public AbstractResourceScopeToggleStrategy(String strategyId, String description, Map<String, String> initParams) {
super(strategyId, description, null, initParams);
assertRequiredParameter(INIT_PARAM_RESOURCE_SCOPE_LIST);

String resourceScopesValue = initParams.get(INIT_PARAM_RESOURCE_SCOPE_LIST);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.tencent.bk.job.common.util.feature.strategy;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.helpers.MessageFormatter;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
Expand All @@ -14,16 +16,44 @@
public abstract class AbstractToggleStrategy implements ToggleStrategy {

protected final String id;
protected final String description;
protected List<ToggleStrategy> compositeStrategies = null;
protected final Map<String, String> initParams;

/**
* 初始化特性开关
*
* @param strategyId 策略ID
* @param initParams 初始化参数
* @param strategyId 策略ID
* @param description 策略说明
* @param compositeStrategies 子策略
* @param initParams 初始化参数
*/
public AbstractToggleStrategy(String strategyId, Map<String, String> initParams) {
public AbstractToggleStrategy(String strategyId,
String description,
List<ToggleStrategy> compositeStrategies,
Map<String, String> initParams) {
this.id = strategyId;
this.description = description;
this.compositeStrategies = compositeStrategies;
if (initParams != null) {
this.initParams = initParams;
} else {
this.initParams = new HashMap<>();
}
}

/**
* 初始化特性开关
*
* @param strategyId 策略ID
* @param description 策略说明
* @param initParams 初始化参数
*/
public AbstractToggleStrategy(String strategyId,
String description,
Map<String, String> initParams) {
this.id = strategyId;
this.description = description;
if (initParams != null) {
this.initParams = initParams;
} else {
Expand Down Expand Up @@ -59,4 +89,12 @@ public void assertRequiredAtLeastOneParameter(String... paramNames) {
throw new FeatureConfigParseException(msg);
}
}

public void assertRequiredAtLeastOneStrategy() {
if (!CollectionUtils.isEmpty(this.compositeStrategies)) {
String msg = "Required at least one strategy for this ToggleStrategy";
log.error(msg);
throw new FeatureConfigParseException(msg);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.tencent.bk.job.common.util.feature.strategy;

import com.tencent.bk.job.common.util.feature.FeatureExecutionContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.security.SecureRandom;
import java.util.Map;
import java.util.Random;
import java.util.StringJoiner;

@Slf4j
public class AllGseV2AgentToggleStrategy extends AbstractToggleStrategy {
/**
* 策略参数-权重
*/
public static final String INIT_PARAM_WEIGHT = "weight";
/**
* 特性开关开启策略ID
*/
public static final String STRATEGY_ID = "AllGseV2AgentToggleStrategy";

private final int weight;

private final Random RANDOM = new SecureRandom();

public AllGseV2AgentToggleStrategy(String description, Map<String, String> initParams) {
super(STRATEGY_ID, description, initParams);
assertRequiredParameter(INIT_PARAM_WEIGHT);
String weightStrValue = initParams.get(INIT_PARAM_WEIGHT);
this.weight = computeWeight(weightStrValue);
}

private int computeWeight(String weightStrValue) {
String weightValue = weightStrValue.trim();
if (StringUtils.isBlank(weightStrValue)) {
log.error("Weight is empty!");
throw new FeatureConfigParseException("Weight is empty!");
}
try {
int weight = Integer.parseInt(weightValue);
if (weight < 0 || weight > 100) {
log.error("Weight should be set between 0 and 100, value: {}", weight);
throw new FeatureConfigParseException("Weight should be set between 0 and 100");
}
return weight;
} catch (NumberFormatException e) {
log.error("Invalid weight value: {}, not a valid number", weightValue);
throw new FeatureConfigParseException("Weight should be a number");
}
}

@Override
public boolean evaluate(String featureId, FeatureExecutionContext ctx) {
if (weight == 0) {
return false;
} else if (weight == 100) {
return true;
} else {
int random = RANDOM.nextInt(100) + 1;
return random <= weight;
}
}

@Override
public String toString() {
return new StringJoiner(", ", AllGseV2AgentToggleStrategy.class.getSimpleName() + "[", "]")
.add("id='" + id + "'")
.add("initParams=" + initParams)
.add("weight=" + weight)
.toString();
}
}
Loading

0 comments on commit bcf3b98

Please sign in to comment.