Sentinel适配GaussDB任务总结
【摘要】 Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。本文提供了一种使用GaussDB存储Sentinel Dashboard设置的流控规则的方法
Sentinel介绍
Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
主要功能:
- 流量控制:可以对系统的入口流量、资源访问流量等进行精确控制,防止系统被突发流量击垮。支持多种流量控制策略,如基于 QPS(每秒查询率)、线程数等。
- 熔断降级:当调用的服务出现故障或响应时间过长时,自动进行熔断,快速返回错误响应,避免级联故障。同时,还可以根据策略进行降级处理,如返回兜底数据等。
- 系统负载保护:实时监控系统的负载情况,当系统负载过高时,自动采取保护措施,确保系统的稳定性。
- 动态规则配置:可以通过控制台等方式动态调整流量控制、熔断降级等规则,无需重启系统。
DEMO完成过程,以FlowRule存储和读取为例
适配过程
- fork sentinel源代码,并下载
- 在sentinel-extension目录下新建sentinel-datasource-gaussdb模块,如下图所示
- 在该模块下实现将流控规则存储到GaussDB和读取规则,新建AbstractGaussDBDataSource实现ReadableDataSource和WritableDataSource接口,部分接口实现在子类中
- 新建FlowGaussDBDataSource类继承AbstractGaussDBDataSource,实现父类的抽象方法
DEMO集成sentinel过程
- fork:https://gitcode.com/flygoods/OpenSourceForHuaweiDemoJava 仓库,并下载代码,创建sentinel分支,在resource-server中引入sentinel-datasource-gaussdb包
- 在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>
- 在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") );
- 集成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); }
- 修改启动类,修改后如下
@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编写
- 编写 /v1/sentinel/flow 接口
- 在实现方法上添加注解,完成后如下
@Override @SentinelResource(value = "demo-api", blockHandler = "exceptionHandler") public String flowRule() { return "hello sentinel"; } public String exceptionHandler(String str, BlockException ex) { return str; }
- 修改resource-server的Dockerfile文件,添加如下启动命令:
-Dproject.name:sentinel-dashboard中显示的应用名称-Dproject.name=resource-server -Dcsp.sentinel.dashboard.server=127.0.0.1:8080 -Dcsp.sentinel.api.port=8791
-Dcsp.sentinel.dashboard.server:管理后台地址
-Dcsp.sentinel.api.port:应用和sentinel通信的端口 - push代码到sentinel分支,使用CodeArts编译、生成resource-server镜像
由于采用容器话部署,确保容器间能正常访问
部署sentinel-dashboard
- 将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"]
- 使用CodeArts编译、上传镜像
- 部署sentinel-dashboard工作负载时,需要添加服务如下:
9119: 用于访问sentinel-dashboard管理后端
8791: 用于应用和sentinel通信 - 部署完成后访问如下图
DEMO部署
- 在CCE中部署resource-server工作负载,部署完成后,在GaussDB中查询sentinel-app表,
- 进入sentinel-dashboard后,会发现左侧列表多了一个resource-server的应用,为其添加流控规则
- 确定后,查看数据库
- 访问DEMO接口测试页,访问接口如下
- 修改流控规则
- 查看数据库
- 再次进行接口测试
说明规则已经生效
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)