在 sentinel 的控制台设置的规则信息默认都是存在内存当中的。因此不管你是重启了 sentinel 的客户端仍是 sentinel 的控制台。你所设置的规则都会丢失。若是想要 sentinel 在线上环境使用,要么花钱用阿里云上的付费版本,要么本身去实现规则的持久化,若是你或你所在的公司不差钱,那么关掉这篇文章,直接用付费版吧,省掉了一大堆坑要踩。或者你是一个特立独行的人,那么咱们接着往下说。
首先说一下写这篇文章的缘由,由于真得在与 apllo 集成时,踩坑踩到怀疑人生。另外一点是,找了一大堆关于集成的 apollo 的文章,都清一色的都是仿照官方给的限流规则的 DEMO 作的。 可是 sentinel 规则还有熔断规则、参数限流、系统限流、黑白名单等不少规则,每一个规则还有细节上的不一致,这些都没有提,还有一些客户端的坑就更没有了。踩了这么多坑,有了一点心得与体会,梳理与此,但愿能帮助到读者。java
由于修改内容过多,本文不会详述,下面的截图是全部修改内容,而且由于写这篇文章时,1.7版本在 master 开发,有大量快照版本。因此是切到当前稳定的 1.6 分支进行修改的。我已经 fork sentinel 到个人 github,下面是修改的内容 地址git
添加与实现了全部的规则的 Provider 与 Publisher 的配置拉取的与推送。github
规则在控制台的操做 controller 进行大量改造。web
最后一点也是最坑的修改了大量的 xxEntity 类,这些类是规则的实体类,自己没什么,源码是直接 json 化保存的,可是用于客户端集成的 spring-cloud-alibaba 使用了 json 校验,若是 apollo 保存的 json 与客户端的实体类有一丁点不同就报 convert 0 rules but there are 1 rules from datasource . RuleCLass: FlowRule 。 是否是以为很摸不着头脑,这报错跟 json 格式转换错误有什么,下面是 spring-cloud-alibaba json 转换的代码。spring
写这段代码的老哥,把这个异常吃了,并补上了一个 // won't be happen 的注释,你能理解我当时被这个报错坑的死去活来,后来发现是这里的问题吗?后来在 github 上找到两个一样的问题问题1、问题2,按照方法把 xxEntity 中用不到的字段所有加上 @JSONField(serialize = false) 解决。json
添加的配置在下面bootstrap
配置名称 | 是否必填 | 默认值 | 做用 |
---|---|---|---|
env | 否 | DEV | 指定 apollo 使用的环境 |
app.id | 否 | sentinel-apollo | 指定保存 sentinel 规则的 apollo 应用 ID |
cluster.name | 否 | default | 指定保存 sentinel 使用的 apollo 集群 |
namespace.name | 否 | application | 指定保存 sentinel 使用的 apollo 命名空间 |
modify.user | 是 | apollo 控制台显示的修改人帐号,此帐号务必要有此应用的权限 | |
modify.comment | 否 | modify by sentinel-dashboard | apollo 控制台显示的修改备注 |
release.user | 是 | apollo 控制台显示的发布人帐号,此帐号务必要有此应用的权限 | |
release.comment | 否 | release by sentinel-dashboard | apollo 控制台显示的发布备注 |
apollo.portal.url | 是 | apollo 控制台的地址 | |
apollo.application.token | 是 | 指定保存 sentinel 规则的 apollo 应用 openapi 的 token | |
authority.key.suffix | 否 | authority | 认证规则保存在 apollo 中的 key 的后缀 |
degrade.key.suffix | 否 | degrade | 熔断规则保存在 apollo 中的 key 的后缀 |
flow.key.suffix | 否 | flow | 限流规则保存在 apollo 中的 key 的后缀 |
param.key.suffix | 否 | param_flow | 参数限流规则保存在 apollo 中的 key 的后缀 |
system.key.suffix | 否 | system | 系统限流规则保存在 apollo 中的 key 的后缀 |
auth.username | 否 | sentinel | sentinel 控制台的登陆用户名 |
auth.password | 否 | sentinel | sentinel 控制台的登陆密码 |
server.port | 否 | 8080 | sentinel 控制台的启动端口 |
源码地址segmentfault
<dependency> <groupid>org.springframework.cloud</groupid> <artifactid>spring-cloud-starter-alibaba-sentinel</artifactid> <version>0.9.0.RELEASE</version> </dependency> <dependency> <groupid>com.alibaba.csp</groupid> <artifactid>sentinel-datasource-apollo</artifactid> <version>1.5.2</version> </dependency>
package cn.coder4j.study.example.sentinel; import com.alibaba.csp.sentinel.annotation.SentinelResource; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * @author buhao * @version TestController.java, v 0.1 2019-09-19 20:53 buhao */ @RequestMapping("/test") @Controller public class TestController { /** * 没有注解经过自适应的限流 * @return */ @GetMapping("/flowRule") @ResponseBody public String flowRule(){ return "success"; } /** * 经过手动注解的限流 * @return */ @GetMapping("/flowRuleWithAnno") @ResponseBody @SentinelResource("flowRuleWithAnno") public String flowRuleWithAnno(){ return "success"; } /** * 参数限流规则测试 * @param param * @return */ @GetMapping("/paramFlowRule") @ResponseBody @SentinelResource("paramFlowRule") public String paramFlowRule(String param){ return "success"; } /** * 熔断规则测试 * @return */ @GetMapping("/degradeRule") @ResponseBody @SentinelResource("degradeRule") public String degradeRule(){ throw new RuntimeException("服务器异常"); } }
apollo: bootstrap: enabled: true # 开启 apollo meta: xxx # 指定 apollo 注册地址 app: id: sentinel-apollo # 指定规则项目在 apollo 的app.id,要与 sentinel 控制台启动参数一致 spring: application: name: study-sentinel-example # 应用名称,不一样项目要惟一,会把他作为规则 Key 的前缀 cloud: sentinel: transport: dashboard: localhost:8989 # sentinel 控制台的地址 datasource: ds1: apollo: namespace-name: {部门名}.sentinel-rule # 保存规则的 apollo 应用的公共 namespace, 要与 sentinel 控制台启动参数一致 rule-type: flow # 指定该数据源是限流规则 flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds1.apollo.rule-type} # 指定该规则在 apollo 应用中 key 名称 ds2: apollo: namespace-name: {部门名}.sentinel-rule rule-type: degrade # 指定该数据源是熔断规则 flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds2.apollo.rule-type} # 指定该规则在 apollo 应用中 key 名称 ds3: apollo: namespace-name: {部门名}.sentinel-rule rule-type: param_flow # 指定该数据源是参数限流规则 flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds3.apollo.rule-type} # 指定该规则在 apollo 应用中 key 名称 ds4: apollo: namespace-name: {部门名}.sentinel-rule rule-type: system # 指定该数据源是系统限流规则 flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds4.apollo.rule-type} # 指定该规则在 apollo 应用中 key 名称 ds5: apollo: namespace-name: {部门名}.sentinel-rule rule-type: authority # 指定该数据源是认证限流(黑白名单)规则 flow-rules-key: ${spring.application.name}-${spring.cloud.sentinel.datasource.ds5.apollo.rule-type} # 指定该规则在 apollo 应用中 key 名称
jmeter 是用于测试与验证规则使用的,由于能够设置线程数,因此能够很好的测试限流状况。测试脚本下载api
线程组要把线程设置成 100,方便后面的统计,另外为了在一秒内执行完,Ramp-Up 时间设为0 服务器
请求默认值就是填写你本地的启的测试项目的地址
xx 规则填写测试接口地址,参数限流由于要作对照实验因此写了两个
查看结果树能够看到你每次请求的内容与结果
能够看到上张图片内有红色的有绿色的,红色说明断言失败,绿色说明断言成功,断言的内容就是包含 success
聚合统计,这个能够统计出100个线程请求后的整体结果,咱们只要看 Error% 的失败率就能够了。图中能够看到除了熔断限流,其它限流失败率是 0
欢迎关注个人公众号「KIWI的碎碎念」,也能够收藏 个人博客