sentinel分布式系统的流量防卫兵

由于 Netflflix 中多项开源产品已进入维护阶段,不再开发新的版本,就目前来看是没有什么问题的。但是从长远角度
出发,我们还是需要考虑是否有可替代产品使用。比如本文中要介绍的 Alibaba Sentinel 就是一款高性能且轻量级
== 流量控制,熔断降级 == 可替换方案。
Sentinel 官网: http://github.com/alibaba/Sentinel
HyStrix 目前状态 :
官网 : http://github.com/Netflflix/Hystrix
1. 学习目标 2. Sentinel 是什么
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点,从流量控制、熔断降
级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 具有以下特征 :
丰富的应用场景 Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控
制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
完备的实时监控 Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数
据,甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态 Sentinel 提供开箱即用的与其它开源框架 / 库的整合模块,例如与 Spring Cloud Dubbo
gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel
完善的 SPI 扩展点 Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制
逻辑。例如定制规则管理、适配动态数据源等。
Sentinel 的主要特性: Sentinel 的开源生态: 2018
Sentinel 分为两个部分 :
核心库( Java 客户端)不依赖任何框架 / 库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring
Cloud 等框架也有较好的支持。【客户端】
控制台( Dashboard )基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
[ 服务端 ]
3. Sentinel 的核心
Sentinel 的使用可以分为两个部分 : 核心库( Java 客户端 ) ∶不依赖任何框架 / 库,能够运行于 Java 7 及以上的版本的运行时环境,同时对 Dubbo /
Spring Cloud 等框架也有较好的支持 ( 见主流框架适配 )
控制台 (Dashboard) : 控制台主要负责管理推送规则、监控、集群限流分配管理、机器发现等。
4. Sentinel 的控制台
Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群 ) ,规则管理和推送
的功能。
官方文档 : https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0
4.1 获取控制台
您可以从 release 页面 下载最新版本的控制台 jar 包。
您也可以从最新版本的源码自行构建 Sentinel 控制台:
下载 控制台 工程
使用以下命令将代码打包成一个 fat jar: mvn clean package
4.2 启动控制台
注意 :启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。
使用如下命令启动控制台:
其中 -Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080
Sentinel 1.6.0 起, Sentinel 控制台引入基本的 登录 功能,默认用户名和密码都是 sentinel 。可以参考 鉴权模块
文档 配置用户名和密码。
注:若您的应用为 Spring Boot Spring Cloud 应用,您可以通过 Spring 配置文件来指定配置,详情请参
Spring Cloud Alibaba Sentinel 文档
5. 项目环境
shop-product : 商品服务,提供了 /product/fifindById/{id}
shop-order-rest : 订单服务,基于 Ribbon 通过 RestTemplate 调用商品服务。
shop-order-feign :订单服务,基于 Feign 通过声明式服务调用商品服务。
6. 客户端接入控制台
控制台启动后,客户端需要按照如下步骤接入到控制台:
添加依赖
定义资源
定义规则
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar
sentinel-dashboard.jar 先把可能需要保护的资源定义好,之后再配置规则。也可以理解为,只要有了资源,我们就可以在任何时候灵活地
定义各种流量控制规则。在编码的时候,只需要考虑这个代码是否需要保护,如果需要保护,就将之定义为一个资
二、在根目录下开启cmd黑窗口启用jar文件

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

加入依赖
<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
配置文件
客户端需要启动 Transport 模块来与 Sentinel 控制台进行通信。
shop-order  application.yml
spring :
   cloud :
     sentinel :
        transport :
                port : 8719
                dashboard : localhost : 8080
定义资源
资源 Sentinel 中的核心概念之一。我们说的资源,可以是任何东西,服务,服务里的方法,甚至是一段代码。最
常用的资源是我们代码中的 Java 方法。 Sentinel 提供了 @SentinelResource 注解用于定义资源,并提供了 AspectJ
扩展用于自动定义资源、处理 BlockException 等。
package com.slj.order.service.Impl;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.slj.entry.Product;
import com.slj.order.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;


/**
 * @program: springcloud-parent
 * @description:
 * @author: 孙路军
 * @create: 2021-07-15 10:39
 **/

@Service
public class ProductServiceImpl_blank implements ProductService {

    @Autowired
    private RestTemplate restTemplate;

    @Override
    @SentinelResource(value = "findByid", blockHandler = "selectByIdBlock", fallback = "selectByIdBack")
    public Product findByid(Integer pid) {
            if(pid==1){
                    throw new RuntimeException("pid不能为1");
                    }
        return restTemplate.getForObject("http://shop-product/product/findById?pid=" + pid, Product.class);
    }


    public Product selectByIdBlock(Integer pid,BlockException e){
        Product product=new Product();
        product.setPid(pid);
        product.setPname("熔断");
        return product;
    }

    public Product selectByIdBack(Integer pid,Throwable e){
        Product product=new Product();
        product.setPid(pid);
        product.setPname("异常");
        return product;
    }
}
测试

 

 

 点击新增之后,继续访问页面同时点击多次就会出现熔断,这个垄断是我们在后台写的
blockHandlerMethod方法里

 

 降级是通常是为异常设置的,设置好降级之后,一般我们要删除流控设置的东西。要不然时间间隔效果看不出来。设置id为1的时候出现异常 

 多次访问id为1就会出现下图所示

 设置id为2的不是异常,没过间隔30秒访问id为2也会出现

 过了30秒之后才会成功访问

 

动态规则扩展
SentinelProperties 内部提供了 TreeMap 类型的 datasource 属性用于配置数据源信息。支持
文件配置规
Nacos 配置规则
ZooKeeper 配置规则
Apollo 配置规则
Redis 配置规则
6.3.3.1. 文件配置规则
Sentinel 支持通过本地文件加载规则配置,使用方式如下 ( 限流规则作为演示 )

spring :
cloud :
sentinel :
datasource :
ds1 :
fifile :
fifile : classpath : flflowRule.json
data-type : json
rule-type : flflow
flflowRule.json 对应 com.alibaba.csp .sentinel.slots.block .RuleConstant 各属性
[
{
"resource" : "fifindByid" ,
"count" : 1 ,
"grade" : 1 ,
"limitApp" : "default" ,
"strategy" : 0 ,
"controlBehavior" : 0
}
]
. RestTemplate 支持
Spring Cloud Alibaba Sentinel 支持对 RestTemplate 调用的服务进行服务保护。需要在构造 RestTemplate Bean
添加 SentinelRestTemplate 注解。

 创建util类ExceptionUtil

package com.slj.order.util;

import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;
import com.slj.entry.Product;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

/**
 * @program: springcloud-parent
 * @description: gongjulei
 * @author: 孙路军
 * @create: 2021-07-15 16:44
 **/
@Component
public class ExceptionUtil {
    public static ClientHttpResponse fallback(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) {
        return new SentinelClientHttpResponse(JSON.toJSONString(new Product(1,"服务流量控制-兜底的数据",5555.0,1000)));
    }
    public static ClientHttpResponse handlerException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) {
        return new SentinelClientHttpResponse(JSON.toJSONString(new Product(1,"服务熔断降级控制-兜底的数据",6666.0,1000)));

    }
}
在主启动类上加上注解,方法名要和创建的 ExceptionUti的方法名字一致

 

 

 openfeign的支持

在配置里多加3行代码,是openfeign让sentinel管理所需要的

 添加依赖

<dependency>
<groupId> org.springframework.cloud </groupId>
<artifactId> spring-cloud-starter-openfeign </artifactId>
</dependency>
<dependency>
<groupId> com.alibaba.cloud </groupId>
<artifactId> spring-cloud-starter-alibaba-sentinel </artifactId>
</dependency>
开启 Sentinel
spring :
cloud :
sentinel :
transport :
dashboard : localhost : 8080
feign :
sentinel :
enabled : true

创建一个实现类继承所需要的openfeign的方法

 openfeign的接口

 

实现类

 

  运行成功后如下图所示

 

当设置降级或者流控之后进行操作如下图所示

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值