微服务 Sentinel 流量管理框架 基础配置

官网 https://sentinelguard.io/

Sentinel的流量管理是在控制器层面的(Controller)
原理是当收到请求时,先让请求经过配置文件中
spring.cloud.sentinel.transport.port设置的端口(每个项目必须唯一)
从Sentinel过一圈,再到自己的代码逻辑内运行,如流量过大,
按照限流规则,可能Sentinel会直接拦截请求,执行快速失败或其他,不再进入原来的代码里

请注意Sentinel本质上是一个运维工具,所以当项目重启后,原来设置的限流规则会被抛弃,需重新设置


需要下载Sentinel服务端程序,并运行jar包,启动命令(指定了端口为18080,默认8080)

java -jar sentinel-dashboard-1.8.2.jar --server.port=18080

出现以下界面表示启动成功.
可以访问http://localhost:18080进入控制台
账号密码皆为:sentinel

INFO: Sentinel log output type is: file
INFO: Sentinel log charset is: utf-8
INFO: Sentinel log base directory is: C:\Users\Administrator\logs\csp\
INFO: Sentinel log name use pid is: false

.   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/  ___)| |_)| | | | | || (_| |  ) ) ) )
'  |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot ::        (v2.0.5.RELEASE)

2022-08-24 11:36:02.150  INFO 5660 --- [           main] c.a.c.s.dashboard.DashboardApplication   : Starting DashboardApplication on DESKTOP-K8VRATH with PID 5660 (D:\sentinel\sentinel-dashboard-1.8.2.jar started by Administrator in D:\sentinel)
....................中间省略一堆....................
2022-08-24 11:36:03.808  INFO 5660 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Root mapping to handler of type [class org.springframework.web.servlet.mvc.ParameterizableViewController]
2022-08-24 11:36:03.818  INFO 5660 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2022-08-24 11:36:03.819  INFO 5660 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2022-08-24 11:36:03.942  INFO 5660 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2022-08-24 11:36:03.968  INFO 5660 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 18080 (http) with context path ''
2022-08-24 11:36:03.972  INFO 5660 --- [           main] c.a.c.s.dashboard.DashboardApplication   : Started DashboardApplication in 2.034 seconds (JVM running for 2.321)
<dependency>
  <groupId>com.alibaba.cloudgroupId>
  <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
dependency>
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:18080 #配置Sentinel仪表台的地址
        port: 8721 #执行限流的端口号,每个项目必须唯一

限流

添加依赖与配置项后,在控制器方法上,
添加**@SentinelResource(value = “XXX的方法”,blockHandler = “blockHandler”)**
value设置了此方法的名称
blockHandler指定了限流触发时的处理方法(可以不设置,异常会被抛出,具体参考异常拦截处理)

  • 访问修饰符必须是public
  • 此方法的返回值类型必须与控制器的返回值一致
  • 方法名称必须与注解内的blockHandler属性一致
  • 参数列表前面必须与控制器方法一致,末尾添加BlockException类型的参数

标注了这个注解的方法会被Sentinel进行管理
控制器方法第一次运行后,可以在Sentinel仪表台界面中设置限流规则

设置流控规则
微服务 Sentinel 流量管理框架 基础配置_第1张图片

如图所示,是设置QPS超过1的时候,触发限流
QPS: 每秒请求数
并发线程数: 同一时间调用此方法的线程数量,如设置1,则表示同一时间只有1个线程调用,第2个线程进来会被限流

微服务 Sentinel 流量管理框架 基础配置_第2张图片

异常拦截处理

此处演示的是直接在Controller类里编写限流处理方法,正常应当编写独立的类处理,并使用注解的blockHandlerClass属性指定

@PostMapping("/reduceCount")
@ApiOperation("减少库存")
@SentinelResource(value = "减少库存的方法",blockHandler = "blockHandler")
public JsonResult<Void> reduceCount(StockReduceCountDTO stockReduceCountDTO) {
    service.reduceCount(stockReduceCountDTO);
    return JsonResult.ok();
}
//限流处理方法
public JsonResult<Void> blockHandler(StockReduceCountDTO stockReduceCountDTO, BlockException e){
    log.debug("触发限流...");
    JsonResult<Void> result = JsonResult.failed(ResponseCode.BAD_REQUEST, "服务器忙,请稍后再试!");
    return result;
}

如未设置异常处理方法(blockHandler),将抛出java.lang.reflect.UndeclaredThrowableException异常

java.lang.reflect.UndeclaredThrowableException
  at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:770)
  at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
  ..........省略一堆..........
  at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
  at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
  at java.lang.Thread.run(Thread.java:748)
Caused by: com.alibaba.csp.sentinel.slots.block.flow.FlowException

可在统一异常处理类中进行拦截处理

/**
* 处理限流后抛出的异常
*/
@ExceptionHandler({UndeclaredThrowableException.class})
public JsonResult<Void> handleUndeclaredThrowableException(UndeclaredThrowableException e) {
    e.printStackTrace();
    log.debug("请求被限流,直接返回数据");
    JsonResult<Void> result = JsonResult.failed(ResponseCode.INTERNAL_SERVER_ERROR, "服务器忙,请稍后再试");
    return result;
}
    

达内:lzy

你可能感兴趣的:(java,sentinel,微服务,java)