文章目录
- 前言
- [4 授权规则](#4 授权规则)
-
- [4.1 基本原理](#4.1 基本原理)
- [4.2 获取origin](#4.2 获取origin)
- [4.3 配置授权规则](#4.3 配置授权规则)
- [5 自定义异常结果](#5 自定义异常结果)
- [6 规则持久化](#6 规则持久化)
前言
微服务保护学习笔记(一)雪崩问题及解决方案、Sentinel介绍与安装
微服务保护学习笔记(二)簇点链路、流控操作、流控模式(关联、链路)
微服务保护学习笔记(三)流控效果(warm up、排队等待)、热点参数限流
微服务保护学习笔记(四)FeignClient整合Sentinel、线程隔离(舱壁模式)、熔断降级
4 授权规则
4.1 基本原理
授权规则可以对服务调用方的来源做控制,有白名单和黑名单两种方式:
- 白名单:来源(origin)在白名单内的调用者允许访问
- 黑名单:来源(origin)在黑名单内的调用者不允许访问
点击Sentinel控制台左侧菜单"授权规则",可以新增授权规则:
- 资源名:受保护的资源,例如
/order/query
- 流控应用:调用方名单(origin)
- 授权类型:设置调用方名单是白名单还是黑名单
4.2 获取origin
Sentinel是通过RequestOriginParser
这个接口的parseOrigin()
方法来获取请求的来源的。
这个方法的作用是从request
对象中,获取请求者的origin值并返回。默认情况下,Sentinel不管请求者从哪里来,返回值永远是default,也就是说一切请求的来源都被认为是一样的值default。
因此,自定义这个接口的实现,就可以让不同的请求,返回不同的origin。
在sd-user-service
微服务中,定义一个RequestOriginParser
实现类:
java
@Component
public class HeaderOriginParser implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest request) {
// 获取请求头
String origin = request.getHeader("Origin");
if(StringUtils.isEmpty(origin)) {
origin = "blank";
}
return origin;
}
}
4.3 配置授权规则
为sd-user-service
微服务配置授权规则,设置origin为sd-user-service
的请求为白名单:
测试:
可见,/user/query
资源只允许origin请求头为sd-user-service
的请求调用。
5 自定义异常结果
默认情况下,当发生限流、降级或授权拦截时,都会抛出异常到调用方,并且异常结果都是flow limmiting(即限流,从4.3节的截图可以看出)。这样不够友好,无法得知具体原因。
Sentinel提供了一个BlockExceptionHandler
接口,用于自定义异常结果:
其handle()
方法有三个参数,其中第三个参数BlockException
就是Sentinel拦截时抛出的异常。
BlockException
类又包含多个不同的子类:
在sd-user-service
微服务中,定义一个BlockExceptionHandler
实现类:
java
@Component
public class SentinelExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
String msg = "未知异常";
int status = 429;
if (e instanceof FlowException) {
msg = "请求被限流了";
} else if (e instanceof ParamFlowException) {
msg = "请求被热点参数限流";
} else if (e instanceof DegradeException) {
msg = "请求被降级了";
} else if (e instanceof AuthorityException) {
msg = "没有授权访问";
status = 401;
}
response.setContentType("application/json;charset=utf-8");
response.setStatus(status);
response.getWriter().println("{\"msg\": " + msg + ", \"status\": " + status + "}");
}
}
重启微服务,配置授权规则,发起origin请求头为sd-user-service
的请求:
6 规则持久化
在默认情况下,Sentinel的所有规则都是内存存储,重启后所有规则都会丢失。因此在上面的测试中,每次重启微服务,Sentinel配置的规则均会消失。
规则是否能持久化,取决于规则管理模式,Sentinel支持三种规则管理模式:
- 原始模式:Sentinel的默认模式,将规则保存在内存,重启服务会丢失。
- pull模式:Sentinel控制台将配置的规则推送到Sentinel客户端,而客户端会将配置规则保存在本地文件或数据库中,以后会定时去本地文件或数据库中查询,更新本地规则。
- push模式:Sentinel控制台将配置规则推送到远程配置中心,例如Nacos。Sentinel客户端监听Nacos,获取配置变更的推送消息,完成本地配置更新。
...
本节完,更多内容请查阅分类专栏:微服务学习笔记
感兴趣的读者还可以查阅我的另外几个专栏: