diff --git a/spring-cloud-alibaba-examples/sentinel-example/readme-zh.md b/spring-cloud-alibaba-examples/sentinel-example/readme-zh.md
index c849d51fc..eb261a51d 100644
--- a/spring-cloud-alibaba-examples/sentinel-example/readme-zh.md
+++ b/spring-cloud-alibaba-examples/sentinel-example/readme-zh.md
@@ -10,45 +10,55 @@
## 示例
### 如何接入
+
在启动示例进行演示之前,我们先了解一下如何接入 Sentinel。
-**注意 本章节只是为了便于您理解接入方式,本示例代码中已经完成接入工作,您无需再进行修改。**
-1. 首先,修改 pom.xml 文件,引入 Sentinel starter。
+> **注意:本章节只是为了便于您理解接入方式,本示例代码中已经完成接入工作,您无需再进行修改。**
+
+1. 首先,修改 `pom.xml` 文件,引入 Sentinel starter。
+
+```xml
+
+ org.springframework.cloud
+ spring-cloud-starter-alibaba-sentinel
+
+```
-
- org.springframework.cloud
- spring-cloud-starter-alibaba-sentinel
-
-
2. 接入限流埋点
+ - HTTP 埋点
- 1. HTTP埋点
Sentinel starter 默认为所有的 HTTP 服务提供了限流埋点,如果只想对 HTTP 服务进行限流,那么只需要引入依赖,无需修改代码。
+ - 自定义埋点
+
+ 如果需要对某个特定的方法进行限流或降级,可以通过 `@SentinelResource` 注解来完成限流的埋点,示例代码如下:
+
+ ```java
+ @SentinelResource("resource")
+ public String hello() {
+ return "Hello";
+ }
+ ```
- 2. 自定义埋点
- 如果需要对某个特定的方法进行限流或降级,可以通过 @SentinelResource 来完成限流的埋点,示例代码如下
+ 当然也可以通过原始的 `SphU.entry(xxx)` 方法进行埋点,可以参见 [Sentinel 文档](https://github.com/alibaba/Sentinel/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8#%E5%AE%9A%E4%B9%89%E8%B5%84%E6%BA%90)。
- @SentinelResource("resource")
- public String hello() {
- return "Hello";
- }
-
3. 配置限流规则
- Sentinel提供了两种配置限流规则的方式,代码配置 和 控制台配置,本示例使用的方式为通过控制台配置。
+ Sentinel 提供了两种配置限流规则的方式:代码配置 和 控制台配置。本示例使用的方式为通过控制台配置。
1. 通过代码来实现限流规则的配置。一个简单的限流规则配置示例代码如下,更多限流规则配置详情请参考 [Sentinel 文档](https://github.com/alibaba/Sentinel/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8#%E5%AE%9A%E4%B9%89%E8%A7%84%E5%88%99)。
- List rules = new ArrayList();
- FlowRule rule = new FlowRule();
- rule.setResource(str);
- // set limit qps to 10
- rule.setCount(10);
- rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
- rule.setLimitApp("default");
- rules.add(rule);
- FlowRuleManager.loadRules(rules);
-
+ ```java
+ List rules = new ArrayList();
+ FlowRule rule = new FlowRule();
+ rule.setResource(str);
+ // set limit qps to 10
+ rule.setCount(10);
+ rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
+ rule.setLimitApp("default");
+ rules.add(rule);
+ FlowRuleManager.loadRules(rules);
+ ```
+
2. 通过控制台进行限流规则配置请参考文章后面的图文说明。
### 启动 Sentinel 控制台
@@ -65,10 +75,12 @@
1. 增加配置,在应用的 /src/main/resources/application.properties 中添加基本配置信息
- spring.application.name=sentinel-example
- server.port=18083
- spring.cloud.sentinel.dashboard=localhost:8080
-
+ ```
+ spring.application.name=sentinel-example
+ server.port=18083
+ spring.cloud.sentinel.dashboard=localhost:8080
+ ```
+
2. 启动应用,支持 IDE 直接启动和编译打包后启动。
1. IDE直接启动:找到主类 `ServiceApplication`,执行 main 方法启动应用。
@@ -84,7 +96,8 @@
### 配置限流规则并验证
1. 访问 http://localhost:8080 页面,可以在左侧看到 Sentinel-Example 应用已经注册到了控制台,单击 **流控规则** ,可以看到目前的流控规则为空。
-**注意 如果您在控制台没有找到应用,请调用一下进行了 Sentinel 埋点的 URL 或方法,因为 Sentinel 使用了 lazy load 策略**
+
+> **注意:如果您在控制台没有找到应用,请调用一下进行了 Sentinel 埋点的 URL 或方法,因为 Sentinel 使用了 lazy load 策略。详细的排查过程请参见 [Sentinel FAQ](https://github.com/alibaba/Sentinel/wiki/FAQ)。**

@@ -94,7 +107,7 @@

-3. 配置自定义限流规则:点击新增流控规则,资源名填写 @SentinelResource 注解 value 字段的值,单机阈值选择需要限流的阈值,点击新增进行确认。(为了便于演示效果,这里将值设置成了 1)。
+3. 配置自定义限流规则:点击新增流控规则,资源名填写 `@SentinelResource` 注解 `value` 字段的值,单机阈值选择需要限流的阈值,点击新增进行确认。(为了便于演示效果,这里将值设置成了 1)。

@@ -110,61 +123,82 @@
## 自定义限流处理逻辑
1. URL 限流触发后默认处理逻辑是,直接返回 "Blocked by Sentinel (flow limiting)"。
- 如果需要自定义处理逻辑,实现的方式如下
-
- public class CustomUrlBlockHandler implements UrlBlockHandler {
- @Override
- public void blocked(HttpServletRequest httpServletRequest,
- HttpServletResponse httpServletResponse) throws IOException {
- // todo add your logic
- }
- }
-
- WebCallbackManager.setUrlBlockHandler(new CustomUrlBlockHandler());
+ 如果需要自定义处理逻辑,实现的方式如下:
+ ```java
+ public class CustomUrlBlockHandler implements UrlBlockHandler {
+ @Override
+ public void blocked(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException {
+ // todo add your logic
+ }
+ }
+ WebCallbackManager.setUrlBlockHandler(new CustomUrlBlockHandler());
+ ```
2. 自定义限流触发后,默认的处理逻辑是抛出异常。
- 如果需要自定义处理逻辑,填写@SentinelResource注解的blockHandler和blockHandlerClass属性,指定后会去blockHandlerClass类里找对应的blockHandler静态方法。示例实现如下
-
- @SentinelResource(value = "resource", blockHandler = "", blockHandlerClass = ExceptionUtil.class)
- public String hello() {
- return "Hello";
- }
-
- // ExceptionUtil.java
- public class ExceptionUtil {
- public static void handleException(BlockException ex) {
- System.out.println("Oops: " + ex.getClass().getCanonicalName());
- }
- }
-
+
+如果需要自定义处理逻辑,填写 `@SentinelResource` 注解的 `blockHandler` 属性(针对所有类型的 `BlockException`,需自行判断)或 `fallback` 属性(针对熔断降级异常),注意**对应方法的签名和位置有限制**,详情见 [Sentinel 注解支持文档](https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81#sentinelresource-%E6%B3%A8%E8%A7%A3)。示例实现如下:
+
+```java
+public class TestService {
+
+ // blockHandler 是位于 ExceptionUtil 类下的 handleException 静态方法,需符合对应的类型限制.
+ @SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {ExceptionUtil.class})
+ public void test() {
+ System.out.println("Test");
+ }
+
+ // blockHandler 是位于当前类下的 exceptionHandler 方法,需符合对应的类型限制.
+ @SentinelResource(value = "hello", blockHandler = "exceptionHandler")
+ public String hello(long s) {
+ return String.format("Hello at %d", s);
+ }
+
+ public String exceptionHandler(long s, BlockException ex) {
+ // Do some log here.
+ ex.printStackTrace();
+ return "Oops, error occurred at " + s;
+ }
+}
+```
+
+```java
+public final class ExceptionUtil {
+
+ public static void handleException(BlockException ex) {
+ System.out.println("Oops: " + ex.getClass().getCanonicalName());
+ }
+}
+```
+
+一个简单的示例可以见 [sentinel-demo-annotation-spring-aop](https://github.com/alibaba/Sentinel/tree/master/sentinel-demo/sentinel-demo-annotation-spring-aop)。
## Endpoint 信息查看
Spring Boot 应用支持通过 Endpoint 来暴露相关信息,Sentinel Starter 也支持这一点。
-在使用之前需要在 maven 中添加 `spring-boot-starter-actuator`依赖,并在配置中允许 Endpoints 的访问。
-* Spring Boot1.x 中添加配置 management.security.enabled=false
-* Spring Boot2.x 中添加配置 management.endpoints.web.exposure.include=*
+在使用之前需要在 Maven 中添加 `spring-boot-starter-actuator`依赖,并在配置中允许 Endpoints 的访问。
+* Spring Boot 1.x 中添加配置 `management.security.enabled=false`
+* Spring Boot 2.x 中添加配置 `management.endpoints.web.exposure.include=*`
-Spring Boot1.x 可以通过访问 http://127.0.0.1:18083/sentinel 来查看 Sentinel Endpoint 的信息。Spring Boot2.x 可以通过访问 http://127.0.0.1:18083/acutator/sentinel 来访问。
+Spring Boot 1.x 可以通过访问 http://127.0.0.1:18083/sentinel 来查看 Sentinel Endpoint 的信息。Spring Boot 2.x 可以通过访问 http://127.0.0.1:18083/acutator/sentinel 来访问。

## 查看实时监控
Sentinel 控制台支持实时监控查看,您可以通过 Sentinel 控制台查看各链路的请求的通过数和被限流数等信息。
-其中 p_qps 为通过(pass) 流控的 QPS,b_qps 为被限流 (block) 的 QPS。
+其中 `p_qps` 为通过(pass) 流控的 QPS,`b_qps` 为被限流 (block) 的 QPS。

-## DataSource支持
+## DataSource 支持
-Sentinel内部提供了[动态规则的扩展实现DataSource](https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95#datasource-%E6%89%A9%E5%B1%95)。
+Sentinel 内部提供了[动态规则的扩展实现 DataSource](https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95#datasource-%E6%89%A9%E5%B1%95)。
-Sentinel starter整合了目前存在的4类DataSource。只需要在配置文件中进行相关配置,即可在Spring容器中自动注册DataSource。
+Sentinel starter 整合了目前存在的几类 DataSource。只需要在配置文件中进行相关配置,即可在 Spring 容器中自动注册 DataSource。
-比如要定义一个FileRefreshableDataSource,配置如下:
+比如要定义一个 `FileRefreshableDataSource`,配置如下:
spring.cloud.sentinel.datasource.type=file
spring.cloud.sentinel.datasource.recommendRefreshMs=2000
@@ -172,40 +206,40 @@ Sentinel starter整合了目前存在的4类DataSource。只需要在配置文
spring.cloud.sentinel.datasource.charset=utf-8
spring.cloud.sentinel.datasource.configParser=myParser
spring.cloud.sentinel.datasource.file=/Users/you/rule.json
-
-然后使用`@SentinelDataSource`注解修饰DataSource即可注入:
-
+
+然后使用`@SentinelDataSource` 注解修饰 DataSource 即可注入:
+
@SentinelDataSource("spring.cloud.sentinel.datasource")
private DataSource dataSource;
-
-`@SentinelDataSource`注解的value属性可以不填。默认值就是spring.cloud.sentinel.datasource。
-value属性代表配置前缀。示例中会去找spring.cloud.sentinel.datasource.xxx相关的配置。
+`@SentinelDataSource` 注解的 value 属性可以不填。默认值就是 `spring.cloud.sentinel.datasource`。
-spring.cloud.sentinel.datasource.type就是对应的DataSource类型。
+`value` 属性代表配置前缀。示例中会去找 `spring.cloud.sentinel.datasource.xxx` 相关的配置。
-spring.cloud.sentinel.datasource.recommendRefreshMs里的recommendRefreshMs对应相关DataSource的属性。
+`spring.cloud.sentinel.datasource.type` 就是对应的 DataSource 类型。
-spring.cloud.sentinel.datasource.configParser代表ConfigParser在Spring容器里的name。如果没找到,会抛出异常。
+`spring.cloud.sentinel.datasource.recommendRefreshMs` 里的 `recommendRefreshMs` 对应相关 DataSource 的属性。
+
+`spring.cloud.sentinel.datasource.configParser`代表 `ConfigParser` 在 Spring 容器里的 name。如果没找到,会抛出异常。
type目前支持file, nacos, zk, apollo。
### 自定义DataSource
-自定义DataSource只需要两部。
+自定义DataSource只需要两步。
1. 定义DataSource
-
+
public class CustomDataSource implements DataSource {
private String fieldA;
private String fieldB;
...
}
-
+
2. 装配DataSource。有两种方式处理。
* 直接构造DataSource
-
+
@Bean
public CustomDataSource customDataSource() {
CustomDataSource customDataSource =
@@ -219,13 +253,13 @@ type目前支持file, nacos, zk, apollo。
* 在classpath:/META-INF/sentinel-datasource.properties中管理DataSource信息
custom = yourpackage.CustomDataSource
-
+
在application.properties中定义DataSource
-
+
spring.cloud.sentinel.datasource.type = custom
spring.cloud.sentinel.datasource.fieldA = valueA
spring.cloud.sentinel.datasource.fieldB = valueB
-
+
注意:由于目前Sentinel的AbstractDataSource需要有个ConfigParser作为构造函数中的参数,并且它的子类的构造都是通过多个参数的构造函数构造的。
所以目前所有的Sentinel starter中的DataSource都是基于FactoryBean并且通过设置属性构造的。如果有这方面的需求,需要再多加一个registerFactoryBean过程。