sentinel-transport-SPI-HeartbeatSenderInitFunc

说明

我们引入以下依赖

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
     <version>1.8.6</version>
</dependency>

配置环境变量

-Dcsp.sentinel.dashboard.server=localhost:8080

则会上报到dashboard,如果关闭服务,一段时间时候就会自动剔除,判断是否失联则是根据HeartbeatSenderInitFunc在定期发送心跳的

 

通过初始化com.alibaba.csp.sentinel.init.InitExecutor#doInit 之后,

<1>

com.alibaba.csp.sentinel.init.InitExecutor#doInit

 public static void doInit() {
        //原子性set和判断是否已经初始化
        if (!initialized.compareAndSet(false, true)) {
            return;
        }
        try {
            //SPI获取InitFunc
            ServiceLoader<InitFunc> loader = ServiceLoaderUtil.getServiceLoader(InitFunc.class);
            List<OrderWrapper> initList = new ArrayList<OrderWrapper>();
            for (InitFunc initFunc : loader) {
                RecordLog.info("[InitExecutor] Found init func: " + initFunc.getClass().getCanonicalName());
                insertSorted(initList, initFunc);
            }
            for (OrderWrapper w : initList) {
                //<1-2>com.alibaba.csp.sentinel.transport.init.HeartbeatSenderInitFunc#init
                w.func.init();
                RecordLog.info(String.format("[InitExecutor] Executing %s with order %d",
                    w.func.getClass().getCanonicalName(), w.order));
            }
        } catch (Exception ex) {
            RecordLog.warn("[InitExecutor] WARN: Initialization failed", ex);
            ex.printStackTrace();
        } catch (Error error) {
            RecordLog.warn("[InitExecutor] ERROR: Initialization failed with fatal error", error);
            error.printStackTrace();
        }
    }

<1-2>

com.alibaba.csp.sentinel.transport.init.HeartbeatSenderInitFunc#init

    @Override
    public void init() {
        //这里也是通过SPI获取HeartbeatSender 我们可以自定义
        HeartbeatSender sender = HeartbeatSenderProvider.getHeartbeatSender();
        if (sender == null) {
            RecordLog.warn("[HeartbeatSenderInitFunc] WARN: No HeartbeatSender loaded");
            return;
        }

        //初始化ScheduledThreadPoolExecutor 通过他来完成定时心跳发送
        initSchedulerIfNeeded();
        //获取心跳间隔时间 我们可以通过环境变量csp.sentinel.heartbeat.interval.ms 
        long interval = retrieveInterval(sender);
        //设置到config 后去使用
        setIntervalIfNotExists(interval);
        //<1-2-1>开启心跳定时发送任务
        scheduleHeartbeatTask(sender, interval);
    }

<1-2-1->

com.alibaba.csp.sentinel.transport.init.HeartbeatSenderInitFunc#scheduleHeartbeatTask

 private void scheduleHeartbeatTask(/*@NonNull*/ final HeartbeatSender sender, /*@Valid*/ long interval) {
        pool.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try {
                    //<1-2-1-1>发送心跳
                    sender.sendHeartbeat();
                } catch (Throwable e) {
                    RecordLog.warn("[HeartbeatSender] Send heartbeat error", e);
                }
            }
        }, 5000, interval, TimeUnit.MILLISECONDS);
        RecordLog.info("[HeartbeatSenderInit] HeartbeatSender started: "
            + sender.getClass().getCanonicalName());
    }

<1-2-1-1>

 public boolean sendHeartbeat() throws Exception {
        if (TransportConfig.getRuntimePort() <= 0) {
            RecordLog.info("[SimpleHttpHeartbeatSender] Command server port not initialized, won't send heartbeat", new Object[0]);
            return false;
        } else {
            //获取dashboard地址 key=ip value=端口
            Tuple2<String, Integer> addrInfo = this.getAvailableAddress();
            if (addrInfo == null) {
                return false;
            } else {
                InetSocketAddress addr = new InetSocketAddress((String)addrInfo.r1, (Integer)addrInfo.r2);
                //获取心跳地址可以通过csp.sentinel.heartbeat.api.path指定 默认是 /registry/machine
                SimpleHttpRequest request = new SimpleHttpRequest(addr, TransportConfig.getHeartbeatApiPath());
                //构建发送参数 如:{app=sentinel-app1-demo, hostname=hdyf-liqiang2, app_type=0, port=8719, v=1.8.0, ip=10.4.1.125, version=1727578190020} ,比如我想在这里加这个服务哪些用户可以看,则可以在这里做
                request.setParams(this.heartBeat.generateCurrentMessage());

                try {
                    //http请求发送心跳
                    SimpleHttpResponse response = this.httpClient.post(request);
                    if (response.getStatusCode() == 200) {
                        return true;
                    }

                    if (this.clientErrorCode(response.getStatusCode()) || this.serverErrorCode(response.getStatusCode())) {
                        RecordLog.warn("[SimpleHttpHeartbeatSender] Failed to send heartbeat to " + addr + ", http status code: " + response.getStatusCode(), new Object[0]);
                    }
                } catch (Exception var5) {
                    RecordLog.warn("[SimpleHttpHeartbeatSender] Failed to send heartbeat to " + addr, var5);
                }

                return false;
            }
        }
    }

 

posted @ 2024-09-29 10:42  意犹未尽  阅读(8)  评论(0编辑  收藏  举报