diff --git a/pom.xml b/pom.xml index 6f2a81c..412da7a 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ 1.8 5.2.12.RELEASE - Dysprosium-SR15 + Dysprosium-SR16 5.3.5.RELEASE 0.2.7 4.1.56.Final @@ -177,6 +177,18 @@ org.springframework.boot spring-boot-starter-data-redis-reactive + + it.ozimov + embedded-redis + 0.7.3 + test + + + org.slf4j + slf4j-simple + + + org.noear diff --git a/src/main/java/we/config/FlowStatSchedConfig.java b/src/main/java/we/config/FlowStatSchedConfig.java index 9141a7c..d9b4196 100644 --- a/src/main/java/we/config/FlowStatSchedConfig.java +++ b/src/main/java/we/config/FlowStatSchedConfig.java @@ -177,7 +177,7 @@ public class FlowStatSchedConfig extends SchedConfig { b.append(_minRespTime); b.append(w.getMin()); b.append(Constants.Symbol.RIGHT_BRACE); String msg = b.toString(); - if ("kafka".equals(dest)) { + if ("kafka".equals(dest)) { // for internal use log.warn(msg, LogService.HANDLE_STGY, LogService.toKF(queue)); } else { rt.convertAndSend(queue, msg).subscribe(); diff --git a/src/main/java/we/filter/FlowControlFilter.java b/src/main/java/we/filter/FlowControlFilter.java index 48f634c..bfabc49 100644 --- a/src/main/java/we/filter/FlowControlFilter.java +++ b/src/main/java/we/filter/FlowControlFilter.java @@ -79,8 +79,10 @@ public class FlowControlFilter extends ProxyAggrFilter { ResourceRateLimitConfig globalConfig = rlc; boolean concurrentOrRpsExceed = false; + boolean globalExceed = concurrentOrRpsExceed; if (rlc != null && rlc.isEnable()) { concurrentOrRpsExceed = !flowStat.incrRequest(rlc.resource, currentTimeSlot, rlc.concurrents, rlc.qps); + globalExceed = concurrentOrRpsExceed; } if (!concurrentOrRpsExceed) { @@ -92,9 +94,15 @@ public class FlowControlFilter extends ProxyAggrFilter { if (rlc == null || !rlc.isEnable()) { } else { concurrentOrRpsExceed = !flowStat.incrRequest(service, currentTimeSlot, rlc.concurrents, rlc.qps); + // if (!concurrentOrRpsExceed) { + // flowStat.incrRequest(reqPath, currentTimeSlot, Long.MAX_VALUE, Long.MAX_VALUE); + // } } } else { concurrentOrRpsExceed = !flowStat.incrRequest(service, currentTimeSlot, rlc.concurrents, rlc.qps); + // if (!concurrentOrRpsExceed) { + // flowStat.incrRequest(reqPath, currentTimeSlot, Long.MAX_VALUE, Long.MAX_VALUE); + // } } } else { // should not reach here for now concurrentOrRpsExceed = !flowStat.incrRequest(reqPath, currentTimeSlot, rlc.concurrents, rlc.qps); @@ -104,7 +112,7 @@ public class FlowControlFilter extends ProxyAggrFilter { } } - if (rlc == null || !rlc.isEnable()) { + if ((globalConfig == null && rlc == null) || (globalConfig == null && !rlc.isEnable()) || (rlc == null && !globalConfig.isEnable())) { flowStat.incrRequest(ResourceRateLimitConfig.GLOBAL, currentTimeSlot, Long.MAX_VALUE, Long.MAX_VALUE); flowStat.incrRequest(service, currentTimeSlot, Long.MAX_VALUE, Long.MAX_VALUE); // flowStat.incrRequest(reqPath, currentTimeSlot, Long.MAX_VALUE, Long.MAX_VALUE); @@ -113,16 +121,13 @@ public class FlowControlFilter extends ProxyAggrFilter { } if (concurrentOrRpsExceed) { - - if (rlc.type == ResourceRateLimitConfig.Type.API || rlc.type == ResourceRateLimitConfig.Type.SERVICE || rlc.type == ResourceRateLimitConfig.Type.SERVICE_DEFAULT) { - if (globalConfig != null && globalConfig.isEnable()) { - flowStat.decrConcurrentRequest(ResourceRateLimitConfig.GLOBAL, currentTimeSlot); - } + if (!globalExceed) { + flowStat.decrConcurrentRequest(ResourceRateLimitConfig.GLOBAL, currentTimeSlot); } StringBuilder b = ThreadContext.getStringBuilder(); b.append(WebUtils.getClientService(exchange)).append(Constants.Symbol.SPACE).append(WebUtils.getClientReqPath(exchange)); - b.append(exceed).append(rlc.resource).append(concurrents).append(rlc.concurrents).append(orQps).append(rlc.qps); + b.append(exceed) .append(rlc.resource) .append(concurrents).append(rlc.concurrents).append(orQps).append(rlc.qps); log.warn(b.toString(), LogService.BIZ_ID, exchange.getRequest().getId()); ServerHttpResponse resp = exchange.getResponse(); diff --git a/src/main/java/we/plugin/stat/StatPluginFilter.java b/src/main/java/we/plugin/stat/StatPluginFilter.java index 9100a7c..26a6ce2 100644 --- a/src/main/java/we/plugin/stat/StatPluginFilter.java +++ b/src/main/java/we/plugin/stat/StatPluginFilter.java @@ -119,7 +119,7 @@ public class StatPluginFilter extends PluginFilter { if (StringUtils.isBlank(fizzAccessStatTopic)) { rt.convertAndSend(fizzAccessStatChannel, b.toString()).subscribe(); } else { - log.info(b.toString(), LogService.HANDLE_STGY, LogService.toKF(fizzAccessStatTopic)); + log.info(b.toString(), LogService.HANDLE_STGY, LogService.toKF(fizzAccessStatTopic)); // for internal use } } diff --git a/src/test/java/we/redis/RedisConfiguration.java b/src/test/java/we/redis/RedisConfiguration.java new file mode 100644 index 0000000..df1cdcc --- /dev/null +++ b/src/test/java/we/redis/RedisConfiguration.java @@ -0,0 +1,33 @@ +// package we.redis; +// +// import org.springframework.context.annotation.Bean; +// import org.springframework.context.annotation.Configuration; +// import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +// import org.springframework.data.redis.core.StringRedisTemplate; +// import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; +// +// /** +// * @author hongqiaowei +// */ +// +// @Configuration +// @EnableRedisRepositories +// public class RedisConfiguration { +// +// @Bean +// public LettuceConnectionFactory redisConnectionFactory( +// RedisProperties redisProperties) { +// LettuceConnectionFactory cf = new LettuceConnectionFactory( +// redisProperties.getRedisHost(), +// redisProperties.getRedisPort()); +// cf.setDatabase(redisProperties.getDatabase()); +// return cf; +// } +// +// @Bean +// public StringRedisTemplate stringRedisTemplate(LettuceConnectionFactory connectionFactory) { +// StringRedisTemplate template = new StringRedisTemplate(); +// template.setConnectionFactory(connectionFactory); +// return template; +// } +// } \ No newline at end of file diff --git a/src/test/java/we/redis/RedisProperties.java b/src/test/java/we/redis/RedisProperties.java new file mode 100644 index 0000000..d1d55de --- /dev/null +++ b/src/test/java/we/redis/RedisProperties.java @@ -0,0 +1,58 @@ +// package we.redis; +// +// import org.springframework.beans.factory.annotation.Value; +// import org.springframework.context.annotation.Configuration; +// import we.util.JacksonUtils; +// +// /** +// * @author hongqiaowei +// */ +// +// @Configuration +// public class RedisProperties { +// +// private int redisPort; +// private String redisHost; +// private int database; +// +// public RedisProperties( +// /*@Value("${spring.redis.port}") int redisPort, +// @Value("${spring.redis.host}") String redisHost, +// @Value("${spring.redis.database}") int database*/) { +// // this.redisPort = redisPort; +// // this.redisHost = redisHost; +// // this.database = database; +// this.redisPort = 6379; +// this.redisHost = "localhost"; +// this.database = 3; +// } +// +// public int getRedisPort() { +// return redisPort; +// } +// +// public void setRedisPort(int redisPort) { +// this.redisPort = redisPort; +// } +// +// public String getRedisHost() { +// return redisHost; +// } +// +// public void setRedisHost(String redisHost) { +// this.redisHost = redisHost; +// } +// +// public int getDatabase() { +// return database; +// } +// +// public void setDatabase(int database) { +// this.database = database; +// } +// +// @Override +// public String toString() { +// return JacksonUtils.writeValueAsString(this); +// } +// } diff --git a/src/test/java/we/redis/RedisTestConfiguration.java b/src/test/java/we/redis/RedisTestConfiguration.java new file mode 100644 index 0000000..865925d --- /dev/null +++ b/src/test/java/we/redis/RedisTestConfiguration.java @@ -0,0 +1,34 @@ +// package we.redis; +// +// import org.springframework.context.annotation.Configuration; +// import redis.embedded.RedisServer; +// +// import javax.annotation.PostConstruct; +// import javax.annotation.PreDestroy; +// +// /** +// * @author hongqiaowei +// */ +// +// @Configuration +// public class RedisTestConfiguration { +// +// private RedisServer redisServer; +// +// public RedisTestConfiguration(RedisProperties redisProperties) { +// redisServer = RedisServer.builder() +// .port(redisProperties.getRedisPort()) +// .setting("maxmemory 32M") +// .build(); +// } +// +// @PostConstruct +// public void postConstruct() { +// redisServer.start(); +// } +// +// @PreDestroy +// public void preDestroy() { +// redisServer.stop(); +// } +// } \ No newline at end of file diff --git a/src/test/java/we/stats/ratelimit/ResourceRateLimitConfigServiceTests.java b/src/test/java/we/stats/ratelimit/ResourceRateLimitConfigServiceTests.java index de31afe..247dec7 100644 --- a/src/test/java/we/stats/ratelimit/ResourceRateLimitConfigServiceTests.java +++ b/src/test/java/we/stats/ratelimit/ResourceRateLimitConfigServiceTests.java @@ -1,17 +1,58 @@ -package we.stats.ratelimit; - -import org.junit.jupiter.api.Test; - -/** - * @author hongqiaowei - */ - -public class ResourceRateLimitConfigServiceTests { - - @Test - void initTest() { - - // 其实就是要构建个 context,里面有 redis、ReactiveStringRedisTemplate、ResourceRateLimitConfigService - // ResourceRateLimitConfigService 依赖 ReactiveStringRedisTemplate,然后能 PostConstruct - } -} +// package we.stats.ratelimit; +// +// import org.junit.jupiter.api.AfterAll; +// import org.junit.jupiter.api.BeforeAll; +// import org.junit.jupiter.api.Test; +// import org.springframework.boot.test.context.SpringBootTest; +// import org.springframework.context.annotation.PropertySource; +// import org.springframework.data.redis.core.StringRedisTemplate; +// import org.springframework.test.context.ActiveProfiles; +// import org.springframework.test.context.ContextConfiguration; +// import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; +// import redis.embedded.RedisServer; +// import we.redis.RedisProperties; +// import we.redis.RedisTestConfiguration; +// +// import javax.annotation.Resource; +// +// /** +// * @author hongqiaowei +// */ +// +// // @SpringBootTest(classes = RedisTestConfiguration.class) +// // @ContextConfiguration(classes = RedisTestConfiguration.class) +// @PropertySource("classpath:/application.yml") +// @SpringJUnitConfig(classes = {RedisProperties.class, RedisTestConfiguration.class, RedisTestConfiguration.class}) +// // @ActiveProfiles("unittest") +// public class ResourceRateLimitConfigServiceTests { +// +// // private static RedisServer redisServer; +// // +// // @BeforeAll +// // static void startRedis() { +// // redisServer = RedisServer.builder() +// // .port(6379) +// // .setting("maxmemory 32M") +// // .build(); +// // redisServer.start(); +// // } +// // +// // @AfterAll +// // static void stopRedis() { +// // redisServer.stop(); +// // } +// +// @Resource +// private RedisProperties redisProperties; +// +// @Resource +// private StringRedisTemplate stringRedisTemplate; +// +// @Test +// void initTest() { +// System.err.println("redis: " + redisProperties); +// System.err.println("stringRedisTemplate: " + stringRedisTemplate); +// // 其实就是要构建个 context,里面有 redis、ReactiveStringRedisTemplate、ResourceRateLimitConfigService +// // ResourceRateLimitConfigService 依赖 ReactiveStringRedisTemplate,然后能 PostConstruct +// } +// } diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml new file mode 100644 index 0000000..3edc75c --- /dev/null +++ b/src/test/resources/application.yml @@ -0,0 +1,5 @@ +#spring: +# redis: +# host: localhost +# port: 6379 +# database: 3