Sentinel 实战:如何实现分布式系统的高效流量管控?

开发 前端
我们将展示如何使用 Sentinel 配置流控规则、实现熔断降级和跨服务流量管控,同时包含完整的代码和配置。

实现分布式系统的高效流量管控是微服务架构中非常重要的一环。下面以 Spring Boot 和 Spring Cloud 框架为例,通过阿里巴巴的 Sentinel 组件实现多服务环境下的流量监控与管控。我们将展示如何使用 Sentinel 配置流控规则、实现熔断降级和跨服务流量管控,同时包含完整的代码和配置。

系统设计目标

  1. 模拟一个微服务架构:订单服务(order-service)和库存服务(inventory-service)。
  2. Sentinel 的核心功能:
  • 在每个服务上设置流控规则,限制流量请求。
  • 实现跨服务调用时的流量监控。
  • 配置熔断降级规则,确保系统的稳定性。
  1. 提供完整的整合代码,包括服务配置、Sentinel 规则代码和流量控制逻辑。

系统架构图

用户请求 -> Gateway(网关) -> Order-Service -> Inventory-Service

流控目标:

  1. 限制 order-service 的并发访问数为 10。
  2. 对 inventory-service 的 QPS 设置为 5。
  3. 配置熔断规则,若 inventory-service 超时率超过 50%,熔断 10 秒。
  4. 在 Sentinel Dashboard 上实时监控流量数据。

准备工作

依赖引入

在所有服务中需要添加以下依赖。

pom.xml 公共依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Sentinel Dashboard 下载

下载并启动 Sentinel 控制台(建议使用最新版本):

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -jar sentinel-dashboard.jar

核心服务实现

1、Order-Service(订单服务)

订单服务负责接收用户订单请求,并调用库存服务扣减库存。

application.yml 配置

server:
  port: 8081

spring:
  application:
    name: order-service
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080 # 指定 Sentinel Dashboard 地址
        port: 8719 # 服务与 Sentinel Dashboard 的通信端口

management:
  endpoints:
    web:
      exposure:
        include: '*'

主启动类

@SpringBootApplication
@EnableDiscoveryClient
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

控制层

@RestController
@RequestMapping("/orders")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/create")
    @SentinelResource(value = "createOrder", blockHandler = "handleOrderBlock")
    public String createOrder(@RequestParam("productId") String productId) {
        // 调用库存服务扣减库存
        String result = restTemplate.getForObject("http://inventory-service/inventory/deduct?productId=" + productId, String.class);
        return "Order created successfully! Result from inventory: " + result;
    }

    // 流控处理逻辑
    public String handleOrderBlock(String productId, BlockException ex) {
        return "Order service is busy. Please try again later.";
    }
}

流控规则配置

@Configuration
public class SentinelConfig {

    @PostConstruct
    public void initFlowRules() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("createOrder"); // 资源名称
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // 基于 QPS 的流控
        rule.setCount(10); // 最大 QPS 为 10
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }
}

RestTemplate 配置

@Configuration
public class RestTemplateConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

2、Inventory-Service(库存服务)

库存服务负责处理库存扣减请求。

application.yml 配置

server:
  port: 8082

spring:
  application:
    name: inventory-service
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8720

management:
  endpoints:
    web:
      exposure:
        include: '*'

主启动类

@SpringBootApplication
@EnableDiscoveryClient
public class InventoryServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(InventoryServiceApplication.class, args);
    }
}

控制层

@RestController
@RequestMapping("/inventory")
public class InventoryController {

    @GetMapping("/deduct")
    @SentinelResource(value = "deductInventory", blockHandler = "handleDeductBlock", fallback = "fallbackForDeduct")
    public String deduct(@RequestParam("productId") String productId) {
        // 模拟业务处理
        if ("timeout".equals(productId)) {
            try {
                Thread.sleep(2000); // 模拟超时
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return "Inventory deducted successfully for productId: " + productId;
    }

    // 流控处理逻辑
    public String handleDeductBlock(String productId, BlockException ex) {
        return "Inventory service is busy. Please try again later.";
    }

    // Fallback 逻辑
    public String fallbackForDeduct(String productId, Throwable throwable) {
        return "Fallback: Unable to process inventory deduction.";
    }
}

熔断规则配置

@Configuration
public class SentinelConfig {

    @PostConstruct
    public void initDegradeRules() {
        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule rule = new DegradeRule();
        rule.setResource("deductInventory");
        rule.setGrade(RuleConstant.DEGRADE_GRADE_RT); // 基于响应时间熔断
        rule.setCount(1000); // 超时阈值(ms)
        rule.setTimeWindow(10); // 熔断持续时间(秒)
        rule.setMinRequestAmount(5); // 最小请求数
        rule.setStatIntervalMs(60000); // 统计时间窗口(ms)
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }
}

3、Gateway(网关服务)

application.yml 配置

server:
  port: 8080

spring:
  application:
    name: gateway
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8721

  gateway:
    routes:
      - id: order-service
        uri: http://localhost:8081
        predicates:
          - Path=/orders/**
      - id: inventory-service
        uri: http://localhost:8082
        predicates:
          - Path=/inventory/**

主启动类

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

测试步骤

  1. 启动 Sentinel Dashboard 和所有服务(gateway、order-service、inventory-service)。
  2. 在浏览器访问 Sentinel 控制台(http://localhost:8080),添加流控和熔断规则。
  3. 测试订单服务接口:
  • 正常请求:http://localhost:8080/orders/create?productId=1
  • 模拟超时:http://localhost:8080/orders/create?productId=timeout

总结

通过以上示例,我们实现了以下目标:

1、 基于 Sentinel 的流量控制(FlowRule)和熔断降级(DegradeRule)。

2、 使用注解和手动规则配置,实现服务间调用的流量管控。 3、 利用 Gateway 统一流量入口,实现跨服务的高效监控。

你可以在此基础上扩展更多规则,比如热点参数限流、系统保护规则等,进一步增强系统的鲁棒性和稳定性。

责任编辑:武晓燕 来源: 架构师秋天
相关推荐

2022-05-22 09:48:47

微服务Sentinel

2024-05-06 08:45:25

Spring分布式日志

2019-07-22 09:35:23

RedisSentinel

2019-08-05 07:58:01

分布式架构系统

2023-05-12 08:23:03

分布式系统网络

2024-01-26 13:17:00

rollbackMQ订单系统

2023-01-13 07:39:07

2023-04-06 08:52:54

Sentinel分布式系统

2013-09-11 16:02:00

Spark分布式计算系统

2022-05-05 12:03:08

分布式系统设计

2023-08-21 19:10:34

Redis分布式

2023-02-11 00:04:17

分布式系统安全

2022-02-22 10:29:24

分布式架构高可用

2023-05-29 14:07:00

Zuul网关系统

2023-05-05 06:13:51

分布式多级缓存系统

2022-11-06 19:28:02

分布式锁etcd云原生

2023-11-08 10:25:00

模型技术

2022-05-11 13:55:18

高可用性分布式弹性

2017-10-27 08:40:44

分布式存储剪枝系统

2024-10-28 08:01:11

点赞
收藏

51CTO技术栈公众号