001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.components.gateway;
017
018import com.jfinal.kit.LogKit;
019import io.jboot.components.http.JbootHttpRequest;
020import io.jboot.utils.HttpUtil;
021import io.jboot.utils.NamedThreadFactory;
022import io.jboot.utils.StrUtil;
023
024import java.util.Set;
025import java.util.concurrent.ScheduledThreadPoolExecutor;
026import java.util.concurrent.TimeUnit;
027
028/**
029 * @author michael yang (fuhai999@gmail.com)
030 * @Date: 2020/3/21
031 */
032public class JbootGatewayHealthChecker implements Runnable {
033
034    private static JbootGatewayHealthChecker me = new JbootGatewayHealthChecker();
035
036    public static JbootGatewayHealthChecker me() {
037        return me;
038    }
039
040
041    private ScheduledThreadPoolExecutor fixedScheduler;
042    private long fixedSchedulerInitialDelay = 10;
043    private long fixedSchedulerDelay = 30;
044
045
046    /**
047     * 开始健康检查
048     * 多次执行,只会启动一次
049     */
050    public synchronized void start() {
051        if (fixedScheduler == null) {
052            fixedScheduler = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("jboot-gateway-health-check"));
053            fixedScheduler.scheduleWithFixedDelay(this, fixedSchedulerInitialDelay, fixedSchedulerDelay, TimeUnit.SECONDS);
054        }
055    }
056
057    public void stop() {
058        fixedScheduler.shutdown();
059        fixedScheduler = null;
060    }
061
062
063    @Override
064    public void run() {
065        try {
066            doHealthCheck();
067        } catch (Exception ex) {
068            LogKit.error(ex.toString(), ex);
069        }
070    }
071
072    /**
073     * 健康检查
074     */
075    private void doHealthCheck() {
076        for (JbootGatewayConfig config : JbootGatewayManager.me().getConfigMap().values()) {
077            if (config.isEnable() && config.isUriHealthCheckEnable() && StrUtil.isNotBlank(config.getUriHealthCheckPath())) {
078                Set<String> uris = config.getUri();
079                for (String uri : uris) {
080                    String url = uri + config.getUriHealthCheckPath();
081                    if (getHttpCode(url) == 200) {
082                        config.removeUnHealthUri(uri);
083                    } else {
084                        config.addUnHealthUri(uri);
085                    }
086                }
087            }
088        }
089    }
090
091    private int getHttpCode(String url) {
092        try {
093            JbootHttpRequest req = JbootHttpRequest.create(url);
094            req.setReadBody(false);
095            return HttpUtil.handle(req).getResponseCode();
096        } catch (Exception ex) {
097            // do nothing
098            return 0;
099        }
100    }
101
102    public ScheduledThreadPoolExecutor getFixedScheduler() {
103        return fixedScheduler;
104    }
105
106    public long getFixedSchedulerInitialDelay() {
107        return fixedSchedulerInitialDelay;
108    }
109
110    public void setFixedSchedulerInitialDelay(long fixedSchedulerInitialDelay) {
111        this.fixedSchedulerInitialDelay = fixedSchedulerInitialDelay;
112    }
113
114    public long getFixedSchedulerDelay() {
115        return fixedSchedulerDelay;
116    }
117
118    public void setFixedSchedulerDelay(long fixedSchedulerDelay) {
119        this.fixedSchedulerDelay = fixedSchedulerDelay;
120    }
121}