diff --git a/spring-cloud-alibaba-dependencies/pom.xml b/spring-cloud-alibaba-dependencies/pom.xml
index 356418ff..f438ccf0 100644
--- a/spring-cloud-alibaba-dependencies/pom.xml
+++ b/spring-cloud-alibaba-dependencies/pom.xml
@@ -71,6 +71,11 @@
sentinel-core
${sentinel.version}
+
+ com.alibaba.csp
+ sentinel-parameter-flow-control
+ ${sentinel.version}
+
com.alibaba.csp
sentinel-datasource-extension
diff --git a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/pom.xml b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/pom.xml
index 03896924..383703cb 100644
--- a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/pom.xml
+++ b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/pom.xml
@@ -40,6 +40,11 @@
spring-cloud-starter-feign
+
+ org.springframework.cloud
+ spring-cloud-starter-alibaba-sentinel
+
+
diff --git a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ConsumerApplication.java b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ConsumerApplication.java
index 96a62331..dddd3368 100644
--- a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ConsumerApplication.java
+++ b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ConsumerApplication.java
@@ -2,6 +2,7 @@ package org.springframework.cloud.alibaba.cloud.examples;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.alibaba.cloud.examples.ConsumerApplication.EchoService;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@@ -10,6 +11,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;
/**
@@ -20,22 +22,50 @@ import org.springframework.web.client.RestTemplate;
@EnableFeignClients
public class ConsumerApplication {
- @LoadBalanced
- @Bean
- public RestTemplate restTemplate() {
- return new RestTemplate();
- }
+ @LoadBalanced
+ @Bean
+ public RestTemplate restTemplate() {
+ return new RestTemplate();
+ }
+ public static void main(String[] args) {
+ SpringApplication.run(ConsumerApplication.class, args);
+ }
+ @FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
+ public interface EchoService {
+ @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
+ String echo(@PathVariable("str") String str);
+ @RequestMapping(value = "/divide", method = RequestMethod.GET)
+ String divide(@RequestParam("a") Integer a, @RequestParam("b") Integer b);
- public static void main(String[] args) {
- SpringApplication.run(ConsumerApplication.class, args);
- }
+ @RequestMapping(value = "/notFound", method = RequestMethod.GET)
+ String notFound();
+ }
- @FeignClient(name = "service-provider")
- public interface EchoService {
- @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
- String echo(@PathVariable("str") String str);
- }
+}
+
+class FeignConfiguration {
+ @Bean
+ public EchoServiceFallback echoServiceFallback() {
+ return new EchoServiceFallback();
+ }
+}
+
+class EchoServiceFallback implements EchoService {
+ @Override
+ public String echo(@PathVariable("str") String str) {
+ return "echo fallback";
+ }
+
+ @Override
+ public String divide(@RequestParam Integer a, @RequestParam Integer b) {
+ return "divide fallback";
+ }
+
+ @Override
+ public String notFound() {
+ return "notFound fallback";
+ }
}
diff --git a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/TestController.java b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/TestController.java
index b896691b..55c751c7 100644
--- a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/TestController.java
+++ b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/TestController.java
@@ -6,6 +6,7 @@ import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@@ -15,31 +16,42 @@ import org.springframework.web.client.RestTemplate;
@RestController
public class TestController {
- @Autowired
- private RestTemplate restTemplate;
- @Autowired
- private EchoService echoService;
+ @Autowired
+ private RestTemplate restTemplate;
+ @Autowired
+ private EchoService echoService;
+ @Autowired
+ private DiscoveryClient discoveryClient;
- @Autowired
- private DiscoveryClient discoveryClient;
+ @RequestMapping(value = "/echo-rest/{str}", method = RequestMethod.GET)
+ public String rest(@PathVariable String str) {
+ return restTemplate.getForObject("http://service-provider/echo/" + str,
+ String.class);
+ }
- @RequestMapping(value = "/echo-rest/{str}", method = RequestMethod.GET)
- public String rest(@PathVariable String str) {
- return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
- }
- @RequestMapping(value = "/echo-feign/{str}", method = RequestMethod.GET)
- public String feign(@PathVariable String str) {
- return echoService.echo(str);
- }
+ @RequestMapping(value = "/notFound-feign", method = RequestMethod.GET)
+ public String notFound() {
+ return echoService.notFound();
+ }
+ @RequestMapping(value = "/divide-feign", method = RequestMethod.GET)
+ public String divide(@RequestParam Integer a, @RequestParam Integer b) {
+ return echoService.divide(a, b);
+ }
- @RequestMapping(value="/services/{service}",method = RequestMethod.GET)
- public Object client(@PathVariable String service){
- return discoveryClient.getInstances(service);
- }
- @RequestMapping(value="/services",method = RequestMethod.GET)
- public Object services(){
- return discoveryClient.getServices();
- }
+ @RequestMapping(value = "/echo-feign/{str}", method = RequestMethod.GET)
+ public String feign(@PathVariable String str) {
+ return echoService.echo(str);
+ }
+
+ @RequestMapping(value = "/services/{service}", method = RequestMethod.GET)
+ public Object client(@PathVariable String service) {
+ return discoveryClient.getInstances(service);
+ }
+
+ @RequestMapping(value = "/services", method = RequestMethod.GET)
+ public Object services() {
+ return discoveryClient.getServices();
+ }
}
diff --git a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/application.properties b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/application.properties
index 1df160fc..530d1a27 100644
--- a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/application.properties
+++ b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/application.properties
@@ -1,4 +1,12 @@
spring.application.name=service-consumer
server.port=18083
-management.endpoints.web.exposure.include=*
-spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
\ No newline at end of file
+management.security.enabled=false
+spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
+
+feign.sentinel.enabled=true
+
+spring.cloud.sentinel.transport.dashboard=localhost:8080
+spring.cloud.sentinel.eager=true
+
+spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
+spring.cloud.sentinel.datasource.ds1.file.data-type=json
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/flowrule.json b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/flowrule.json
new file mode 100644
index 00000000..3dd01162
--- /dev/null
+++ b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/flowrule.json
@@ -0,0 +1,10 @@
+[
+ {
+ "resource": "GET:http://service-provider/echo/{str}",
+ "controlBehavior": 0,
+ "count": 1,
+ "grade": 1,
+ "limitApp": "default",
+ "strategy": 0
+ }
+]
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-provider-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ProviderApplication.java b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-provider-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ProviderApplication.java
index 169bccd6..843f5cbe 100644
--- a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-provider-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ProviderApplication.java
+++ b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-provider-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ProviderApplication.java
@@ -6,6 +6,7 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
@@ -25,5 +26,10 @@ public class ProviderApplication {
public String echo(@PathVariable String string) {
return "hello Nacos Discovery " + string;
}
+
+ @RequestMapping(value = "/divide", method = RequestMethod.GET)
+ public String divide(@RequestParam Integer a, @RequestParam Integer b) {
+ return String.valueOf(a / b);
+ }
}
}
diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ServiceApplication.java b/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ServiceApplication.java
index 93183382..f1fe28e6 100644
--- a/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ServiceApplication.java
+++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/ServiceApplication.java
@@ -2,7 +2,7 @@ package org.springframework.cloud.alibaba.cloud.examples;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.alibaba.sentinel.annotation.SentinelProtect;
+import org.springframework.cloud.alibaba.sentinel.annotation.SentinelRestTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@@ -15,7 +15,7 @@ import com.alibaba.csp.sentinel.datasource.Converter;
public class ServiceApplication {
@Bean
- @SentinelProtect(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
+ @SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
public RestTemplate restTemplate() {
return new RestTemplate();
}
diff --git a/spring-cloud-alibaba-sentinel-datasource/pom.xml b/spring-cloud-alibaba-sentinel-datasource/pom.xml
index db4ed997..b3c636ef 100644
--- a/spring-cloud-alibaba-sentinel-datasource/pom.xml
+++ b/spring-cloud-alibaba-sentinel-datasource/pom.xml
@@ -18,6 +18,13 @@
com.alibaba.csp
sentinel-datasource-extension
+ true
+
+
+
+ com.alibaba.csp
+ sentinel-parameter-flow-control
+ true
diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/JsonConverter.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/JsonConverter.java
index b05626a5..ebe58acc 100644
--- a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/JsonConverter.java
+++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/JsonConverter.java
@@ -17,6 +17,7 @@ import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
+import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -31,6 +32,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
* @see DegradeRule
* @see SystemRule
* @see AuthorityRule
+ * @see ParamFlowRule
* @see ObjectMapper
*/
public class JsonConverter implements Converter> {
@@ -47,7 +49,7 @@ public class JsonConverter implements Converter> {
public List convert(String source) {
List ruleList = new ArrayList<>();
if (StringUtils.isEmpty(source)) {
- logger.info(
+ logger.warn(
"Sentinel JsonConverter can not convert rules because source is empty");
return ruleList;
}
@@ -67,7 +69,7 @@ public class JsonConverter implements Converter> {
List rules = Arrays.asList(convertFlowRule(itemJson),
convertDegradeRule(itemJson), convertSystemRule(itemJson),
- convertAuthorityRule(itemJson));
+ convertAuthorityRule(itemJson), convertParamFlowRule(itemJson));
List convertRuleList = new ArrayList<>();
@@ -105,8 +107,6 @@ public class JsonConverter implements Converter> {
throw new RuntimeException(
"Sentinel JsonConverter convert error: " + e.getMessage(), e);
}
- logger.info("Sentinel JsonConverter convert {} rules: {}", ruleList.size(),
- ruleList);
return ruleList;
}
@@ -158,4 +158,15 @@ public class JsonConverter implements Converter> {
return rule;
}
+ private ParamFlowRule convertParamFlowRule(String json) {
+ ParamFlowRule rule = null;
+ try {
+ rule = objectMapper.readValue(json, ParamFlowRule.class);
+ }
+ catch (Exception e) {
+ // ignore
+ }
+ return rule;
+ }
+
}
diff --git a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/XmlConverter.java b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/XmlConverter.java
index c67cc645..af62df74 100644
--- a/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/XmlConverter.java
+++ b/spring-cloud-alibaba-sentinel-datasource/src/main/java/org/springframework/cloud/alibaba/sentinel/datasource/converter/XmlConverter.java
@@ -17,6 +17,7 @@ import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
+import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -31,6 +32,7 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper;
* @see DegradeRule
* @see SystemRule
* @see AuthorityRule
+ * @see ParamFlowRule
* @see XmlMapper
*/
public class XmlConverter implements Converter> {
@@ -47,7 +49,7 @@ public class XmlConverter implements Converter> {
public List convert(String source) {
List ruleList = new ArrayList<>();
if (StringUtils.isEmpty(source)) {
- logger.info(
+ logger.warn(
"Sentinel XmlConverter can not convert rules because source is empty");
return ruleList;
}
@@ -67,7 +69,7 @@ public class XmlConverter implements Converter> {
List rules = Arrays.asList(convertFlowRule(itemXml),
convertDegradeRule(itemXml), convertSystemRule(itemXml),
- convertAuthorityRule(itemXml));
+ convertAuthorityRule(itemXml), convertParamFlowRule(itemXml));
List convertRuleList = new ArrayList<>();
@@ -104,8 +106,6 @@ public class XmlConverter implements Converter> {
throw new RuntimeException(
"Sentinel XmlConverter convert error: " + e.getMessage(), e);
}
- logger.info("Sentinel XmlConverter convert {} rules: {}", ruleList.size(),
- ruleList);
return ruleList;
}
@@ -157,4 +157,15 @@ public class XmlConverter implements Converter> {
return rule;
}
+ private ParamFlowRule convertParamFlowRule(String json) {
+ ParamFlowRule rule = null;
+ try {
+ rule = xmlMapper.readValue(json, ParamFlowRule.class);
+ }
+ catch (Exception e) {
+ // ignore
+ }
+ return rule;
+ }
+
}
diff --git a/spring-cloud-alibaba-sentinel/pom.xml b/spring-cloud-alibaba-sentinel/pom.xml
index 31824be2..dba86dfb 100644
--- a/spring-cloud-alibaba-sentinel/pom.xml
+++ b/spring-cloud-alibaba-sentinel/pom.xml
@@ -35,6 +35,18 @@
sentinel-dubbo-adapter
+
+ org.springframework.cloud
+ spring-cloud-starter-openfeign
+ provided
+ true
+
+
+
+ com.alibaba.csp
+ sentinel-parameter-flow-control
+
+
org.springframework.cloud
spring-cloud-alibaba-sentinel-datasource
diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/SentinelProperties.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/SentinelProperties.java
index feac8acc..d827222e 100644
--- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/SentinelProperties.java
+++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/SentinelProperties.java
@@ -26,6 +26,7 @@ import org.springframework.cloud.alibaba.sentinel.datasource.config.DataSourcePr
import org.springframework.core.Ordered;
import com.alibaba.csp.sentinel.config.SentinelConfig;
+import com.alibaba.csp.sentinel.log.LogBase;
import com.alibaba.csp.sentinel.transport.config.TransportConfig;
/**
@@ -48,11 +49,6 @@ public class SentinelProperties {
*/
private boolean enabled = true;
- /**
- * charset when sentinel write or search metric file {@link SentinelConfig#CHARSET}
- */
- private String charset = "UTF-8";
-
/**
* configurations about datasource, like 'nacos', 'apollo', 'file', 'zookeeper'
*/
@@ -91,6 +87,12 @@ public class SentinelProperties {
@NestedConfigurationProperty
private Flow flow = new Flow();
+ /**
+ * sentinel log configuration {@link LogBase}
+ */
+ @NestedConfigurationProperty
+ private Log log = new Log();
+
public boolean isEager() {
return eager;
}
@@ -107,14 +109,6 @@ public class SentinelProperties {
this.flow = flow;
}
- public String getCharset() {
- return charset;
- }
-
- public void setCharset(String charset) {
- this.charset = charset;
- }
-
public Transport getTransport() {
return transport;
}
@@ -163,6 +157,14 @@ public class SentinelProperties {
this.datasource = datasource;
}
+ public Log getLog() {
+ return log;
+ }
+
+ public void setLog(Log log) {
+ this.log = log;
+ }
+
public static class Flow {
/**
@@ -208,6 +210,12 @@ public class SentinelProperties {
*/
private String fileTotalCount;
+ /**
+ * charset when sentinel write or search metric file
+ * {@link SentinelConfig#CHARSET}
+ */
+ private String charset = "UTF-8";
+
public String getFileSingleSize() {
return fileSingleSize;
}
@@ -223,6 +231,14 @@ public class SentinelProperties {
public void setFileTotalCount(String fileTotalCount) {
this.fileTotalCount = fileTotalCount;
}
+
+ public String getCharset() {
+ return charset;
+ }
+
+ public void setCharset(String charset) {
+ this.charset = charset;
+ }
}
public static class Transport {
@@ -298,4 +314,35 @@ public class SentinelProperties {
this.urlPatterns = urlPatterns;
}
}
+
+ public static class Log {
+
+ /**
+ * sentinel log base dir
+ */
+ private String dir;
+
+ /**
+ * distinguish the log file by pid number
+ */
+ private boolean switchPid = false;
+
+ public String getDir() {
+ return dir;
+ }
+
+ public void setDir(String dir) {
+ this.dir = dir;
+ }
+
+ public boolean isSwitchPid() {
+ return switchPid;
+ }
+
+ public void setSwitchPid(boolean switchPid) {
+ this.switchPid = switchPid;
+ }
+
+ }
+
}
diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/annotation/SentinelProtect.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/annotation/SentinelRestTemplate.java
similarity index 79%
rename from spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/annotation/SentinelProtect.java
rename to spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/annotation/SentinelRestTemplate.java
index 6586c8d3..da1a3c26 100644
--- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/annotation/SentinelProtect.java
+++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/annotation/SentinelRestTemplate.java
@@ -16,7 +16,11 @@
package org.springframework.cloud.alibaba.sentinel.annotation;
-import java.lang.annotation.*;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* @author fangjian
@@ -24,7 +28,7 @@ import java.lang.annotation.*;
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
-public @interface SentinelProtect {
+public @interface SentinelRestTemplate {
String blockHandler() default "";
diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java
index ea74c449..924f415c 100644
--- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java
+++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelAutoConfiguration.java
@@ -39,6 +39,7 @@ import com.alibaba.csp.sentinel.adapter.servlet.config.WebServletConfig;
import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
import com.alibaba.csp.sentinel.config.SentinelConfig;
import com.alibaba.csp.sentinel.init.InitExecutor;
+import com.alibaba.csp.sentinel.log.LogBase;
import com.alibaba.csp.sentinel.transport.config.TransportConfig;
import com.alibaba.csp.sentinel.util.AppNameUtil;
@@ -89,8 +90,9 @@ public class SentinelAutoConfiguration {
properties.getTransport().getHeartbeatIntervalMs());
}
if (StringUtils.isEmpty(System.getProperty(SentinelConfig.CHARSET))
- && StringUtils.hasText(properties.getCharset())) {
- System.setProperty(SentinelConfig.CHARSET, properties.getCharset());
+ && StringUtils.hasText(properties.getMetric().getCharset())) {
+ System.setProperty(SentinelConfig.CHARSET,
+ properties.getMetric().getCharset());
}
if (StringUtils
.isEmpty(System.getProperty(SentinelConfig.SINGLE_METRIC_FILE_SIZE))
@@ -109,6 +111,15 @@ public class SentinelAutoConfiguration {
System.setProperty(SentinelConfig.COLD_FACTOR,
properties.getFlow().getColdFactor());
}
+ if (StringUtils.isEmpty(System.getProperty(LogBase.LOG_DIR))
+ && StringUtils.hasText(properties.getLog().getDir())) {
+ System.setProperty(LogBase.LOG_DIR, properties.getLog().getDir());
+ }
+ if (StringUtils.isEmpty(System.getProperty(LogBase.LOG_NAME_USE_PID))
+ && properties.getLog().isSwitchPid()) {
+ System.setProperty(LogBase.LOG_NAME_USE_PID,
+ String.valueOf(properties.getLog().isSwitchPid()));
+ }
if (StringUtils.hasText(properties.getServlet().getBlockPage())) {
WebServletConfig.setBlockPage(properties.getServlet().getBlockPage());
diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelBeanPostProcessor.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelBeanPostProcessor.java
index fdad9664..4fb9a6cf 100644
--- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelBeanPostProcessor.java
+++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelBeanPostProcessor.java
@@ -25,87 +25,88 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.cloud.alibaba.sentinel.annotation.SentinelProtect;
+import org.springframework.cloud.alibaba.sentinel.annotation.SentinelRestTemplate;
import org.springframework.context.ApplicationContext;
import org.springframework.core.type.StandardMethodMetadata;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
/**
- * PostProcessor handle @SentinelProtect Annotation, add interceptor for RestTemplate
+ * PostProcessor handle @SentinelRestTemplate Annotation, add interceptor for RestTemplate
*
* @author Jim
- * @see SentinelProtect
+ * @see SentinelRestTemplate
* @see SentinelProtectInterceptor
*/
public class SentinelBeanPostProcessor implements MergedBeanDefinitionPostProcessor {
- @Autowired
- private ApplicationContext applicationContext;
+ @Autowired
+ private ApplicationContext applicationContext;
- private ConcurrentHashMap cache = new ConcurrentHashMap<>();
+ private ConcurrentHashMap cache = new ConcurrentHashMap<>();
- @Override
- public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
- Class> beanType, String beanName) {
- if (checkSentinelProtect(beanDefinition, beanType)) {
- SentinelProtect sentinelProtect = ((StandardMethodMetadata) beanDefinition
- .getSource()).getIntrospectedMethod()
- .getAnnotation(SentinelProtect.class);
- cache.put(beanName, sentinelProtect);
- }
- }
+ @Override
+ public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
+ Class> beanType, String beanName) {
+ if (checkSentinelProtect(beanDefinition, beanType)) {
+ SentinelRestTemplate sentinelRestTemplate = ((StandardMethodMetadata) beanDefinition
+ .getSource()).getIntrospectedMethod()
+ .getAnnotation(SentinelRestTemplate.class);
+ cache.put(beanName, sentinelRestTemplate);
+ }
+ }
- private boolean checkSentinelProtect(RootBeanDefinition beanDefinition,
- Class> beanType) {
- return beanType == RestTemplate.class
- && beanDefinition.getSource() instanceof StandardMethodMetadata
- && ((StandardMethodMetadata) beanDefinition.getSource())
- .isAnnotated(SentinelProtect.class.getName());
- }
+ private boolean checkSentinelProtect(RootBeanDefinition beanDefinition,
+ Class> beanType) {
+ return beanType == RestTemplate.class
+ && beanDefinition.getSource() instanceof StandardMethodMetadata
+ && ((StandardMethodMetadata) beanDefinition.getSource())
+ .isAnnotated(SentinelRestTemplate.class.getName());
+ }
- @Override
- public Object postProcessAfterInitialization(Object bean, String beanName)
- throws BeansException {
- if (cache.containsKey(beanName)) {
- // add interceptor for each RestTemplate with @SentinelProtect annotation
- StringBuilder interceptorBeanName = new StringBuilder();
- SentinelProtect sentinelProtect = cache.get(beanName);
- interceptorBeanName
- .append(StringUtils.uncapitalize(
- SentinelProtectInterceptor.class.getSimpleName()))
- .append("_")
- .append(sentinelProtect.blockHandlerClass().getSimpleName())
- .append(sentinelProtect.blockHandler()).append("_")
- .append(sentinelProtect.fallbackClass().getSimpleName())
- .append(sentinelProtect.fallback());
- RestTemplate restTemplate = (RestTemplate) bean;
- registerBean(interceptorBeanName.toString(), sentinelProtect);
- SentinelProtectInterceptor sentinelProtectInterceptor = applicationContext
- .getBean(interceptorBeanName.toString(),
- SentinelProtectInterceptor.class);
- restTemplate.getInterceptors().add(sentinelProtectInterceptor);
- }
- return bean;
- }
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName)
+ throws BeansException {
+ if (cache.containsKey(beanName)) {
+ // add interceptor for each RestTemplate with @SentinelRestTemplate annotation
+ StringBuilder interceptorBeanName = new StringBuilder();
+ SentinelRestTemplate sentinelRestTemplate = cache.get(beanName);
+ interceptorBeanName
+ .append(StringUtils.uncapitalize(
+ SentinelProtectInterceptor.class.getSimpleName()))
+ .append("_")
+ .append(sentinelRestTemplate.blockHandlerClass().getSimpleName())
+ .append(sentinelRestTemplate.blockHandler()).append("_")
+ .append(sentinelRestTemplate.fallbackClass().getSimpleName())
+ .append(sentinelRestTemplate.fallback());
+ RestTemplate restTemplate = (RestTemplate) bean;
+ registerBean(interceptorBeanName.toString(), sentinelRestTemplate);
+ SentinelProtectInterceptor sentinelProtectInterceptor = applicationContext
+ .getBean(interceptorBeanName.toString(),
+ SentinelProtectInterceptor.class);
+ restTemplate.getInterceptors().add(sentinelProtectInterceptor);
+ }
+ return bean;
+ }
- private void registerBean(String interceptorBeanName,
- SentinelProtect sentinelProtect) {
- // register SentinelProtectInterceptor bean
- DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext
- .getAutowireCapableBeanFactory();
- BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
- .genericBeanDefinition(SentinelProtectInterceptor.class);
- beanDefinitionBuilder.addConstructorArgValue(sentinelProtect);
- BeanDefinition interceptorBeanDefinition = beanDefinitionBuilder
- .getRawBeanDefinition();
- beanFactory.registerBeanDefinition(interceptorBeanName,
- interceptorBeanDefinition);
- }
+ private void registerBean(String interceptorBeanName,
+ SentinelRestTemplate sentinelRestTemplate) {
+ // register SentinelProtectInterceptor bean
+ DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext
+ .getAutowireCapableBeanFactory();
+ BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
+ .genericBeanDefinition(SentinelProtectInterceptor.class);
+ beanDefinitionBuilder.addConstructorArgValue(sentinelRestTemplate);
+ BeanDefinition interceptorBeanDefinition = beanDefinitionBuilder
+ .getRawBeanDefinition();
+ beanFactory.registerBeanDefinition(interceptorBeanName,
+ interceptorBeanDefinition);
+ }
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- return bean;
- }
+ @Override
+ public Object postProcessBeforeInitialization(Object bean, String beanName)
+ throws BeansException {
+ return bean;
+ }
}
\ No newline at end of file
diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelProtectInterceptor.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelProtectInterceptor.java
index dc22262f..f8fa0820 100644
--- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelProtectInterceptor.java
+++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/custom/SentinelProtectInterceptor.java
@@ -22,7 +22,7 @@ import java.net.URI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.cloud.alibaba.sentinel.annotation.SentinelProtect;
+import org.springframework.cloud.alibaba.sentinel.annotation.SentinelRestTemplate;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
@@ -37,103 +37,104 @@ import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.util.StringUtil;
/**
- * Interceptor using by SentinelProtect and SentinelProtectInterceptor
+ * Interceptor using by SentinelRestTemplate and SentinelProtectInterceptor
*
* @author fangjian
*/
public class SentinelProtectInterceptor implements ClientHttpRequestInterceptor {
- private static final Logger logger = LoggerFactory
- .getLogger(SentinelProtectInterceptor.class);
+ private static final Logger logger = LoggerFactory
+ .getLogger(SentinelProtectInterceptor.class);
- private SentinelProtect sentinelProtect;
+ private SentinelRestTemplate sentinelRestTemplate;
- public SentinelProtectInterceptor(SentinelProtect sentinelProtect) {
- this.sentinelProtect = sentinelProtect;
- }
+ public SentinelProtectInterceptor(SentinelRestTemplate sentinelRestTemplate) {
+ this.sentinelRestTemplate = sentinelRestTemplate;
+ }
- @Override
- public ClientHttpResponse intercept(HttpRequest request, byte[] body,
- ClientHttpRequestExecution execution) throws IOException {
- URI uri = request.getURI();
- String hostResource = uri.getScheme() + "://" + uri.getHost() + ":"
- + (uri.getPort() == -1 ? 80 : uri.getPort());
- String hostWithPathResource = hostResource + uri.getPath();
- Entry hostEntry = null, hostWithPathEntry = null;
- ClientHttpResponse response = null;
- try {
- ContextUtil.enter(hostWithPathResource);
- hostWithPathEntry = SphU.entry(hostWithPathResource);
- hostEntry = SphU.entry(hostResource);
- response = execution.execute(request, body);
- }
- catch (BlockException e) {
- logger.error("RestTemplate block", e);
- try {
- handleBlockException(e);
- }
- catch (Exception ex) {
- logger.error("sentinel handle BlockException error.", e);
- }
- }
- finally {
- if (hostEntry != null) {
- hostEntry.exit();
- }
- if (hostWithPathEntry != null) {
- hostWithPathEntry.exit();
- }
- ContextUtil.exit();
- }
- return response;
- }
+ @Override
+ public ClientHttpResponse intercept(HttpRequest request, byte[] body,
+ ClientHttpRequestExecution execution) throws IOException {
+ URI uri = request.getURI();
+ String hostResource = uri.getScheme() + "://" + uri.getHost() + ":"
+ + (uri.getPort() == -1 ? 80 : uri.getPort());
+ String hostWithPathResource = hostResource + uri.getPath();
+ Entry hostEntry = null, hostWithPathEntry = null;
+ ClientHttpResponse response = null;
+ try {
+ ContextUtil.enter(hostWithPathResource);
+ hostWithPathEntry = SphU.entry(hostWithPathResource);
+ hostEntry = SphU.entry(hostResource);
+ response = execution.execute(request, body);
+ }
+ catch (BlockException e) {
+ logger.error("RestTemplate block", e);
+ try {
+ handleBlockException(e);
+ }
+ catch (Exception ex) {
+ logger.error("sentinel handle BlockException error.", e);
+ }
+ }
+ finally {
+ if (hostEntry != null) {
+ hostEntry.exit();
+ }
+ if (hostWithPathEntry != null) {
+ hostWithPathEntry.exit();
+ }
+ ContextUtil.exit();
+ }
+ return response;
+ }
- private void handleBlockException(BlockException ex) throws Exception {
- Object[] args = new Object[] { ex };
- // handle degrade
- if (isDegradeFailure(ex)) {
- Method method = extractFallbackMethod(sentinelProtect.fallback(),
- sentinelProtect.fallbackClass());
- if (method != null) {
- method.invoke(null, args);
- }
- }
- // handle block
- Method blockHandler = extractBlockHandlerMethod(sentinelProtect.blockHandler(),
- sentinelProtect.blockHandlerClass());
- if (blockHandler != null) {
- blockHandler.invoke(null, args);
- }
- }
+ private void handleBlockException(BlockException ex) throws Exception {
+ Object[] args = new Object[] { ex };
+ // handle degrade
+ if (isDegradeFailure(ex)) {
+ Method method = extractFallbackMethod(sentinelRestTemplate.fallback(),
+ sentinelRestTemplate.fallbackClass());
+ if (method != null) {
+ method.invoke(null, args);
+ }
+ }
+ // handle block
+ Method blockHandler = extractBlockHandlerMethod(
+ sentinelRestTemplate.blockHandler(),
+ sentinelRestTemplate.blockHandlerClass());
+ if (blockHandler != null) {
+ blockHandler.invoke(null, args);
+ }
+ }
- private Method extractFallbackMethod(String fallback, Class> fallbackClass) {
- if (StringUtil.isBlank(fallback) || fallbackClass == void.class) {
- return null;
- }
- Method cachedMethod = BlockClassRegistry.lookupFallback(fallbackClass, fallback);
- if (cachedMethod == null) {
- cachedMethod = ClassUtils.getStaticMethod(fallbackClass, fallback,
- BlockException.class);
- BlockClassRegistry.updateFallbackFor(fallbackClass, fallback, cachedMethod);
- }
- return cachedMethod;
- }
+ private Method extractFallbackMethod(String fallback, Class> fallbackClass) {
+ if (StringUtil.isBlank(fallback) || fallbackClass == void.class) {
+ return null;
+ }
+ Method cachedMethod = BlockClassRegistry.lookupFallback(fallbackClass, fallback);
+ if (cachedMethod == null) {
+ cachedMethod = ClassUtils.getStaticMethod(fallbackClass, fallback,
+ BlockException.class);
+ BlockClassRegistry.updateFallbackFor(fallbackClass, fallback, cachedMethod);
+ }
+ return cachedMethod;
+ }
- private Method extractBlockHandlerMethod(String block, Class> blockClass) {
- if (StringUtil.isBlank(block) || blockClass == void.class) {
- return null;
- }
- Method cachedMethod = BlockClassRegistry.lookupBlockHandler(blockClass, block);
- if (cachedMethod == null) {
- cachedMethod = ClassUtils.getStaticMethod(blockClass, block,
- BlockException.class);
- BlockClassRegistry.updateBlockHandlerFor(blockClass, block, cachedMethod);
- }
- return cachedMethod;
- }
+ private Method extractBlockHandlerMethod(String block, Class> blockClass) {
+ if (StringUtil.isBlank(block) || blockClass == void.class) {
+ return null;
+ }
+ Method cachedMethod = BlockClassRegistry.lookupBlockHandler(blockClass, block);
+ if (cachedMethod == null) {
+ cachedMethod = ClassUtils.getStaticMethod(blockClass, block,
+ BlockException.class);
+ BlockClassRegistry.updateBlockHandlerFor(blockClass, block, cachedMethod);
+ }
+ return cachedMethod;
+ }
- private boolean isDegradeFailure(BlockException ex) {
- return ex instanceof DegradeException;
- }
+ private boolean isDegradeFailure(BlockException ex) {
+ return ex instanceof DegradeException;
+ }
}
diff --git a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpoint.java b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpoint.java
index 05262314..d7e3e9da 100644
--- a/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpoint.java
+++ b/spring-cloud-alibaba-sentinel/src/main/java/org/springframework/cloud/alibaba/sentinel/endpoint/SentinelEndpoint.java
@@ -31,6 +31,8 @@ import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
+import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
+import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
@@ -60,10 +62,12 @@ public class SentinelEndpoint extends AbstractEndpoint