-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
215 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
sentinel-sample/src/main/java/com/example/demo/config/BlockExceptionHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.example.demo.config; | ||
|
||
import com.alibaba.csp.sentinel.slots.block.BlockException; | ||
|
||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
/** | ||
* 哨兵流控规则异常处理器 | ||
* | ||
* @author yclimb | ||
* @date 2020/10/12 | ||
*/ | ||
public interface BlockExceptionHandler { | ||
|
||
/** | ||
* 在此处处理限流异常,可以跳转到指定页面或返回指定的内容 | ||
* | ||
* @param request req | ||
* @param response resp | ||
* @param e e | ||
* @throws Exception e | ||
*/ | ||
void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception; | ||
} |
29 changes: 29 additions & 0 deletions
29
sentinel-sample/src/main/java/com/example/demo/config/SentinelWebConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.example.demo.config; | ||
|
||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
import java.io.PrintWriter; | ||
|
||
/** | ||
* 哨兵流控规则异常处理配置项(流控规则对应 Controller 中的方法) | ||
* | ||
* @author yclimb | ||
* @date 2020/10/12 | ||
*/ | ||
@Configuration | ||
public class SentinelWebConfig { | ||
|
||
@Bean | ||
public BlockExceptionHandler sentinelBlockExceptionHandler() { | ||
return (request, response, e) -> { | ||
// 429 Too Many Requests | ||
response.setStatus(429); | ||
|
||
PrintWriter out = response.getWriter(); | ||
out.print("Oops, blocked by Sentinel: " + e.getClass().getSimpleName()); | ||
out.flush(); | ||
out.close(); | ||
}; | ||
} | ||
} |
30 changes: 29 additions & 1 deletion
30
sentinel-sample/src/main/java/com/example/demo/controller/TestController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,38 @@ | ||
package com.example.demo.controller; | ||
|
||
import com.example.demo.service.TestService; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
/** | ||
* 测试 | ||
* 测试控制层 | ||
* | ||
* @author yclimb | ||
* @date 2020/10/12 | ||
*/ | ||
@RestController | ||
public class TestController { | ||
|
||
@Autowired | ||
private TestService testService; | ||
|
||
@GetMapping("/test") | ||
public void test() { | ||
testService.test(); | ||
} | ||
|
||
@GetMapping("/hello/{name}") | ||
public String hello(@PathVariable String name) { | ||
/*String str = testService.hello(111L); | ||
System.out.println(str);*/ | ||
return testService.sayHello(name); | ||
} | ||
|
||
@GetMapping("/hello") | ||
public void hello() { | ||
testService.hello(); | ||
} | ||
|
||
} |
110 changes: 110 additions & 0 deletions
110
sentinel-sample/src/main/java/com/example/demo/service/TestService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package com.example.demo.service; | ||
|
||
import com.alibaba.csp.sentinel.Entry; | ||
import com.alibaba.csp.sentinel.SphU; | ||
import com.alibaba.csp.sentinel.annotation.SentinelResource; | ||
import com.alibaba.csp.sentinel.slots.block.BlockException; | ||
import com.alibaba.csp.sentinel.slots.block.RuleConstant; | ||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; | ||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; | ||
import com.example.demo.util.ExceptionUtil; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
/** | ||
* 测试服务层(流控规则对应 Service 中的方法) | ||
* | ||
* @author yclimb | ||
* @date 2020/10/12 | ||
*/ | ||
@Service | ||
public class TestService { | ||
|
||
/** | ||
* 自定义流控规则,手动代码实现 | ||
*/ | ||
public void hello() { | ||
initFlowRules(); | ||
|
||
// 循环30次 | ||
int i = 30; | ||
while (i > 0) { | ||
// 1.5.0 版本开始可以直接利用 try-with-resources 特性,自动 exit entry | ||
try (Entry entry = SphU.entry("HelloWorld")) { | ||
// 被保护的逻辑 | ||
System.out.println(i + ":hello world"); | ||
} catch (BlockException ex) { | ||
// 处理被流控的逻辑 | ||
System.out.println(i + "blocked!"); | ||
} | ||
i--; | ||
} | ||
} | ||
|
||
/** | ||
* 初始化流控规则,用于 hello 自定义流控规则方法使用 | ||
*/ | ||
private static void initFlowRules(){ | ||
List<FlowRule> rules = new ArrayList<>(); | ||
FlowRule rule = new FlowRule(); | ||
rule.setResource("HelloWorld"); | ||
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); | ||
// Set limit QPS to 20. | ||
rule.setCount(20); | ||
rules.add(rule); | ||
FlowRuleManager.loadRules(rules); | ||
} | ||
|
||
/** | ||
* 哨兵自定义异常类 | ||
* 对应的 `handleException` 函数需要位于 `ExceptionUtil` 类中,并且必须为 static 函数. | ||
*/ | ||
@SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {ExceptionUtil.class}) | ||
public void test() { | ||
System.out.println("Test"); | ||
} | ||
|
||
/** | ||
* 默认哨兵,触动规则无异常处理 | ||
* @param name name | ||
* @return String | ||
*/ | ||
@SentinelResource(value = "sayHello") | ||
public String sayHello(String name) { | ||
return "Hello, " + name; | ||
} | ||
|
||
/** | ||
* 原始函数 | ||
* 需要借助于本类方法 exceptionHandler、helloFallback 来使用 | ||
* @param s s | ||
* @return String | ||
*/ | ||
@SentinelResource(value = "hello", blockHandler = "exceptionHandler", fallback = "helloFallback") | ||
public String hello(long s) { | ||
return String.format("Hello at %d", s); | ||
} | ||
|
||
/** | ||
* Fallback 函数,函数签名与原函数一致或加一个 Throwable 类型的参数. | ||
* @param s s | ||
* @return String | ||
*/ | ||
public String helloFallback(long s) { | ||
return String.format("Halooooo %d", s); | ||
} | ||
|
||
/** | ||
* Block 异常处理函数,参数最后多一个 BlockException,其余与原函数一致. | ||
* @param s s | ||
* @param ex ex | ||
* @return String | ||
*/ | ||
public String exceptionHandler(long s, BlockException ex) { | ||
// Do some log here. | ||
ex.printStackTrace(); | ||
return "Oops, error occurred at " + s; | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
sentinel-sample/src/main/java/com/example/demo/util/ExceptionUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.example.demo.util; | ||
|
||
import com.alibaba.csp.sentinel.slots.block.BlockException; | ||
|
||
/** | ||
* 异常处理工具类 | ||
* | ||
* @author yclimb | ||
* @date 2020/10/12 | ||
*/ | ||
public final class ExceptionUtil { | ||
|
||
/** | ||
* 使用 @SentinelResource(blockHandlerClass) 时使用,返回值必须和方法返回值一致 | ||
* @param ex ex | ||
*/ | ||
public static void handleException(BlockException ex) { | ||
System.out.println("Oops: " + ex.getClass().getCanonicalName()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters