1.1. 引言
- 昨天已经把sentinel成功部署到线上环境,可参考我上篇博文,该走的坑也都走了一遍,已经可以初步使用它的限流和降级功能,根据我目前的实践,限流和降级规则似乎不能一同起效,还不知道原因,下面继续探索
1.2. 源码
1.2.1. 流控降级监控等的构建
- 首先客户端而言,我关注的是我写的代码SphU.entry,这明显是很关键的方法,下图的内容就是这里构建的
- -Sentinel工作主流程就包含在上面一个方法里,通过链式调用的方式,经过了建立树状结构,保存统计簇点,异常日志记录,实时数据统计,负载保护,权限认证,流量控制,熔断降级等Slot
- 进入链式方法的入口为CtSph类,try方法大括号内
Entry e = new CtEntry(resourceWrapper, chain, context); try { chain.entry(context, resourceWrapper, null, count, prioritized, args); } catch (BlockException e1) { e.exit(count, args); throw e1; } catch (Throwable e1) { // This should not happen, unless there are errors existing in Sentinel internal. RecordLog.info("Sentinel unexpected exception", e1); }
1.2.2. 修改控制台规则是如何通知客户端的?
- 看sentinel-transport-simple-http包中的HttpEventTask类,它开启了一个线程,转么用来做为socket连接,控制台通过socket请求通知客户端,从而更新客户端规则,更改规则核心代码如下
// Find the matching command handler. CommandHandler<?> commandHandler = SimpleHttpCommandCenter.getHandler(commandName); if (commandHandler != null) { CommandResponse<?> response = commandHandler.handle(request); handleResponse(response, printWriter, outputStream); } else { // No matching command handler. badRequest(printWriter, "Unknown command `" + commandName + '`'); }
通过命令模式,commandName为setRules时,更新规则
1.2.3. 既然它建立连接用的socket,为什么不用netty呢?
- 带着这个疑问,我本想在issues里找下,突然发现它的源码中有个sentinel-transport-netty-http这个包和sentinel-transport-simple-http处于同级,官方的例子用的simple-http,但明显它也准备了netty-http,于是我替换成了netty-http,运行后效果和原先一样,至于效率上有没有提升,我就不清楚了^_^
1.2.4. 流量规则如何检查?
- 该规则检查类为FlowRuleChecker,在core核心包中,核心检查方法如下
private static boolean passLocalCheck(FlowRule rule, Context context, DefaultNode node, int acquireCount, boolean prioriti