blockHandler / blockHandlerClass: blockHandler对应处理 BlockException 的函数名称,可选项。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
fallback:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:
返回值类型必须与原函数返回值类型一致;
方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
defaultFallback(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:
返回值类型必须与原函数返回值类型一致;
方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
❝注:1.6.0 之前的版本 fallback 函数只针对降级异常(DegradeException)进行处理,「不能针对业务异常进行处理」。
❞特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。若未配置 blockHandler、fallback 和 defaultFallback,则被限流降级时会将 BlockException 「直接抛出」(若方法本身未定义 throws BlockException 则会被 JVM 包装一层 UndeclaredThrowableException)。
从 1.4.0 版本开始,注解方式定义资源支持自动统计业务异常,无需手动调用 Tracer.trace(ex) 来记录业务异常。Sentinel 1.4.0 以前的版本需要自行调用 Tracer.trace(ex) 来记录业务异常。
定义规则Sentinel 的所有规则都可以在「内存态中动态地查询及修改,修改之后立即生效」。同时 Sentinel 也提供相关 API,供您来定制自己的规则策略。
Sentinel 支持以下几种规则:「流量控制规则」、「熔断降级规则」、「热点参数规则」、「系统保护规则」和「来源访问控制规则」。
官网文档:
流量控制规则 添加流量控制规则选择 簇点链路 找到定义好的资源 selectProductById 并点击对应的规则按钮进行设置。
比如我们设置一个流量控制规则,定义资源访问的 QPS 为 1(每秒能处理查询数目)。
测试快速刷新页面多次访问::9090/order/idAndOrderNo?id=1&orderNo=order-001 结果如下:
熔断降级规则 模拟服务出错修改 order-service-rest 项目中的核心代码,模拟服务出错。
package com.example.service.impl; import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; import com.example.pojo.Product; import com.example.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; /** * 商品管理 */ @Service public class ProductServiceImpl implements ProductService { @Autowired private RestTemplate restTemplate; /** * 根据主键查询商品 * * @param id * @return */ @SentinelResource(value = "selectProductById", blockHandler = "selectProductByIdBlockHandler", fallback = "selectProductByIdFallback") @Override public Product selectProductById(Integer id, String productName) { // 模拟查询主键为 1 的商品信息会导致异常 if (1 == id) throw new RuntimeException("查询主键为 1 的商品信息导致异常"); return restTemplate.getForObject("http://product-service/product/" + id, Product.class); } // 服务流量控制处理,参数最后多一个 BlockException,其余与原函数一致。 public Product selectProductByIdBlockHandler(Integer id, BlockException ex) { // Do some log here. ex.printStackTrace(); return new Product(id, "服务流量控制处理-托底数据", 1, 2666D); } // 服务熔断降级处理,函数签名与原函数一致或加一个 Throwable 类型的参数 public Product selectProductByIdFallback(Integer id, Throwable throwable) { System.out.println("product-service 服务的 selectProductById 方法出现异常,异常信息如下:" + throwable); return new Product(id, "服务熔断降级处理-托底数据", 1, 2666D); } } 添加熔断降级规则熔断降级规则支持相应时间、异常比例、异常数三种方式。
测试访问::9090/order/idAndOrderNo?id=1&orderNo=order-001 结果如下:
热点参数规则热点参数规则是一种更细粒度的流控规则,它允许将规则具体到参数上。比如 selectOrderByIdAndOrderNo 方法有两个参数,我们对第一个参数进行限流,对第二个参数不限流。
添加热点参数规则选择 簇点链路 找到定义好的资源 selectOrderByIdAndOrderNo 并点击对应的规则按钮进行设置。
设置热点参数规则,定义对资源的第一个参数的 QPS 为 1(每秒能处理查询数目)。
测试分别用两个参数访问,会发现只对第一个参数限流了。
快速刷新页面多次访问::9090/order/idAndOrderNo?id=1 被限流。
快速刷新页面多次访问::9090/order/idAndOrderNo?orderNo=order-001 正常访问。
授权规则很多时候,我们需要根据调用来源来判断该次请求是否被允许,这时候可以使用 Sentinel 的来源访问控制的功能。来源访问控制根据资源的请求来源(origin)限制资源是否通过。
Sentinel 提供了 RequestOriginParser 接口来处理来源。一旦 Sentinel 保护的接口资源被访问,Sentinel 就会调用 RequestOriginParser 的实现类去解析访问来源。
自定义来源处理规则 package com.example.sentinel; import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; /** * 自定义来源处理规则 */ @Component public class MyRequestOriginParser implements RequestOriginParser { @Override public String parseOrigin(HttpServletRequest request) { return request.getParameter("userName"); } } 新增授权规则下图配置的意思是资源 selectOrderByIdAndOrderNo 只有 userName=zhangsan 的用户无法访问(黑名单)
测试快速刷新页面多次访问::9090/order/idAndOrderNo?id=1&userName=zhangsan 被限流。
快速刷新页面多次访问::9090/order/idAndOrderNo?id=1&userName=lisi 正常访问。
系统保护规则系统保护规则是从应用级别的入口流量进行控制,从单台机器的总体 LOAD、RT、线程数、入口 QPS 和 CPU 使用率五个维度监控应用数据,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量(进入应用的流量)生效。