大家好,我是哪吒。
Sentinel是阿里巴巴开源的一款轻量级流量控制、熔断降级工具,它提供了实时的流量控制,熔断降级等功能,能够帮助我们实现服务的高可用性和稳定性。
本文将会介绍Sentinel的作用和优势、快速开始、进阶使用、Spring Cloud Alibaba Sentinel整合以及实践案例,并对Sentinel的局限和不足进行分析。
Sentinel 是阿里巴巴开源的一款针对分布式系统的流量控制、熔断降级的框架。在微服务架构的系统中,请求流量复杂多样,可能会因为某一个服务异常而导致整体服务不可用,这时候需要熔断降级,而 Sentinel 就提供了这样的解决方案。
Sentinel 可以针对服务方法调用、HTTP 请求、Dubbo 服务等,进行实时的流量控制、熔断降级,确保服务高可用,同时还可以提供实时的监控和报警功能。
Sentinel 有以下一些优势:
本文将为读者介绍 Sentinel 的基础和进阶使用方法,包括
本文的目的是帮助读者快速上手使用 Sentinel,并且深入理解其基本原理和使用方法。同时,也希望能够对读者们的日常工作有所帮助。
在开始使用 Sentinel 之前,我们需要准备好以下环境:
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
在Sentinel的官网下载最新的控制台jar包,然后在控制台目录下执行以下命令启动控制台:
java -jar sentinel-dashboard-1.8.2.jar
启动成功后,可以通过浏览器访问http://localhost:8080/#/dashboard/home查看控制台页面。
在应用启动类上添加注解@EnableSentinel注解,然后在配置文件中配置应用名称和Sentinel控制台的地址:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
datasource:
ds1:
nacos:
server-addr: localhost:8848
dataId: sentinel
groupId: DEFAULT_GROUP
data-type: json
Sentinel提供了多种限流降级策略,本文以流控规则为例进行演示。
在需要限流的方法上添加@SentinelResource注解,然后配置流控规则:
@GetMapping("/hello")
@SentinelResource(value = "hello", blockHandler = "blockHandler")
public String hello() {
return "Hello, World!";
}
public String blockHandler(BlockException e) {
return "请求过于频繁,请稍后重试!";
}
在控制台的流控规则页面添加对应的规则,设置好阈值和统计窗口等参数,然后测试该接口。
Sentinel Dashboard是Sentinel的可视化监控平台,可以用于实时监控应用的流量、延迟、异常等指标,并对应用进行限流降级等操作。
Sentinel客户端首先向Sentinel Dashboard注册。Sentinel Dashboard返回一个token给客户端,客户端将使用该token连接Sentinel。
应用程序将使用token连接Sentinel,Sentinel客户端将返回连接成功信息。Sentinel客户端将实时推送metrics数据到Sentinel Dashboard,Sentinel Dashboard将监控和管理应用程序。
Sentinel是一款开源的流量控制和降级框架,提供多种限流降级策略,包括流控规则、降级规则、热点参数限流等。
下面将逐一介绍这些规则。
流控规则用于限制系统的流量,可以通过设置QPS流量控制和线程数流量控制等方式来控制系统的访问速度。
在Sentinel Dashboard中,可以通过以下步骤来配置和管理流控规则:
降级规则用于应对系统的异常情况,可以通过设置异常比例降级、异常数降级和慢调用降级等方式来降低系统的负载。
在Sentinel Dashboard中,可以通过以下步骤来配置和管理降级规则:
热点参数限流用于对热点参数进行限流,可以有效避免某些参数被过多地请求。在Sentinel Dashboard中,可以通过以下步骤来配置和管理热点参数限流规则:
在使用这些规则时,需要注意参数设置和阈值设置等细节,以避免规则的误判或限流不准确等问题。
通过Sentinel Dashboard的可视化界面,可以方便地进行规则的配置和管理,提高系统的稳定性和可靠性。
Sentinel的资源名和URL匹配规则是限流降级策略的重要组成部分,可以根据业务需求定义合适的匹配规则。
上图展示了应用程序代码中定义资源名和 URL 匹配规则时的交互过程。
应用程序通过 Sentinel 客户端向 Sentinel 发送配置请求,Sentinel 返回配置结果。应用程序根据配置结果使用 Sentinel 进行限流降级。
在这个过程中,应用程序需要注意合理性和精确性,以避免出现误判或限流不准确等问题。
上图是自定义规则扩展的关系图示。
自定义规则扩展包括数据源扩展、限流降级规则扩展、规则统计扩展等,可以使用多种语言进行开发。
在进行规则扩展时,需要注意代码质量和性能,以保证扩展的准确性和有效性。
以下是一个自定义规则类型的示例:
public class CustomFlowRule implements FlowRule {
private String resourceName;
private int count;
private int interval;
public CustomFlowRule(String resourceName, int count, int interval) {
this.resourceName = resourceName;
this.count = count;
this.interval = interval;
}
@Override
public String getResource() {
return resourceName;
}
@Override
public int getCount() {
return count;
}
@Override
public void setCount(int count) {
this.count = count;
}
@Override
public int getInterval() {
return interval;
}
@Override
public void setInterval(int interval) {
this.interval = interval;
}
}
在这个示例中,我们自定义了一个 CustomFlowRule 类型,它包含了 resourceName、count 和 interval 三个属性。同时,我们实现了 FlowRule 接口,并实现了其中的各个方法,以满足 Sentinel 对规则类型的要求。
使用这个自定义规则类型时,我们需要在代码中添加相关的配置,例如:
Listrules = new ArrayList<>();
CustomFlowRule rule = new CustomFlowRule("custom_resource", 10, 1);
rules.add(rule);
FlowRuleManager.loadRules(rules);
在这个示例中,我们通过 CustomFlowRule 类型创建了一个规则,它的资源名称为 custom_resource,限流阈值为 10,时间间隔为 1 秒。然后我们将这个规则添加到 Sentinel 的规则管理器中,从而让 Sentinel 能够自动识别和使用这个规则。
Sentinel Starter是Spring Cloud Alibaba Sentinel的快速入门依赖,提供了自动化配置和默认规则等能力,可以简化Sentinel在Spring Cloud中的使用。
在使用Sentinel Starter时,只需要添加依赖并在配置文件中配置相应的参数,即可快速实现Sentinel的限流降级功能。
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel控制台地址
port: 8719
datasource:
ds1:
nacos:
server-addr: localhost:8848 # Nacos配置中心地址
dataId: ${spring.application.name}-sentinel # Sentinel配置数据ID
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow,degrade # Sentinel规则类型
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker
@EnableSentinel // 开启 Sentinel 功能
public class ProductServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ProductServiceApplication.class, args);
}
}
@RestController
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/products/{id}")
@SentinelResource(value = "products/{id}", blockHandlerClass = ProductControllerBlockHandler.class, blockHandler = "handleBlock")
public Product getProduct(@PathVariable Long id) {
return productService.getProduct(id);
}
}
其中,@SentinelResource 注解中的 value 参数为资源名称,blockHandlerClass 和 blockHandler 分别指定了限流或降级时的处理类和方法。
在上图中,我们可以看到当服务请求量过大时,API Gateway 可以对服务进行限流,避免服务过载。同时,当某个服务出现故障或负载过高时,可以对该服务进行降级,避免影响其他服务的正常运行。
@RestController
public class OrderController {
@PostMapping("/createOrder")
@SentinelResource(value = "createOrder", blockHandlerClass = OrderBlockHandler.class, blockHandler = "handleBlock")
public Result createOrder(@RequestBody OrderRequest orderRequest) {
// ...
}
}
@RestController
public class OrderController {
@PostMapping("/createOrder")
@SentinelResource(value = "createOrder", blockHandlerClass = OrderBlockHandler.class, blockHandler = "handleBlock")
@Idempotent(key = "#orderRequest.userId + ':' + #orderRequest.productId")
public Result createOrder(@RequestBody OrderRequest orderRequest) {
// ...
}
}
@Component
public class OrderService {
@Autowired
private RedisTemplateredisTemplate;
public boolean checkIdempotency(String key) {
Boolean result = redisTemplate.opsForValue().setIfAbsent(key, "1");
if (result != null && result) {
redisTemplate.expire(key, 60, TimeUnit.SECONDS);
return true;
}
return false;
}
}
假设我们有一个高并发的秒杀系统,我们需要实现分布式锁来控制同一时间只能有一个用户参与秒杀活动。为了防止死锁和死节点,我们使用 Sentinel 的分布式锁实现来保证系统的可用性和稳定性。
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
port: 8719
@RestController
public class SeckillController {
@Autowired
private DistributedLock distributedLock;
@GetMapping("/seckill")
public String seckill(@RequestParam("userId") Long userId,
@RequestParam("itemId") Long itemId) {
// 获取锁
String lockKey = "seckill:" + itemId;
boolean locked = distributedLock.tryLock(lockKey);
if (!locked) {
return "Failed to get lock";
}
try {
// 执行秒杀逻辑
return "Success";
} finally {
// 释放锁
distributedLock.unlock(lockKey);
}
}
}
在 Sentinel 控制台中创建流控规则,限制流量:
示例代码:
@Component
public class DistributedLock {
private static final String LOCK_PREFIX = "distributed-lock:";
@Autowired
private CuratorFramework curatorFramework;
public boolean tryLock(String key) {
String lockPath = LOCK_PREFIX + key;
InterProcessMutex lock = new InterProcessMutex(curatorFramework, lockPath);
try {
return lock.acquire(1, TimeUnit.SECONDS);
} catch (Exception ex) {
throw new RuntimeException("Failed to acquire lock", ex);
}
}
public void unlock(String key) {
String lockPath = LOCK_PREFIX + key;
InterProcessMutex lock = new InterProcessMutex(curatorFramework, lockPath);
try {
lock.release();
} catch (Exception ex) {
throw new RuntimeException("Failed to release lock", ex);
}
}
}
假设我们有一个电商网站,想要测试一个新的促销活动页面对用户购买行为的影响。我们希望将用户随机分为两个组,其中一个组将看到新的促销页面,另一个组将看到旧的促销页面。我们希望通过分析两组用户的购买转化率来确定新页面是否对提高购买转化率有帮助。
@RestController
public class PromotionController {
@GetMapping("/promotion")
@SentinelResource(value = "promotion", blockHandlerClass = PromotionBlockHandler.class, blockHandler = "handle")
public String promotion(@RequestParam("userId") Long userId) {
// 根据用户 id 判断用户应该分到哪个组
int groupId = userId % 2;
return "Group " + groupId;
}
}
@Component
public class PromotionBlockHandler {
public String handle(Long userId, BlockException ex) {
// 处理限流或降级情况下的逻辑
int groupId = userId % 2;
return "Blocked Group " + groupId;
}
}
@RestController
public class PromotionController {
@GetMapping("/promotion")
@SentinelResource(value = "promotion", blockHandlerClass = PromotionBlockHandler.class, blockHandler = "handle")
public String promotion(@RequestParam("userId") Long userId, @RequestParam("itemId") Long itemId) {
// 根据用户 id 判断用户应该分到哪个组
int groupId = userId % 2;
// 上报用户购买行为和分组信息
String resourceName = "promotion_" + itemId;
Entry entry = null;
try {
entry = SphU.entry(resourceName);
Tracer.traceEntry("group_id=" + groupId);
// 执行业务逻辑
return "Success";
} catch (BlockException ex) {
// 处理限流或降级情况下的逻辑
return "Blocked Group " + groupId;
} finally {
if (entry != null) {
entry.exit();
}
}
}
}
在 Sentinel 控制台中创建两个流控规则,将两个组的流量分别限制在一定的范围内,可以通过配置在限流规则中添加特定的参数,如 group_id=0 和 group_id=1,来将不同组的请求进行区分。
示例代码:
规则名称:promotion_flow_control;
资源名:promotion_*;
限流阈值:100;
流控模式:QPS;
应用名称:default;
参数:group_id=0;
点击 "提交" 按钮,创建一个限制组 0 的流控规则;
点击 "新建" 按钮,填写如下信息:
规则名称:promotion_flow_control;
资源名:promotion_*;
限流阈值:100;
流控模式:QPS;
应用名称:default;
参数:group_id=1;
点击 “提交” 按钮,创建一个限制组 1 的流控规则;
注意事项:
在使用 Sentinel 进行 A/B 测试时,需要注意以下几个方面:
Sentinel虽然具有很多优点和优势,但也存在一些局限和不足。
例如,Sentinel对业务代码的侵入性较大,需要在代码中添加相关的注解或者拦截器等;同时,Sentinel的配置较为复杂,需要进行多种规则的配置和参数的调整等。
此外,Sentinel还存在一些性能问题和安全问题,需要注意规避和解决。
尽管Sentinel存在一些不足和局限,但随着微服务和云原生技术的普及和发展,Sentinel在限流降级等方面的需求和重要性将会越来越大。
同时,Sentinel也在不断地进行优化和改进,例如在性能和安全方面进行了多项优化和加强,同时还提供了更加方便和高效的规则扩展开发能力,可以满足不同业务场景的需求。
因此,Sentinel在未来的发展中将会发挥越来越重要的作用,成为云原生技术生态圈中的一颗明珠。
本文转载自微信公众号「哪吒编程」,可以通过以下二维码关注。转载本文请联系哪吒编程公众号。
网站名称:一万字图解分布式系统限流平台Sentinel
转载来于:http://www.shufengxianlan.com/qtweb/news11/355011.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联