Sentinel适配GaussDB任务总结

举报
yd_255530874 发表于 2024/12/12 16:09:10 2024/12/12
【摘要】 Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。本文提供了一种使用GaussDB存储Sentinel Dashboard设置的流控规则的方法

Sentinel介绍

Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。

主要功能:

  • 流量控制:可以对系统的入口流量、资源访问流量等进行精确控制,防止系统被突发流量击垮。支持多种流量控制策略,如基于 QPS(每秒查询率)、线程数等。
  • 熔断降级:当调用的服务出现故障或响应时间过长时,自动进行熔断,快速返回错误响应,避免级联故障。同时,还可以根据策略进行降级处理,如返回兜底数据等。
  • 系统负载保护:实时监控系统的负载情况,当系统负载过高时,自动采取保护措施,确保系统的稳定性。
  • 动态规则配置:可以通过控制台等方式动态调整流量控制、熔断降级等规则,无需重启系统。

DEMO完成过程,以FlowRule存储和读取为例

适配过程

  1. fork sentinel源代码,并下载
  2. 在sentinel-extension目录下新建sentinel-datasource-gaussdb模块,如下图所示
  3. 在该模块下实现将流控规则存储到GaussDB和读取规则,新建AbstractGaussDBDataSource实现ReadableDataSource和WritableDataSource接口,部分接口实现在子类中
  4. 新建FlowGaussDBDataSource类继承AbstractGaussDBDataSource,实现父类的抽象方法

DEMO集成sentinel过程

  1. fork:https://gitcode.com/flygoods/OpenSourceForHuaweiDemoJava 仓库,并下载代码,创建sentinel分支,在resource-server中引入sentinel-datasource-gaussdb包
  2. 在pom中添加配置,主要配置如下
    <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-datasource-gaussdb</artifactId>
      <version>1.8.8</version>
      <scope>system</scope>
      <systemPath>${project.basedir}/lib/sentinel-datasource-gaussdb-1.8.8.jar</systemPath>
    </dependency>
    <dependency>
      <groupId>org.opengauss</groupId>
      <artifactId>opengauss-jdbc</artifactId>
      <version>5.1.0-og</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-transport-simple-http</artifactId>
      <version>1.8.8</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba.csp</groupId>
      <artifactId>sentinel-annotation-aspectj</artifactId>
      <version>1.8.8</version>
    </dependency>
    在build中修改plugin配置
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
        <includeSystemScope>true</includeSystemScope>
      </configuration>
    </plugin>
    
  3. 在GaussDB中新建SCHEMA:sentinel,表:sentinel_app、sentinel_flow_rule
    CREATE SCHEMA sentinel;
    
    SET SEARCH_PATH TO sentinel;
    
    DROP TABLE IF EXISTS sentinel_app;
    
    CREATE TABLE sentinel_app
    (
        "id"             serial4 not null,
        "name"           varchar(100),
        "chn_name"       varchar(100),
        "description"    varchar(500),
        "host_name"      varchar(100),
        "ip"             varchar(50),
        "port"           int4,
        "create_user_id" int4,
        "update_user_id" int4,
        "create_time"    timestamp(6),
        "update_time"    timestamp(6),
        "enabled"        int2    NOT NULL DEFAULT 1,
        "deleted"        int2    NOT NULL DEFAULT 0,
        PRIMARY KEY (id)
    );
    
    DROP TABLE IF EXISTS sentinel_flow_rule;
    CREATE TABLE sentinel_flow_rule
    (
        "id"                   serial8,
        "app_id"               int4,
        "resource"             varchar(200),
        "resource_type"        varchar(20),
        "description"          varchar(500),
        "limit_app"            varchar(100),
        "grade"                int2,
        "count"                float8,
        "strategy"             int4,
        "ref_resource"         varchar(200),
        "control_behavior"     int2,
        "warm_up_period_sec"   int4,
        "change_status"        int2,
        "create_user_id"       int4,
        "update_user_id"       int4,
        "create_time"          timestamp(6),
        "update_time"          timestamp(6),
        "enabled"              int2 NOT NULL DEFAULT 1,
        "deleted"              int2 NOT NULL DEFAULT 0,
        "max_queueing_time_ms" int4,
        PRIMARY KEY ("id")
    );
    
  4. 集成sentinel-datasource-gaussdb,关键代码如下
    private void initGaussDBDataSource(String appName, String ip, Integer port) {
        LambdaQueryWrapper<SentinelApp> sentinelAppLambdaQuery = Wrappers.lambdaQuery();
        sentinelAppLambdaQuery.eq(SentinelApp::getName, appName)
                .eq(SentinelApp::getIp, ip)
                .eq(SentinelApp::getPort, port);
        Long count = sentinelAppMapper.selectCount(sentinelAppLambdaQuery);
        int appId = 0;
        if (count > 0) {
            appId = sentinelAppMapper.selectOne(sentinelAppLambdaQuery).getId();
        } else {
            SentinelApp sentinelApp = new SentinelApp();
            sentinelApp.setName(appName);
            sentinelApp.setIp(ip);
            sentinelApp.setPort(port);
            sentinelAppMapper.insert(sentinelApp);
            appId = sentinelApp.getId();
        }
        FlowGaussDBDataSource flowRuleDataSource = new FlowGaussDBDataSource(dataSource, appId, appName, ip, port);
        FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
        WritableDataSourceRegistry.registerFlowDataSource(flowRuleDataSource);
    }
    
  5. 修改启动类,修改后如下
    @SpringBootApplication
    @MapperScan("org.apache.servicecomb.fence.resource.mapper")
    @EnableAspectJAutoProxy
    public class ResourceServerApplication {
        public static void main(String[] args) {
            try {
                new SpringApplicationBuilder(ResourceServerApplication.class).web(WebApplicationType.NONE).run(args);
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    
        //使用aop的方式,拦截请求
        @Bean
        public SentinelResourceAspect sentinelResourceAspect() {
            return new SentinelResourceAspect();
        }
    }
    

DEMO编写

  1. 编写 /v1/sentinel/flow 接口
  2. 在实现方法上添加注解,完成后如下
    @Override
    @SentinelResource(value = "demo-api", blockHandler = "exceptionHandler")
    public String flowRule() {
        return "hello sentinel";
    }
    
    public String exceptionHandler(String str, BlockException ex) {
        return str;
    }
    
  3. 修改resource-server的Dockerfile文件,添加如下启动命令:
    -Dproject.name=resource-server
    -Dcsp.sentinel.dashboard.server=127.0.0.1:8080
    -Dcsp.sentinel.api.port=8791
    
    -Dproject.name:sentinel-dashboard中显示的应用名称
    -Dcsp.sentinel.dashboard.server:管理后台地址
    -Dcsp.sentinel.api.port:应用和sentinel通信的端口
  4. push代码到sentinel分支,使用CodeArts编译、生成resource-server镜像

由于采用容器话部署,确保容器间能正常访问

部署sentinel-dashboard

  1. 将sentinel-dashboard模块的代码,添加Dockerfile后,单独上传一份到gitcode
    FROM openjdk:17.0.2-oracle
    ADD target/sentinel-dashboard.jar .
    CMD ["java","-Dserver.port=8080","-Dcsp.sentinel.dashboard.server=localhost:8080","-jar","sentinel-dashboard.jar"]
    
  2. 使用CodeArts编译、上传镜像
  3. 部署sentinel-dashboard工作负载时,需要添加服务如下:

    9119: 用于访问sentinel-dashboard管理后端
    8791: 用于应用和sentinel通信
  4. 部署完成后访问如下图

DEMO部署

  1. 在CCE中部署resource-server工作负载,部署完成后,在GaussDB中查询sentinel-app表,
  2. 进入sentinel-dashboard后,会发现左侧列表多了一个resource-server的应用,为其添加流控规则
  3. 确定后,查看数据库
  4. 访问DEMO接口测试页,访问接口如下
  5. 修改流控规则
  6. 查看数据库
  7. 再次进行接口测试

    说明规则已经生效
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。