[case33]sentinel自定义DataSource实战
序
本文主要研究一下如何自定义sentinel的DataSource,这里以jdbc为例。
maven
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sentinel</artifactId> <version>0.2.0.BUILD-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
扩展AutoRefreshDataSource
public class JdbcDataSource<T> extends AutoRefreshDataSource<String, T> { final String DEFAULT_SQL = "SELECT VALUE from PROPERTIES where APPLICATION=? and PROFILE=? and KEY=?"; final PropertiesResultSetExtractor extractor = new PropertiesResultSetExtractor(); JdbcTemplate jdbc; String app; String key; String profile; public JdbcDataSource(JdbcTemplate jdbc,String app,String profile,String key,ConfigParser<String, T> configParser, long recommendRefreshMs) { super(configParser, recommendRefreshMs); this.jdbc = jdbc; this.app = app; this.key = key; this.profile = profile; } @Override public String readSource() throws Exception { List<String> data = (List<String>) jdbc.query(DEFAULT_SQL, new Object[] { app, profile, key }, this.extractor); if(data.size() > 0){ return data.get(0); } return null; } class PropertiesResultSetExtractor implements ResultSetExtractor<List<String>> { @Override public List<String> extractData(ResultSet rs) throws SQLException, DataAccessException { List<String> result = new ArrayList<>(1); while (rs.next()) { result.add(rs.getString(1)); } return result; } } }
- 这里以拉模式为例,因而扩展的是AutoRefreshDataSource
数据结构及初始化数据
CREATE TABLE IF NOT EXISTS PROPERTIES ( KEY VARCHAR(128), VALUE VARCHAR(4096), APPLICATION VARCHAR(128), PROFILE VARCHAR(128), PRIMARY KEY (`KEY`, `APPLICATION`, `PROFILE`) ); INSERT INTO PROPERTIES (APPLICATION, PROFILE, KEY, VALUE) VALUES ('sentinel-demo', 'jdbc', 'flow', '[ { "resource": "abc", "controlBehavior": 0, "count": 20.0, "grade": 1, "limitApp": "default", "strategy": 0 }, { "resource": "abc1", "controlBehavior": 0, "count": 20.0, "grade": 1, "limitApp": "default", "strategy": 0 } ]'); INSERT INTO PROPERTIES (APPLICATION, PROFILE, KEY, VALUE) VALUES ('sentinel-demo', 'jdbc', 'system', '[ { "avgRt": 10, "highestSystemLoad": 5.0, "maxThread": 10, "qps": 20.0 } ]'); INSERT INTO PROPERTIES (APPLICATION, PROFILE, KEY, VALUE) VALUES ('sentinel-demo', 'jdbc', 'degrade', '[ { "resource": "abc0", "count": 20.0, "grade": 0, "passCount": 0, "timeWindow": 10 }, { "resource": "abc1", "count": 15.0, "grade": 0, "passCount": 0, "timeWindow": 10 } ]');
- 这里仿照spring cloud config server的jdbc存储的schema
自动加载
@Component public class SentinelJdbcAutoConfig implements CommandLineRunner { @Value("${spring.application.name}") String app; @Autowired private Environment environment; @Autowired JdbcTemplate jdbcTemplate; int defaultRefreshMs = 10*1000; @Override public void run(String... args) throws Exception { String profile = environment.getActiveProfiles().length > 0 ? environment.getActiveProfiles()[0] : "default"; // data source for FlowRule DataSource<String, List<FlowRule>> flowRuleDataSource = new JdbcDataSource<List<FlowRule>>(jdbcTemplate, app,profile,"flow", new JsonFlowRuleListParser(),defaultRefreshMs); FlowRuleManager.register2Property(flowRuleDataSource.getProperty()); // data source for DegradeRule DataSource<String, List<DegradeRule>> degradeRuleDataSource = new JdbcDataSource<List<DegradeRule>>(jdbcTemplate, app,profile,"degrade", new JsonDegradeRuleListParser(),defaultRefreshMs); DegradeRuleManager.register2Property(degradeRuleDataSource.getProperty()); // data source for SystemRule DataSource<String, List<SystemRule>> systemRuleDataSource = new JdbcDataSource<List<SystemRule>>(jdbcTemplate, app,profile,"system", new JsonSystemRuleListParser(),defaultRefreshMs); SystemRuleManager.register2Property(systemRuleDataSource.getProperty()); } }
- 这里在启动时通过FlowRuleManager.register2Property,注册了flowRule、degradeRule、systemRule三类规则的数据源
验证
启动之后访问http://localhost:8080/actuator/sentinel,可以看到如下规则:
{ "DegradeRules": [ { "resource": "abc1", "limitApp": "default", "count": 15, "timeWindow": 10, "grade": 0, "cut": false, "passCount": 0 }, { "resource": "abc0", "limitApp": "default", "count": 20, "timeWindow": 10, "grade": 0, "cut": false, "passCount": 0 } ], "SystemRules": [ { "resource": null, "limitApp": null, "highestSystemLoad": 5, "qps": -1, "avgRt": -1, "maxThread": -1 }, { "resource": null, "limitApp": null, "highestSystemLoad": -1, "qps": -1, "avgRt": 10, "maxThread": -1 }, { "resource": null, "limitApp": null, "highestSystemLoad": -1, "qps": -1, "avgRt": -1, "maxThread": 10 }, { "resource": null, "limitApp": null, "highestSystemLoad": -1, "qps": 20, "avgRt": -1, "maxThread": -1 } ], "FlowRules": [ { "resource": "abc1", "limitApp": "default", "grade": 1, "count": 20, "strategy": 0, "refResource": null, "controlBehavior": 0, "warmUpPeriodSec": 10, "maxQueueingTimeMs": 500 }, { "resource": "abc", "limitApp": "default", "grade": 1, "count": 20, "strategy": 0, "refResource": null, "controlBehavior": 0, "warmUpPeriodSec": 10, "maxQueueingTimeMs": 500 } ], "properties": { "enabled": true, "port": "7080", "dashboard": "localhost:9999", "filter": { "order": -2147483648, "urlPatterns": [ "/*" ] } } }查看sentinel的dashboard,可以发现dashboard也能识别出应用自定义的规则。
小结
sentinel datasource提供了灵活的扩展机制,可以自定义数据源来满足不同应用的需求。
doc
相关推荐
Lzs 2020-10-23
聚合室 2020-11-16
零 2020-09-18
Justhavefun 2020-10-22
jacktangj 2020-10-14
ChaITSimpleLove 2020-10-06
Andrea0 2020-09-18
周游列国之仕子 2020-09-15
afanti 2020-09-16
88234852 2020-09-15
YClimb 2020-09-15
风雨断肠人 2020-09-04
卖口粥湛蓝的天空 2020-09-15
stulen 2020-09-15
pythonxuexi 2020-09-06
abfdada 2020-08-26
梦的天空 2020-08-25