美文网首页
RPC(十一:Sentinel )

RPC(十一:Sentinel )

作者: supremecsp | 来源:发表于2022-06-28 11:39 被阅读0次

    Sentinel 是什么?
    随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应过载保护、热点流量防护等多个维度保护服务的稳定性。
    官网:https://sentinelguard.io/zh-cn/index.html
    项目介绍:https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

    在限制的手段上,Sentinel 和 Hystrix 采取了完全不一样的方法。
    Hystrix 通过线程池的方式,来对依赖(在我们的概念中对应资源)进行了隔离。这样做的好处是资源和资源之间做到了最彻底的隔离。缺点是除了增加了线程切换的成本,还需要预先给各个资源做线程池大小的分配。
    Sentinel 对这个问题采取了两种手段:

    • 通过并发线程数进行限制
      和资源池隔离的方法不同,Sentinel 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。这样不但没有线程切换的损耗,也不需要您预先分配线程池的大小。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。
    • 通过响应时间对资源进行降级
      除了对并发线程数进行控制以外,Sentinel 还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。


      线程池隔离时候耗时长的请求,保证大量tomcat线程可用
      线程池隔离和信号量隔离区别可以看看文章:Hystrix线程池隔离和信号量隔离的区别

    下面简单实践下sentinel的使用吧:
    一、 安装Jmeter
    下载地址:http://jmeter.apache.org/download_jmeter.cgi
    教程参考:JAVA常用工具--JMeter压力测试工具_lanyh996的博客-CSDN博客_java压力测试工具
    二、 安装Sentinel
    下载地址:https://github.com/alibaba/Sentinel/releases
    下载的是jar包可以直接运行
    java -Dserver.port=8480 -Dcsp.sentinel.dashboard.server=localhost:8480 -Dproject.name=sentinel-dashboard -Dsentinel.dashboard.auth.username=sentinel -Dsentinel.dashboard.auth.password=123456 -jar sentinel-dashboard-1.7.2.jar
    参数说明:(注意:参数要放到 -jar的前边)

    -Dserver.port=8480 # 指定控制台的端口为8480
    -Dcsp.sentinel.dashboard.server=localhost:8480 # 指定要被哪个控制台监控(这里指定的是自己监控自己)
    -Dproject.name=sentinel-dashboard # 指定实例名称(名称会在控制台左侧以菜单显示)
    -Dsentinel.dashboard.auth.username=sentinel # 设置登录的帐号为:sentinel
    -Dsentinel.dashboard.auth.password=123456 # 设置登录的密码为:123456

    重启后访问:http://localhost:8480/


    更多的参数参考:
    启动配置:https://github.com/alibaba/Sentinel/wiki/%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE%E9%A1%B9
    登录鉴权:https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0#%E9%89%B4%E6%9D%83

    SpringCloud项目服务端配置:

    server:
        port: 8321
    spring:
        application:
            name: alibaba-sentinel # 项目名称,如果不写Sentinel会自己产生一个有端口号的名称
        cloud:
            sentinel:
                transport:
                    # 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互
                    port: 8719
                    # sentinel控制台地址
                    dashboard: localhost:8480
    

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

    在接口中使用@SentinelResource注解

     @GetMapping("/rateLimit/byURL")
        @SentinelResource(value = "byURL")
        public CommonGenericResultRes byURL(){
            int i=0;
            return new CommonGenericResultRes("按url限流测试ok");
        }
    

    启动后要先访问下该接口,才能在图形化界面看到


    接下来对资源做下限流

    启动Jmeter发送请求,可以看到简单的曲线波动

    官网@SentinelResource的使用:注解支持 · alibaba/Sentinel Wiki (github.com)
    @SentinelResource的参数如下:
    value:资源名称
    entryType:entry 类型,可选项(默认为 EntryType.OUT),可选EntryType.OUT和EntryType.IN
    blockHandler/ blockHandlerClass:定位对应处理 BlockException 的函数名称blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。
    fallback / fallbackClass:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。
    defaultFallback(since 1.6.0):默认的 fallback 函数名称,可选项
    exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
    示例:

    public class TestService {
    
        // 原函数
        @SentinelResource(value = "hello", blockHandler = "exceptionHandler", fallback = "helloFallback")
        public String hello(long s) {
            return String.format("Hello at %d", s);
        }
        
        // Fallback 函数,函数签名与原函数一致或加一个 Throwable 类型的参数.
        public String helloFallback(long s) {
            return String.format("Halooooo %d", s);
        }
    
        // Block 异常处理函数,参数最后多一个 BlockException,其余与原函数一致.
        public String exceptionHandler(long s, BlockException ex) {
            // Do some log here.
            ex.printStackTrace();
            return "Oops, error occurred at " + s;
        }
    
        // 这里单独演示 blockHandlerClass 的配置.
        // 对应的 `handleException` 函数需要位于 `ExceptionUtil` 类中,并且必须为 public static 函数.
        @SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {ExceptionUtil.class})
        public void test() {
            System.out.println("Test");
        }
    }
    

    Sentinel一个比较显著的问题:就是随着项目的重启,原来做好的配置就都没有了,还需要再配置。这点如果是在生产环境是不能发生的。我们可以通过配置apollo避免这个问题。
    添加依赖:

    <!-- sentinel整合apollo进行规则持久化 -->
    </dependency>
        <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-apollo</artifactId>
    </dependency>
    

    添加与 sentinel 规则相关的配置项:

    # 项目名
    spring.application.name = myApplication
    # sentinel + apollo 进行规则持久化,为了方便管理,统一将所有项目的 sentinel 规则存放在 sentinel-rules 的公共NameSpace中
    sentinel.datasource.rules.apollo.namespace-name = EDU001.sentinel-rules
     
    # 规则类型:限流
    spring.cloud.sentinel.datasource.flow.apollo.ruleType = flow
    # 从Apollo公共空间中EDU001.sentinel-rules读取限流规则
    spring.cloud.sentinel.datasource.flow.apollo.namespace-name = ${sentinel.datasource.rules.apollo.namespace-name}
    # 限流规则的具体内容,具体写法下文会介绍(我们需要再添加一个key为“myApplication-flow-rules”的属性存放具体的限流规则)
    spring.cloud.sentinel.datasource.flow.apollo.flowRulesKey = ${spring.application.name}-${spring.cloud.sentinel.datasource.flow.apollo.ruleType}-rules
     
    # 规则类型:熔断降级
    spring.cloud.sentinel.datasource.degrade.apollo.ruleType = degrade
    # 从Apollo公共空间中EDU001.sentinel-rules读取熔断规则
    spring.cloud.sentinel.datasource.degrade.apollo.namespace-name = ${sentinel.datasource.rules.apollo.namespace-name}
    # 熔断降级规则的具体内容,具体写法下文会介绍
    spring.cloud.sentinel.datasource.degrade.apollo.flowRulesKey = ${spring.application.name}-${spring.cloud.sentinel.datasource.degrade.apollo.rule-ruleType}-rules
    

    push 模式:即推模式,由规则中心统一推送, Sentinel Client 通过注册监听器的方式时刻监听变化,比如使用 Nacos、Apollo、ZooKeeper 等配置中心,这种方式有更好的实时性和一致性保证。生产环境下推荐采用 push 模式的数据源,push 推送的操作应该由 Sentinel dashboard 和 Config Center Dashboard 控制台统一进行管理和推送,不应该经 Sentinel Client 推送至配置中心,Sentinel Client 仅负责获取配置中心推送的配置并更新到本地,因此推送规则正确做法应该是:配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 客户端。
    单纯通过上面配置只能实现apollo更改同步到图形化界面,实现不了图形化界面更改同步到apollo,需要调整代码,具体怎么实现可以看文章:Sentinel 规则持久化到 apollo 配置中心

    相关文章

      网友评论

          本文标题:RPC(十一:Sentinel )

          本文链接:https://www.haomeiwen.com/subject/hssavrtx.html