Skip to content

Commit

Permalink
perf: Job中的主机根据其对应业务的灰度情况展示Agent状态 #2492
Browse files Browse the repository at this point in the history
处理Review意见。
  • Loading branch information
jsonwan committed Oct 24, 2023
1 parent f17a735 commit 91e00f8
Show file tree
Hide file tree
Showing 18 changed files with 234 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@
package com.tencent.bk.job.common.service.feature;

import com.tencent.bk.job.common.model.dto.ResourceScope;
import com.tencent.bk.job.common.util.feature.ToggleStrategyContextParams;
import com.tencent.bk.job.common.util.feature.Feature;
import com.tencent.bk.job.common.util.feature.FeatureExecutionContext;
import com.tencent.bk.job.common.util.feature.FeatureManager;
import com.tencent.bk.job.common.util.feature.FeatureStore;
import com.tencent.bk.job.common.util.feature.ToggleStrategy;
import com.tencent.bk.job.common.util.feature.ToggleStrategyContextParams;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tags;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -54,6 +54,17 @@ public DefaultFeatureManager(FeatureStore featureStore, MeterRegistry meterRegis
this.meterRegistry = meterRegistry;
}

public boolean isFeatureEnabled(String featureId) {
Feature feature = featureStore.getFeature(featureId);
if (feature == null) {
if (log.isDebugEnabled()) {
log.debug("Feature: {} is not exist!", featureId);
}
return false;
}
return feature.isEnabled();
}

/**
* 判断特性是否开启
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,12 @@ public void assertRequiredInitParam(String paramName) {
}



public void assertRequiredContextParam(FeatureExecutionContext context, String paramName) {
if (context.getParam(paramName) == null) {
String msg = MessageFormatter.format(
"Context param {} is required for evaluate", paramName).getMessage();
log.error(msg);
throw new FeatureConfigParseException(msg);
throw new FeatureParamMissingException(msg);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available.
*
* Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
*
* BK-JOB蓝鲸智云作业平台 is licensed under the MIT License.
*
* License for BK-JOB蓝鲸智云作业平台:
* --------------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
* to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of
* the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

package com.tencent.bk.job.common.service.feature.strategy;

/**
* 特性开关配置参数缺失异常
*/
public class FeatureParamMissingException extends RuntimeException {

public FeatureParamMissingException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,41 +106,29 @@ public JobInstanceAttrToggleStrategy(Map<String, String> initParams) {
@Override
public boolean evaluate(String featureId, FeatureExecutionContext ctx) {
if (requireAllGseV2AgentAvailable != null && requireAllGseV2AgentAvailable) {
Object isAllAgentV2AvailableObj = ctx.getParam(CTX_PARAM_IS_ALL_GSE_V2_AGENT_AVAILABLE);
if (isAllAgentV2AvailableObj == null) {
return false;
}
boolean isAllAgentV2Available = (boolean) isAllAgentV2AvailableObj;
assertRequiredContextParam(ctx, CTX_PARAM_IS_ALL_GSE_V2_AGENT_AVAILABLE);
boolean isAllAgentV2Available = (boolean) ctx.getParam(CTX_PARAM_IS_ALL_GSE_V2_AGENT_AVAILABLE);
if (!isAllAgentV2Available) {
return false;
}
}
if (requireAnyGseV2AgentAvailable != null && requireAnyGseV2AgentAvailable) {
Object isAnyAgentV2AvailableObj = ctx.getParam(CTX_PARAM_IS_ANY_GSE_V2_AGENT_AVAILABLE);
if (isAnyAgentV2AvailableObj == null) {
return false;
}
boolean isAnyAgentV2Available = (boolean) isAnyAgentV2AvailableObj;
assertRequiredContextParam(ctx, CTX_PARAM_IS_ANY_GSE_V2_AGENT_AVAILABLE);
boolean isAnyAgentV2Available = (boolean) ctx.getParam(CTX_PARAM_IS_ANY_GSE_V2_AGENT_AVAILABLE);
if (!isAnyAgentV2Available) {
return false;
}
}
if (CollectionUtils.isNotEmpty(startupModes)) {
Object startupModeObj = ctx.getParam(CTX_PARAM_STARTUP_MODE);
if (startupModeObj == null) {
return false;
}
String startupMode = (String) startupModeObj;
assertRequiredContextParam(ctx, CTX_PARAM_STARTUP_MODE);
String startupMode = (String) ctx.getParam(CTX_PARAM_STARTUP_MODE);
if (!startupModes.contains(startupMode)) {
return false;
}
}
if (CollectionUtils.isNotEmpty(operators)) {
Object operatorObj = ctx.getParam(CTX_PARAM_OPERATOR);
if (operatorObj == null) {
return false;
}
String operator = (String) operatorObj;
assertRequiredContextParam(ctx, CTX_PARAM_OPERATOR);
String operator = (String) ctx.getParam(CTX_PARAM_OPERATOR);
return operators.contains(operator);
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@
* 特性管理
*/
public interface FeatureManager {
/**
* 判断特性是否开启(只考虑特性本身,忽略策略)
*
* @param featureId 特性ID
* @return 是否开启
*/
boolean isFeatureEnabled(String featureId);

/**
* 判断特性是否开启
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,28 @@ public class FeatureToggle {
* @return 是否开启
*/
public static boolean checkFeature(String featureId, FeatureExecutionContext ctx) {
ensureFeatureManagerInited();
return featureManager.checkFeature(featureId, ctx);
}

/**
* 判断特性是否开启(只考虑特性本身,忽略策略)
*
* @param featureId 特性ID
* @return 是否开启
*/
public static boolean isFeatureEnabled(String featureId) {
ensureFeatureManagerInited();
return featureManager.isFeatureEnabled(featureId);
}

private static void ensureFeatureManagerInited() {
if (featureManager == null) {
synchronized (FeatureToggle.class) {
if (featureManager == null) {
featureManager = ApplicationContextRegister.getBean(FeatureManager.class);
}
}
}

return featureManager.checkFeature(featureId, ctx);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ public ThreadPoolExecutor agentStatusQueryExecutor(MeterRegistry meterRegistry,
);
}

@ConditionalOnMissingBean(value = AgentStateClient.class)
@Bean("PreferV2AgentStateClient")
@Bean(DefaultBeanNames.PREFER_V2_AGENT_STATE_CLIENT)
public AgentStateClient preferV2AgentStateClientImpl(AgentStateQueryConfig agentStateQueryConfig,
GseClient gseClient,
@Qualifier("agentStatusQueryExecutor")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,8 @@
public class DefaultBeanNames {
// Agent状态查询线程池Bean名称
public static final String AGENT_STATUS_QUERY_THREAD_POOL_EXECUTOR = "agentStatusQueryExecutor";
// 优先使用GSE V2的Agent状态查询Bean名称
public static final String PREFER_V2_AGENT_STATE_CLIENT = "PreferV2AgentStateClient";
// 基于特性配置决定是否使用GSE V2的Agent状态查询Bean名称
public static final String USE_V2_BY_FEATURE_AGENT_STATE_CLIENT = "UseV2ByFeatureAgentStateClient";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available.
*
* Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
*
* BK-JOB蓝鲸智云作业平台 is licensed under the MIT License.
*
* License for BK-JOB蓝鲸智云作业平台:
* --------------------------------------------------------------------
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
* to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of
* the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

package com.tencent.bk.job.common.gse.service;

import com.tencent.bk.job.common.gse.service.model.HostAgentStateQuery;
import com.tencent.bk.job.common.gse.v2.model.resp.AgentState;
import com.tencent.bk.job.common.util.feature.FeatureIdConstants;
import com.tencent.bk.job.common.util.feature.FeatureToggle;
import lombok.extern.slf4j.Slf4j;

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

/**
* 根据动态变化的特性配置自动选择应当使用的AgentStateClient
*/
@Slf4j
public class AutoChoosingAgentStateClientImpl implements AgentStateClient {

private final AgentStateClient preferV2AgentStateClient;
private final AgentStateClient useV2ByFeatureAgentStateClient;

public AutoChoosingAgentStateClientImpl(AgentStateClient preferV2AgentStateClient,
AgentStateClient useV2ByFeatureAgentStateClient) {
this.preferV2AgentStateClient = preferV2AgentStateClient;
this.useV2ByFeatureAgentStateClient = useV2ByFeatureAgentStateClient;
}

@Override
public String getEffectiveAgentId(HostAgentStateQuery hostAgentStateQuery) {
AgentStateClient agentStateClient = chooseAgentStateByFeatureConfig();
return agentStateClient.getEffectiveAgentId(hostAgentStateQuery);
}

@Override
public AgentState getAgentState(HostAgentStateQuery hostAgentStateQuery) {
AgentStateClient agentStateClient = chooseAgentStateByFeatureConfig();
return agentStateClient.getAgentState(hostAgentStateQuery);
}

@Override
public Map<String, AgentState> batchGetAgentState(List<HostAgentStateQuery> hostAgentStateQueryList) {
AgentStateClient agentStateClient = chooseAgentStateByFeatureConfig();
return agentStateClient.batchGetAgentState(hostAgentStateQueryList);
}

@Override
public Map<String, Boolean> batchGetAgentAliveStatus(List<HostAgentStateQuery> hostAgentStateQueryList) {
AgentStateClient agentStateClient = chooseAgentStateByFeatureConfig();
return agentStateClient.batchGetAgentAliveStatus(hostAgentStateQueryList);
}

private AgentStateClient chooseAgentStateByFeatureConfig() {
AgentStateClient agentStateClient;
if (FeatureToggle.isFeatureEnabled(FeatureIdConstants.FEATURE_AGENT_STATUS_GSE_V2)) {
agentStateClient = useV2ByFeatureAgentStateClient;
} else {
agentStateClient = preferV2AgentStateClient;
}
return agentStateClient;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import com.tencent.bk.job.common.gse.config.AgentStateQueryConfig;
import com.tencent.bk.job.common.gse.constants.DefaultBeanNames;
import com.tencent.bk.job.common.gse.service.AgentStateClient;
import com.tencent.bk.job.common.gse.service.AutoChoosingAgentStateClientImpl;
import com.tencent.bk.job.common.gse.service.BizHostInfoQueryService;
import com.tencent.bk.job.common.gse.service.UseV2ByFeatureAgentStateClientImpl;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
Expand All @@ -17,12 +17,16 @@
@Configuration(value = "jobExecuteGseConfig")
public class GseConfig {

@Primary
@ConditionalOnProperty(name = "job.features.agentStatusGseV2.enabled", havingValue = "true")
@Bean("UseV2ByFeatureAgentStateClient")
public static final String EXECUTE_BEAN_PREFIX = "jobExecute";
public static final String EXECUTE_BEAN_AGENT_STATE_CLIENT = EXECUTE_BEAN_PREFIX + "AgentStateClient";
public static final String EXECUTE_BEAN_USE_V2_BY_FEATURE_AGENT_STATE_CLIENT =
EXECUTE_BEAN_PREFIX + DefaultBeanNames.USE_V2_BY_FEATURE_AGENT_STATE_CLIENT;

@Bean(EXECUTE_BEAN_USE_V2_BY_FEATURE_AGENT_STATE_CLIENT)
public AgentStateClient useV2ByFeatureAgentStateClient(AgentStateQueryConfig agentStateQueryConfig,
GseClient gseClient,
BizHostInfoQueryService bizHostInfoQueryService,
@Qualifier("jobExecuteBizHostInfoQueryService")
BizHostInfoQueryService bizHostInfoQueryService,
@Qualifier(DefaultBeanNames.AGENT_STATUS_QUERY_THREAD_POOL_EXECUTOR)
ThreadPoolExecutor threadPoolExecutor) {
return new UseV2ByFeatureAgentStateClientImpl(
Expand All @@ -32,4 +36,14 @@ public AgentStateClient useV2ByFeatureAgentStateClient(AgentStateQueryConfig age
threadPoolExecutor
);
}

@Primary
@Bean(EXECUTE_BEAN_AGENT_STATE_CLIENT)
public AgentStateClient AutoChoosingAgentStateClientImpl(
@Qualifier(DefaultBeanNames.PREFER_V2_AGENT_STATE_CLIENT) AgentStateClient preferV2AgentStateClient,
@Qualifier(EXECUTE_BEAN_USE_V2_BY_FEATURE_AGENT_STATE_CLIENT)
AgentStateClient useV2ByFeatureAgentStateClient
) {
return new AutoChoosingAgentStateClientImpl(preferV2AgentStateClient, useV2ByFeatureAgentStateClient);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.tencent.bk.job.common.gse.service.model.HostAgentStateQuery;
import com.tencent.bk.job.common.model.dto.HostDTO;
import com.tencent.bk.job.common.util.ip.IpUtils;
import com.tencent.bk.job.execute.config.GseConfig;
import com.tencent.bk.job.execute.engine.consts.Consts;
import com.tencent.bk.job.execute.model.ServersDTO;
import com.tencent.bk.job.execute.service.AgentService;
Expand All @@ -39,6 +40,7 @@
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

Expand Down Expand Up @@ -75,7 +77,8 @@ public HostDTO load(String key) {
);

@Autowired
public AgentServiceImpl(AgentStateClient agentStateClient,
public AgentServiceImpl(@Qualifier(GseConfig.EXECUTE_BEAN_AGENT_STATE_CLIENT)
AgentStateClient agentStateClient,
HostService hostService) {
this.agentStateClient = agentStateClient;
this.hostService = hostService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import java.util.stream.Collectors;

@Slf4j
@Service
@Service("jobExecuteBizHostInfoQueryService")
public class BizHostInfoQueryServiceImpl implements BizHostInfoQueryService {

private final ServiceHostResource hostResource;
Expand Down
Loading

0 comments on commit 91e00f8

Please sign in to comment.