docs: add IDEA shadow deployment and rollback guide

This commit is contained in:
zgw
2026-08-11 19:38:26 +08:00
parent 8b050ac9d6
commit 2fbb20c5b1
5 changed files with 365 additions and 9 deletions

View File

@@ -178,3 +178,15 @@ xss:
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 影子算法默认关闭;现场测试仅通过 IDEA 环境变量显式开启
fortucky:
shadow:
enabled: ${FORTUCKY_SHADOW_ENABLED:false}
warehouse-id: ${FORTUCKY_SHADOW_WAREHOUSE_ID:}
timeout-seconds: ${FORTUCKY_SHADOW_TIMEOUT_SECONDS:3}
algorithm:
mode: ${FORTUCKY_ALGORITHM_MODE:SHADOW}
warehouse-id: ${FORTUCKY_ALGORITHM_WAREHOUSE_ID:01}
database-writes-enabled: ${FORTUCKY_ALGORITHM_DATABASE_WRITES_ENABLED:true}
legacy-fallback-on-technical-error: ${FORTUCKY_ALGORITHM_LEGACY_FALLBACK_ON_TECHNICAL_ERROR:false}

View File

@@ -0,0 +1,60 @@
package com.ruoyi.algorithm.shadow;
import com.ruoyi.algorithm.integration.AlgorithmProperties;
import com.ruoyi.algorithm.integration.SchedulingMode;
import org.junit.jupiter.api.Test;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mock.env.MockEnvironment;
import java.io.IOException;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class ShadowConfigurationTest {
@Test
void applicationDefaultsKeepShadowDisabledAndReadyForExplicitShadowEnablement() throws IOException {
MockEnvironment environment = new MockEnvironment();
Binder binder = applicationBinder(environment);
ShadowObservationProperties shadow = binder
.bind("fortucky.shadow", Bindable.of(ShadowObservationProperties.class))
.orElseThrow(() -> new IllegalStateException("fortucky.shadow configuration is missing"));
AlgorithmProperties algorithm = binder
.bind("fortucky.algorithm", Bindable.of(AlgorithmProperties.class))
.orElseThrow(() -> new IllegalStateException("fortucky.algorithm configuration is missing"));
assertThat(shadow.isEnabled()).isFalse();
assertThat(shadow.getWarehouseId()).isEmpty();
assertThat(shadow.getTimeoutSeconds()).isEqualTo(3);
assertThat(algorithm.getMode()).isEqualTo(SchedulingMode.SHADOW);
assertThat(algorithm.isDatabaseWritesEnabled()).isTrue();
assertThat(algorithm.getWarehouseId()).isEqualTo("01");
}
@Test
void standardLegacyFallbackEnvironmentVariableOverridesTheSafeDefault() throws IOException {
MockEnvironment environment = new MockEnvironment()
.withProperty("FORTUCKY_ALGORITHM_LEGACY_FALLBACK_ON_TECHNICAL_ERROR", "true");
AlgorithmProperties algorithm = applicationBinder(environment)
.bind("fortucky.algorithm", Bindable.of(AlgorithmProperties.class))
.orElseThrow(() -> new IllegalStateException("fortucky.algorithm configuration is missing"));
assertThat(algorithm.isLegacyFallbackOnTechnicalError()).isTrue();
}
private Binder applicationBinder(MockEnvironment environment) throws IOException {
MutablePropertySources propertySources = environment.getPropertySources();
List<PropertySource<?>> yaml = new YamlPropertySourceLoader()
.load("application", new ClassPathResource("application.yml"));
yaml.forEach(propertySources::addLast);
return Binder.get(environment);
}
}