Alibaba Sentinel服务哨兵

Sentinel服务哨兵

Alibaba Sentinel 就是一款高性能且轻量级的流量控制、熔断降级可替换方案

Sentinel 官网:https://github.com/alibaba/Sentinel

1.Sentinel是什么

​ 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Sentinel 具有以下特征:
  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。

  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。

  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、

    Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。

    完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快

    速地定制逻辑。例如定制规则管理、适配动态数据源等

Sentinel 分为两个部分:
  • **核心库(Java 客户端)不依赖任何框架/**库,能够运行于所有 Java 运行时环境,同时对 Dubbo Spring Cloud 等框架也有较好的支持。
  • 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器
2.Sentinel 的历史
  1. 2012 年,Sentinel 诞生,主要功能为入口流量控制。
  2. 2013-2017 年,Sentinel 在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景。Sentinel 也因此积累了大量的流量归整场景以及生产实践。
  3. 2018 年,Sentinel 开源,并持续演进。
3.Sentinel vs Hystrix
SentinelHystrix
隔离策略信号量隔离(并发线程数限流)线程池隔离/信号量隔离
熔断降级策略基于响应时间、异常比率、异常数基于异常比率
实时指标实现滑动窗口(LeapArray)滑动窗口(基于 RxJava)
规则配置支持多种数据源支持多种数据源
扩展性多个扩展点插件的形式
基于注解的支 持支持支持
调用链路信息支持同步调用不支持
限流基于 QPS / 并发数,支持基于调用关系的限流有限支持
流量整形支持慢启动、匀速器模式不支持
系统负载保护支持不支持
控制台开箱即用,可配置规则、查看秒级监控、机器发 现等较为简单
常见框架的适 配Servlet、Spring Cloud、Dubbo、gRPC 等S Neertvflliext、Spring Cloud
4.Sentinel核心

Sentinel 的使用可以分为两个部分:

  • 核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 7 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持(见 主流框架适配)。
  • 控制台(Dashboard):控制台主要负责管理推送规则、监控、集群限流分配管理、机器发现等。
5.Sentinel 控制台

Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集
群),规则管理和推送的功能。

下载:sentinel-dashboard-1.7.1.jar
启动控制台
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -
Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.1.jar

注意:启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。

其中 -Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080 。
从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel

注:若您的应用为 Spring Boot 或 Spring Cloud 应用,您可以通过 Spring 配置文件来指定配置,详
情请参考 Spring Cloud Alibaba Sentinel 文档。

为了方便启动,可以编写一个启动脚本 run.bat

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -
Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.1.jar
pause

访问:http://localhost:8080/

6.环境准备

eureka-server :注册中心
eureka-server02 :注册中心
provider-service :商品服务
order-service-rest :订单服务,基于 Ribbon 通过 RestTemplate 调用商品服务
order-server-feign :订单服务,基于 Feign 通过声明式服务调用商品服务

7.客户端接入控制台
添加依赖

父工程需要添加如下依赖:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.1.0.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

消费服务子工程添加依赖

 <!-- spring-cloud-starter-alibaba-sentinel依赖 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
配置文件

客户端需要启动 Transport 模块来与 Sentinel 控制台进行通信。
order-service-rest 的 application.yml

	spring:
        cloud:
            sentinel:
              transport:
                port: 8719
                dashboard: localhost:8080

这里的 spring.cloud.sentinel.transport.port 端口配置会在应用对应的机器上启动一个
Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了一个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中

初始化客户端

​ 客户端,Sentinel 即可完成客户端初始化操作,并持续向控制台发送心跳包

访问

​ 首先确保 Sentinel 是启动状态,然后依次启动 eureka-server,eureka-server02,product-service,
order-service-rest。

多次访问:http://localhost:9090/product/2

在这里插入图片描述

定义资源

​ 资源 是 Sentinel 中的核心概念之一。我们说的资源,可以是任何东西,服务,服务里的方法,甚
至是一段代码。最常用的资源是我们代码中的 Java 方法。Sentinel 提供了 @SentinelResource 注解
用于定义资源,并提供了 AspectJ 的扩展用于自动定义资源、处理 BlockException 等。

模拟服务出错

修改 order-service-rest 项目中的核心代码,模拟服务出错

/**
* 商品管理
*/
@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) {
        // 模拟查询主键为 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, 6666D);
        } /
        / 服务熔断降级处理,函数签名与原函数一致或加一个 Throwable 类型的参数
        public Product selectProductByIdFallback(Integer id, Throwable throwable) {
        System.out.println("product-service 服务的 selectProductById 方法出现异常,
        异常信息如下:"
        + throwable);
        return new Product(id, "服务熔断降级处理-托底数据", 1, 6666D);
    }
}

注意:注解方式埋点不支持 private 方法

定义规则

​ Sentinel 的所有规则都可以在内存态中动态地查询及修改,修改之后立即生效。同时 Sentinel 也提
供相关 API,供您来定制自己的规则策略。
​ Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则*和 热点参数规则

流量控制规则

选择 簇点链路 找到定义好的资源 selectProductById 并点击对应的规则按钮进行设置

在这里插入图片描述

比如我们设置一个流量控制规则,定义资源访问的 QPS 为 1(每秒能处理查询数目 )

在这里插入图片描述

快速刷新页面多次访问:http://localhost:9090/product/2

在这里插入图片描述

熔断降级规则

熔断降级规则支持相应时间、异常比例、异常数三种方式

在这里插入图片描述

访问:http://localhost:9090/product/1

在这里插入图片描述

加载本地规则

Sentinel 支持通过本地文件加载规则配置,使用方式如下(限流规则作为演示)

spring:
	cloud:
		datasource:
            ds1:
              file:
                file: classpath:flowRule.json
                data-type: json
                rule-type: flow

flowRule.json 对应 com.alibaba.csp.sentinel.slots.block.RuleConstant 各属性

[
  {
    "resource": "selectProductList",
    "count": 1,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0,
    "controlBehavior": 0
  }
]

重要属性

Field说明默认值
resource资源名,资源名是限流规则的作用对象
count限流阈值
grade限流阈值类型,QPS 模式(1)或并发线程数模式 (0)QPS 模式
limitApp流控针对的调用来源default ,代表不区 分调用来源
strategy调用关系限流策略:直接、链路、关联根据资源本身(直接)
controlBehavior流控效果(直接拒绝 / 排队等待 / 慢启动模式), 不支持按调用关系限流直接拒绝
clusterMode是否集群限流

访问客户端以后,刷新控制台,查看流控规则如下

8.RestTemplate支持

​ Spring Cloud Alibaba Sentinel 支持对 RestTemplate 调用的服务进行服务保护。需要在构造
RestTemplate Bean 时添加 @SentinelRestTemplate 注解

启动类
@SpringBootApplication
public class OrderServiceRestApplication {
    @Bean
    @LoadBalanced
    @SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class,
            fallback = "fallback", fallbackClass = ExceptionUtil.class)
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceRestApplication.class, args);
    }
}
服务熔断处理类

ExceptionUtil.java必须用静态方法

package com.example.exception;

import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;
import com.example.pojo.Product;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpResponse;

public class ExceptionUtil {

    // 服务流量控制处理
    public static ClientHttpResponse handleException(HttpRequest request,
                                                     byte[] body,
                                                     ClientHttpRequestExecution execution,
                                                     BlockException exception) {
        exception.printStackTrace();
        System.out.println("-----handleException-----");
        return new SentinelClientHttpResponse(
                JSON.toJSONString(new Product(1, "服务流量控制处理-托底数据", 1, 6666D)));
    }

    // 服务熔断降级处理
    public static ClientHttpResponse fallback(HttpRequest request,
                                                    byte[] body,
                                                    ClientHttpRequestExecution execution,
                                                    BlockException exception) {
        exception.printStackTrace();
        return new SentinelClientHttpResponse(
                JSON.toJSONString(new Product(1, "服务熔断降级处理-托底数据", 1, 6666D)));
    }

}
访问

控制台设置流量控制规则,定义资源访问的 QPS 为 1(每秒能处理查询数目)。
快速刷新页面多次访问:http://localhost:9090/product/2

9.OpenFeign支持

其实不管是 Hystrix 还是 Sentinel 对于 Feign 的支持,核心代码基本上是一致的,只需要修改依赖和
配置文件即可

添加依赖
<!-- spring cloud openfeign 依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- spring cloud alibaba sentinel 依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
开启Sentinel
spring:
  application:
    name: order-service-feign # 应用名称
  cloud:
    sentinel:
      transport:
        port: 8719
        dashboard: localhost:8080

# 端口
server:
  port: 9091

# 配置 Eureka Server 注册中心
eureka:
  instance:
    prefer-ip-address: true       # 是否使用 ip 地址注册
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
  client:
    service-url:                  # 设置服务注册中心地址
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/

# feign 开启 sentinel 支持
feign:
  sentinel:
    enabled: true
熔断降级

ProductServiceFallback.java

/**
 * 服务熔断降级处理可以捕获异常
 */
@Component
public class ProductServiceFallbackFactory implements FallbackFactory<ProductService> {

    // 获取日志,在需要捕获异常的方法中进行处理
    Logger logger = LoggerFactory.getLogger(ProductServiceFallbackFactory.class);

    @Override
    public ProductService create(Throwable throwable) {
        return new ProductService() {
            @Override
            public Product selectProductById(Integer id) {
                logger.error("product-service 服务的 selectProductById 方法出现异常,异常信息如下:"
                        + throwable);
                return new Product(id, "托底数据", 2, 6666D);
            }
        };
    }

}
消费服务
/**
 * 商品管理
 */
// 声明需要调用的服务
@FeignClient(value = "product-service", fallbackFactory = ProductServiceFallbackFactory.class)
public interface ProductService {

    /**
     * 根据主键查询商品
     *
     * @param id
     * @return
     */
    @GetMapping("/product/{id}")
    Product selectProductById(@PathVariable("id") Integer id);

}
控制层
@RestController
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private ProductService productService;

    /**
     * 根据主键查询商品
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public Product selectProductById(@PathVariable("id") Integer id) {
        return productService.selectProductById(id);
    }

}
启动类
// 开启 FeignClients 注解
@EnableFeignClients
@SpringBootApplication
public class OrderServiceFeignApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceFeignApplication.class, args);
    }

}

关闭服务提供者,访问:http://localhost:9091/product/2

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Sentinel 是一款开源的分布式系统防护组件,主要用于服务的流量控制、熔断降级和系统负载保护等。Sentinel 提供了一种基于注解和 API 的自定义限流方式。 自定义限流的主要步骤如下: 1. 定义资源名:在 Sentinel 中,资源是需要受到限流保护的对象。可以使用 `@SentinelResource` 注解来定义资源名。 ```java @SentinelResource(value = "myResource", blockHandler = "handleBlock") public void myMethod() { // 方法逻辑 } // 定义限流规则 private void handleBlock(BlockException ex) { // 处理限流逻辑 } ``` 2. 配置限流规则:通过 Sentinel Dashboard 或者代码方式配置限流规则,即设置每个资源的 QPS 阈值、流控模式等。 3. 触发限流:当资源的访问量超过限流规则中的阈值时,Sentinel 会触发限流,执行 blockHandler 中定义的逻辑。 以上是基于注解的方式,如果希望基于 API 进行自定义限流,可以使用 Sentinel 提供的 `SphU` 和 `Tracer` 等类进行手动埋点和统计。例如: ```java // 定义资源名 String resourceName = "myResource"; // 手动埋点 Entry entry = null; try { entry = SphU.entry(resourceName); // 执行业务逻辑 } catch (BlockException ex) { // 处理限流逻辑 } finally { if (entry != null) { entry.exit(); } } // 手动统计指标 Tracer.traceCount(resourceName, 1); ``` 通过自定义限流,可以灵活地根据业务需要对不同的资源进行限流保护,提高系统的可靠性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值