通俗易懂的阿里Sentinel源码分析:如何向控制台发送心跳包?
源码分析
public class Env {
public static final Sph sph = new CtSph();
static {
// 在Env类的静态代码块中,
// 触发了一系列初始化操作,
// 其中就包括发送心跳包的初始化。
// 如果Env类一直没有被用到,
// 那么不会触发该初始操作。
// 这也印证了官方的“确保客户端有访问量,
// 才开始向控制台发送心跳包”的说法,
// 因为有访问量就会用到Env类。
InitExecutor.doInit();
}
}
InitExecutor.doInit方法的核心源码:
// 通过SPI获取实现了InitFunc接口的实现类,
// 其中初始化发送心跳包的类是HeartbeatSenderInitFunc。
ServiceLoader<InitFunc> loader = ServiceLoaderUtil.getServiceLoader(InitFunc.class);
List<OrderWrapper> initList = new ArrayList<OrderWrapper>();
// 按照InitOrder注解的值对实现类进行排序
for (InitFunc initFunc : loader) {
RecordLog.info("Found init func: " + initFunc.getClass().getCanonicalName());
insertSorted(initList, initFunc);
}
// 按照顺序调用每一个实现类的init方法,
// 其中也包括HeartbeatSenderInitFunc实现类。
for (OrderWrapper w : initList) {
w.func.init();
RecordLog.info(String.format("Executing %s with order %d",
w.func.getClass().getCanonicalName(), w.order));
}
HeartbeatSenderInitFunc.init方法的源码:
// 通过SPI获取HeartbeatSender的实现类,
// 默认的实现类是SimpleHttpHeartbeatSender。
HeartbeatSender sender = HeartbeatSenderProvider.getHeartbeatSender();
if (sender == null) {
RecordLog.warn("WARN: No HeartbeatSender loaded");
return;
}
// 初始化一个支持定时及周期性任务执行的线程池
initSchedulerIfNeeded();
// 获取发送心跳包的时间间隔,如果没有配置
//则调用HeartbeatSender.intervalMs方法获取。
// 在SimpleHttpHeartbeatSender类中,
// intervalMs返回的数值是10000,也就是10秒。
long interval = retrieveInterval(sender);
setIntervalIfNotExists(interval);
// 设置周期性任务
scheduleHeartbeatTask(sender, interval);
HeartbeatSenderInitFunc.scheduleHeartbeatTask方法的核心源码:
pool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
// 每隔interval毫秒,
// 执行一次sender的sendHeartbeat方法。
sender.sendHeartbeat();
} catch (Throwable e) {
RecordLog.warn("Send heartbeat error", e);
}
}
}, 5000, interval, TimeUnit.MILLISECONDS);
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
SimpleHttpHeartbeatSender.sendHeartbeat方法的核心源码:
// 通过csp.sentinel.dashboard.server配置,
// 获取第一个服务端的IP和端口
InetSocketAddress addr = getAvailableAddress();
if (addr == null) {
return false;
}
SimpleHttpRequest request = new SimpleHttpRequest(addr, HEARTBEAT_PATH);
// 构建心跳包的参数,
// 包括客户端IP、端口、应用名称等信息。
request.setParams(heartBeat.generateCurrentMessage());
try {
// 向服务端发送POST请求
SimpleHttpResponse response = httpClient.post(request);
// 状态码为200时,返回true。
if (response.getStatusCode() == OK_STATUS) {
return true;
}
} catch (Exception e) {
RecordLog.warn("Failed to send heartbeat to " + addr + " : ", e);
}
return false;
调用流程
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。
分析结果
在客户端首次调用后,默认为每隔10秒向控制台发送心跳包。
可以通过SentinelConfig.setConfig方法修改间隔配置,比如,把心跳包发送时间间隔改为30秒:
SentinelConfig.setConfig(TransportConfig.HEARTBEAT_INTERVAL_MS, "30000");
另外,热更新控制台的IP和端口也有可能实现,比如:先修改csp.sentinel.dashboard.server
的配置值,然后再调用SimpleHttpHeartbeatSender的getDefaultConsoleIps方法。
微信公众号:万猫学社
微信扫描二维码
获得更多Java技术干货

通俗易懂的阿里Sentinel源码分析:如何向控制台发送心跳包?的更多相关文章
- 2. Sentinel源码分析—Sentinel是如何进行流量统计的?
这一篇我还是继续上一篇没有讲完的内容,先上一个例子: private static final int threadCount = 100; public static void main(Strin ...
- 3. Sentinel源码分析— QPS流量控制是如何实现的?
Sentinel源码解析系列: 1.Sentinel源码分析-FlowRuleManager加载规则做了什么? 2. Sentinel源码分析-Sentinel是如何进行流量统计的? 上回我们用基于并 ...
- 4.Sentinel源码分析— Sentinel是如何做到降级的?
各位中秋节快乐啊,我觉得在这个月圆之夜有必要写一篇源码解析,以表示我内心的高兴~ Sentinel源码解析系列: 1.Sentinel源码分析-FlowRuleManager加载规则做了什么? 2. ...
- 5.Sentinel源码分析—Sentinel如何实现自适应限流?
Sentinel源码解析系列: 1.Sentinel源码分析-FlowRuleManager加载规则做了什么? 2. Sentinel源码分析-Sentinel是如何进行流量统计的? 3. Senti ...
- 6.Sentinel源码分析—Sentinel是如何动态加载配置限流的?
Sentinel源码解析系列: 1.Sentinel源码分析-FlowRuleManager加载规则做了什么? 2. Sentinel源码分析-Sentinel是如何进行流量统计的? 3. Senti ...
- 7.Sentinel源码分析—Sentinel是怎么和控制台通信的?
这里会介绍: Sentinel会使用多线程的方式实现一个类Reactor的IO模型 Sentinel会使用心跳检测来观察控制台是否正常 Sentinel源码解析系列: 1.Sentinel源码分析-F ...
- 阿里sentinel源码研究深入
1. 阿里sentinel源码研究深入 1.1. 前言 昨天已经把sentinel成功部署到线上环境,可参考我上篇博文,该走的坑也都走了一遍,已经可以初步使用它的限流和降级功能,根据我目前的实践,限流 ...
- Sentinel 源码分析- 熔断降级原理分析
直接从Sentinel 源码demo ExceptionRatioCircuitBreakerDemo看起 直接看他的main函数 public static void main(String[] a ...
- Spark RPC框架源码分析(三)Spark心跳机制分析
一.Spark心跳概述 前面两节中介绍了Spark RPC的基本知识,以及深入剖析了Spark RPC中一些源码的实现流程. 具体可以看这里: Spark RPC框架源码分析(二)运行时序 Spark ...
随机推荐
- 注解@NotNull/@NotEmpty/@NotBlank
@NotNull:不能为null,但可以为empty @NotEmpty:不能为null,而且长度必须大于0 @NotBlank:只能作用在String上,不能为null,而且调用trim()后,长度 ...
- Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素 - 允许重复
381. O(1) 时间插入.删除和获取随机元素 - 允许重复 设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构. 注意: 允许出现重复元素. insert(val):向集合中插 ...
- Java实现 LeetCode 222 完全二叉树的节点个数
222. 完全二叉树的节点个数 给出一个完全二叉树,求出该树的节点个数. 说明: 完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集 ...
- java实现第六届蓝桥杯空心菱形
空心菱形 标题:空心菱形 小明刚刚开发了一个小程序,可以打印出任意规模的空心菱形,规模为6时,如下图: ****** ****** ***** ***** **** **** *** *** ** * ...
- java创建透明背景的PNG图片加自定义文字水印
人在码上走,需求天天有.这不,今天前端让我返回一个带自定义水印的背景图片.一通google,有现成的代码,但是基本是直接在源图上添加水印,生成出来的文字样式也没有控制好,看来又只有自己造轮子了. 过程 ...
- 使用百度地图时,Application类的onCreate执行两次的解决方案
应用做的匆忙,很多地方只顾实现功能,没有兼顾好性能,所以停下来重构代码优化性能,结果在打log看启动时间的时候,发现Application的onCreate执行了多次,这样导致重复初始化资源,初始化了 ...
- [原创][开源] SunnyUI.Net 国际化
SunnyUI.Net, 基于 C# .Net WinForm 开源控件库.工具类库.扩展类库.多页面开发框架 Blog: https://www.cnblogs.com/yhuse Gitee: h ...
- 问题解决:psql: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
错误提示: psql: could not connect to server: No such file or directory Is the server running locally and ...
- 网络聚合Network Teaming
team是新的聚合软件,依赖于安装包teamd,可以通过nmcli管理. team和bond的区别在于,支持hash加密,支持负载均衡,支持8块网卡,更好地支持IPV6,总之要取代bond. 1. 添 ...
- docker中mongdb常用操作
一.进入 --使用本地命令行查看 docker exec -it mongos bash