一、什么是Sentinel?
Sentinel (分布式系统的流量防卫兵) 是阿里开源的一套用于服务容错的综合性解决方案。它以流量
为切入点, 从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性
二、如何使用Sentinel?
2.1 添加Sentinel依赖
<!--sentinel组件-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2.2 安装Sentinel控制台
链接:Sentinel控制台
这里呢给大家做了一个批处理的文件,直接双击sentinel启动.bat
即可启动
2.3 指定端口和服务地址
修改application.yml
文件,如下
spring:
cloud:
sentinel:
transport:
port: 9999 #跟控制台交流的端口,随意指定一个未使用的端口即可
dashboard: localhost:8080 # 指定控制台服务的地址
feign:
sentinel:
enabled: true #开启feign对sentinel的支持
通过浏览器访问localhost:8080
进入控制台 ( 默认用户名密码是 sentinel/sentinel )
登陆进去后,idea重启服务访问几次接口,再刷新sentinel控制台,就会出现对应的服务列表
2.4 实现一个接口限流
比如给sentinel2做限流
QPS:每秒请求的数量
单机阈值:请求超过3次就进行限流
然后我们多次快速访问http://localhost:8091/sentinel2
就会出现如下:
2.5 关联限流
什么是关联限流?
举个例子:某个资源网站有vip会员和普通用户,当某时刻该网站的服务器突然接受到了大量的请求,导致服务器承受不了,这时候就要对普通用户进行限流,保证vip用户正常访问。
代码实现:
@RequestMapping("/vip")
public String vip() {
return "vip";
}
@RequestMapping("/common")
public String common() {
return "common";
}
重启服务,在sentinel控制台给common添加流控规则
启动Jmeter给vip接口不断发请求
此时再访问http://localhost:8091/common
同样会出现(访问vip接口能够正常进入)
2.6 链路限流
什么是链路限流?
当从某个接口过来的资源达到限流条件时,开启限流。
代码实现:
定义一个接口
package org.example.service;
public interface ITraceService {
void vipRes();
}
实现该接口
package org.example.service.impl;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.example.service.ITraceService;
import org.springframework.stereotype.Service;
@Service
public class TraceServiceImpl implements ITraceService {
//用SentinelResource定义一个资源 括号里是资源名
@SentinelResource("vipres")
@Override
public void vipRes() {
System.out.println("重要资源");
}
}
controller控制器
@RequestMapping("/trace1")
public String trace1() {
traceService.vipRes();
return "trace1";
}
@RequestMapping("/trace2")
public String trace2() {
traceService.vipRes();
return "trace2";
}
@RequestMapping("/trace3")
public String trace3() {
traceService.vipRes();
return "trace3";
}
配置application.yml
文件
spring:
cloud:
sentinel:
web-context-unify: false #用于链路限流
重启服务后三个接口都访问一下,控制台再刷新
给trace1做链路限流
此时trace1若QPS超过3则会提示如下
而其他接口可以正常访问
2.7 熔断
这里我们给sentinel1增加熔断规则
由于sentinel1我们设置了延迟1s,则按照以上设置的熔断规则来说是100%会熔断的
所以当我们第一次访问http://localhost:8091/sentinel1
时,会正常进入,但是第二次访问时,服务就会被熔断。
2.8 热点限流
何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top n数
据,并对其访问进行限制。比如:
- 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
- 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。
代码实现:
@RequestMapping("/hotSpot1")
//热点限流的资源必须加SentinelResource注解 没有该注解不生效
@SentinelResource(value = "hotSpot1")
public String hotSpot1(Long productId){
return "hotSpot1";
}
重启服务后访问http://localhost:8091/hotSpot1
并在控制台中新增热点规则
注意:这里是对整体接口进行限流,后续还需要对单个热点资源进行限流!!!
当我携带参数访问时(即访问productId资源)访问http://localhost:8091/hotSpot1?productId=3
,且请求次数超过3次,则会报错如下:
对单个资源进行限流
点击绿色按钮添加后,再保存后提示你修改成功
我们访问http://localhost:8091/hotSpot1?productId=1
,请求超过一次时便报错500
这就是热点限流
2.9 授权
很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源访问控制(黑白名单控制)的功能。来源访问控制根据资源的请求来源( origin )限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。
例如:在pc端和ios可以通过,其余客户端不予通过。
代码实现:
controller层
@RequestMapping("/auth")
public String auth(){
return "auth";
}
定义一个util工具类用于解析来源名称,没有就返回error
package org.example.util;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component
public class SourceParse implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest httpServletRequest) {
String sourceName = httpServletRequest.getHeader("sourceName");
if(sourceName == null || "".equals(sourceName)){
sourceName = "error";
}
return sourceName;
}
}
重启服务后访问auth并添加授权规则
若直接访问http://localhost:8091/auth
则会被拦截(因为sourceName=null)
这里我用postman发送请求,通过header携带参数,请求成功