源码分析

  1. public class Env {
  2. public static final Sph sph = new CtSph();
  3. static {
  4. // 在Env类的静态代码块中,
  5. // 触发了一系列初始化操作,
  6. // 其中就包括发送心跳包的初始化。
  7. // 如果Env类一直没有被用到,
  8. // 那么不会触发该初始操作。
  9. // 这也印证了官方的“确保客户端有访问量,
  10. // 才开始向控制台发送心跳包”的说法,
  11. // 因为有访问量就会用到Env类。
  12. InitExecutor.doInit();
  13. }
  14. }

InitExecutor.doInit方法的核心源码:

  1. // 通过SPI获取实现了InitFunc接口的实现类,
  2. // 其中初始化发送心跳包的类是HeartbeatSenderInitFunc。
  3. ServiceLoader<InitFunc> loader = ServiceLoaderUtil.getServiceLoader(InitFunc.class);
  4. List<OrderWrapper> initList = new ArrayList<OrderWrapper>();
  5. // 按照InitOrder注解的值对实现类进行排序
  6. for (InitFunc initFunc : loader) {
  7. RecordLog.info("Found init func: " + initFunc.getClass().getCanonicalName());
  8. insertSorted(initList, initFunc);
  9. }
  10. // 按照顺序调用每一个实现类的init方法,
  11. // 其中也包括HeartbeatSenderInitFunc实现类。
  12. for (OrderWrapper w : initList) {
  13. w.func.init();
  14. RecordLog.info(String.format("Executing %s with order %d",
  15. w.func.getClass().getCanonicalName(), w.order));
  16. }

HeartbeatSenderInitFunc.init方法的源码:

  1. // 通过SPI获取HeartbeatSender的实现类,
  2. // 默认的实现类是SimpleHttpHeartbeatSender。
  3. HeartbeatSender sender = HeartbeatSenderProvider.getHeartbeatSender();
  4. if (sender == null) {
  5. RecordLog.warn("WARN: No HeartbeatSender loaded");
  6. return;
  7. }
  8. // 初始化一个支持定时及周期性任务执行的线程池
  9. initSchedulerIfNeeded();
  10. // 获取发送心跳包的时间间隔,如果没有配置
  11. //则调用HeartbeatSender.intervalMs方法获取。
  12. // 在SimpleHttpHeartbeatSender类中,
  13. // intervalMs返回的数值是10000,也就是10秒。
  14. long interval = retrieveInterval(sender);
  15. setIntervalIfNotExists(interval);
  16. // 设置周期性任务
  17. scheduleHeartbeatTask(sender, interval);

HeartbeatSenderInitFunc.scheduleHeartbeatTask方法的核心源码:

  1. pool.scheduleAtFixedRate(new Runnable() {
  2. @Override
  3. public void run() {
  4. try {
  5. // 每隔interval毫秒,
  6. // 执行一次sender的sendHeartbeat方法。
  7. sender.sendHeartbeat();
  8. } catch (Throwable e) {
  9. RecordLog.warn("Send heartbeat error", e);
  10. }
  11. }
  12. }, 5000, interval, TimeUnit.MILLISECONDS);

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

SimpleHttpHeartbeatSender.sendHeartbeat方法的核心源码:

  1. // 通过csp.sentinel.dashboard.server配置,
  2. // 获取第一个服务端的IP和端口
  3. InetSocketAddress addr = getAvailableAddress();
  4. if (addr == null) {
  5. return false;
  6. }
  7. SimpleHttpRequest request = new SimpleHttpRequest(addr, HEARTBEAT_PATH);
  8. // 构建心跳包的参数,
  9. // 包括客户端IP、端口、应用名称等信息。
  10. request.setParams(heartBeat.generateCurrentMessage());
  11. try {
  12. // 向服务端发送POST请求
  13. SimpleHttpResponse response = httpClient.post(request);
  14. // 状态码为200时,返回true。
  15. if (response.getStatusCode() == OK_STATUS) {
  16. return true;
  17. }
  18. } catch (Exception e) {
  19. RecordLog.warn("Failed to send heartbeat to " + addr + " : ", e);
  20. }
  21. return false;

调用流程

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

分析结果

在客户端首次调用后,默认为每隔10秒向控制台发送心跳包。

可以通过SentinelConfig.setConfig方法修改间隔配置,比如,把心跳包发送时间间隔改为30秒:

  1. SentinelConfig.setConfig(TransportConfig.HEARTBEAT_INTERVAL_MS, "30000");

另外,热更新控制台的IP和端口也有可能实现,比如:先修改csp.sentinel.dashboard.server的配置值,然后再调用SimpleHttpHeartbeatSender的getDefaultConsoleIps方法。

微信公众号:万猫学社

微信扫描二维码

获得更多Java技术干货

通俗易懂的阿里Sentinel源码分析:如何向控制台发送心跳包?的更多相关文章

  1. 2. Sentinel源码分析—Sentinel是如何进行流量统计的?

    这一篇我还是继续上一篇没有讲完的内容,先上一个例子: private static final int threadCount = 100; public static void main(Strin ...

  2. 3. Sentinel源码分析— QPS流量控制是如何实现的?

    Sentinel源码解析系列: 1.Sentinel源码分析-FlowRuleManager加载规则做了什么? 2. Sentinel源码分析-Sentinel是如何进行流量统计的? 上回我们用基于并 ...

  3. 4.Sentinel源码分析— Sentinel是如何做到降级的?

    各位中秋节快乐啊,我觉得在这个月圆之夜有必要写一篇源码解析,以表示我内心的高兴~ Sentinel源码解析系列: 1.Sentinel源码分析-FlowRuleManager加载规则做了什么? 2. ...

  4. 5.Sentinel源码分析—Sentinel如何实现自适应限流?

    Sentinel源码解析系列: 1.Sentinel源码分析-FlowRuleManager加载规则做了什么? 2. Sentinel源码分析-Sentinel是如何进行流量统计的? 3. Senti ...

  5. 6.Sentinel源码分析—Sentinel是如何动态加载配置限流的?

    Sentinel源码解析系列: 1.Sentinel源码分析-FlowRuleManager加载规则做了什么? 2. Sentinel源码分析-Sentinel是如何进行流量统计的? 3. Senti ...

  6. 7.Sentinel源码分析—Sentinel是怎么和控制台通信的?

    这里会介绍: Sentinel会使用多线程的方式实现一个类Reactor的IO模型 Sentinel会使用心跳检测来观察控制台是否正常 Sentinel源码解析系列: 1.Sentinel源码分析-F ...

  7. 阿里sentinel源码研究深入

    1. 阿里sentinel源码研究深入 1.1. 前言 昨天已经把sentinel成功部署到线上环境,可参考我上篇博文,该走的坑也都走了一遍,已经可以初步使用它的限流和降级功能,根据我目前的实践,限流 ...

  8. Sentinel 源码分析- 熔断降级原理分析

    直接从Sentinel 源码demo ExceptionRatioCircuitBreakerDemo看起 直接看他的main函数 public static void main(String[] a ...

  9. Spark RPC框架源码分析(三)Spark心跳机制分析

    一.Spark心跳概述 前面两节中介绍了Spark RPC的基本知识,以及深入剖析了Spark RPC中一些源码的实现流程. 具体可以看这里: Spark RPC框架源码分析(二)运行时序 Spark ...

随机推荐

  1. 注解@NotNull/@NotEmpty/@NotBlank

    @NotNull:不能为null,但可以为empty @NotEmpty:不能为null,而且长度必须大于0 @NotBlank:只能作用在String上,不能为null,而且调用trim()后,长度 ...

  2. Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素 - 允许重复

    381. O(1) 时间插入.删除和获取随机元素 - 允许重复 设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构. 注意: 允许出现重复元素. insert(val):向集合中插 ...

  3. Java实现 LeetCode 222 完全二叉树的节点个数

    222. 完全二叉树的节点个数 给出一个完全二叉树,求出该树的节点个数. 说明: 完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集 ...

  4. java实现第六届蓝桥杯空心菱形

    空心菱形 标题:空心菱形 小明刚刚开发了一个小程序,可以打印出任意规模的空心菱形,规模为6时,如下图: ****** ****** ***** ***** **** **** *** *** ** * ...

  5. java创建透明背景的PNG图片加自定义文字水印

    人在码上走,需求天天有.这不,今天前端让我返回一个带自定义水印的背景图片.一通google,有现成的代码,但是基本是直接在源图上添加水印,生成出来的文字样式也没有控制好,看来又只有自己造轮子了. 过程 ...

  6. 使用百度地图时,Application类的onCreate执行两次的解决方案

    应用做的匆忙,很多地方只顾实现功能,没有兼顾好性能,所以停下来重构代码优化性能,结果在打log看启动时间的时候,发现Application的onCreate执行了多次,这样导致重复初始化资源,初始化了 ...

  7. [原创][开源] SunnyUI.Net 国际化

    SunnyUI.Net, 基于 C# .Net WinForm 开源控件库.工具类库.扩展类库.多页面开发框架 Blog: https://www.cnblogs.com/yhuse Gitee: h ...

  8. 问题解决: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 ...

  9. 网络聚合Network Teaming

    team是新的聚合软件,依赖于安装包teamd,可以通过nmcli管理. team和bond的区别在于,支持hash加密,支持负载均衡,支持8块网卡,更好地支持IPV6,总之要取代bond. 1. 添 ...

  10. docker中mongdb常用操作

    一.进入 --使用本地命令行查看 docker exec -it mongos bash