Commit 7c217d06380b469d80474501ce3b6706215e0803

Authored by wangbin
0 parents
Exists in master

first commit

.gitignore 0 → 100644
  1 +++ a/.gitignore
... ... @@ -0,0 +1,12 @@
  1 +.project
  2 +.classpath
  3 +.settings
  4 +/resources/
  5 +/.gradle/
  6 +/bin/
  7 +/build/
  8 +/WebContent/WEB-INF/lib/
  9 +/WebContent/WEB-INF/classes/
  10 +/src/main/resources/application.properties
  11 +/tmp/
  12 +
... ...
README.md 0 → 100644
  1 +++ a/README.md
... ... @@ -0,0 +1,3 @@
  1 +### taover-心跳监控项目
  2 +
  3 +
... ...
build.gradle 0 → 100644
  1 +++ a/build.gradle
... ... @@ -0,0 +1,66 @@
  1 +/*
  2 + * This file was generated by the Gradle 'init' task.
  3 + *
  4 + * This generated file contains a sample Java Library project to get you started.
  5 + * For more details take a look at the Java Libraries chapter in the Gradle
  6 + * user guide available at https://docs.gradle.org/4.5.1/userguide/java_library_plugin.html
  7 + */
  8 +
  9 +plugins {
  10 + // Apply the java-library plugin to add support for Java Library
  11 + id 'java'
  12 + id 'eclipse'
  13 + id 'application'
  14 + id 'maven'
  15 +}
  16 +
  17 +jar.enabled = true
  18 +group = 'com.taover.heartbeat'
  19 +mainClassName = 'com.taover.heartbeat.HeartbeatManager'
  20 +
  21 +dependencies {
  22 + compile(
  23 + "com.taover:com-taover-util:1.1.116",
  24 + "javax.servlet:javax.servlet-api:4.0.1"
  25 + )
  26 +}
  27 +
  28 +repositories {
  29 + jcenter()
  30 + maven{ url 'http://repository.sonatype.org/content/groups/public/' }
  31 + maven{ url 'https://repository.jboss.org/nexus/content/groups/public/' }
  32 + maven{ url 'http://nexus.taover.com:9001/repository/maven-releases/' }
  33 +}
  34 +task sourcesJar(type: Jar, dependsOn: classes) {
  35 + classifier = 'sources'
  36 + from sourceSets.main.allSource
  37 +}
  38 +
  39 +tasks.withType(JavaCompile) {
  40 + options.encoding = "UTF-8"
  41 +}
  42 +
  43 +artifacts {
  44 + archives sourcesJar
  45 +}
  46 +
  47 +uploadArchives {
  48 + configuration = configurations.archives
  49 + repositories {
  50 + mavenDeployer {
  51 + snapshotRepository(url: MAVEN_REPO_SNAPSHOT_URL) {
  52 + authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD)
  53 + }
  54 + repository(url: MAVEN_REPO_RELEASE_URL) {
  55 + authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD)
  56 + }
  57 + pom.project {
  58 + version '1.1.1'
  59 + artifactId ARTIFACT_Id
  60 + groupId GROUP_ID
  61 + packaging TYPE
  62 + description DESCRIPTION
  63 + }
  64 + }
  65 + }
  66 +}
... ...
gradle.properties 0 → 100644
  1 +++ a/gradle.properties
... ... @@ -0,0 +1,21 @@
  1 +#Maven Repo URL
  2 +MAVEN_REPO_RELEASE_URL=http://nexus.taover.com:9001/repository/maven-releases/
  3 +MAVEN_REPO_SNAPSHOT_URL=http://nexus.taover.com:9001/repository/maven-snapshots/
  4 +
  5 +#maven GroupId
  6 +GROUP=com.taover
  7 +#nexus ossde
  8 +NEXUS_USERNAME=dev
  9 +#nexus oss
  10 +NEXUS_PASSWORD=Nexus@dev
  11 +
  12 +# groupid
  13 +GROUP_ID=com.taover
  14 +
  15 +ARTIFACT_Id=com-taover-heartbeat
  16 +
  17 +# type
  18 +TYPE=jar
  19 +
  20 +# description
  21 +DESCRIPTION=heartbeat package
0 22 \ No newline at end of file
... ...
gradle/wrapper/gradle-wrapper.jar 0 → 100644
No preview for this file type
gradle/wrapper/gradle-wrapper.properties 0 → 100644
  1 +++ a/gradle/wrapper/gradle-wrapper.properties
... ... @@ -0,0 +1,5 @@
  1 +distributionBase=GRADLE_USER_HOME
  2 +distributionPath=wrapper/dists
  3 +distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
  4 +zipStoreBase=GRADLE_USER_HOME
  5 +zipStorePath=wrapper/dists
... ...
gradlew 0 → 100644
  1 +++ a/gradlew
... ... @@ -0,0 +1,172 @@
  1 +#!/usr/bin/env sh
  2 +
  3 +##############################################################################
  4 +##
  5 +## Gradle start up script for UN*X
  6 +##
  7 +##############################################################################
  8 +
  9 +# Attempt to set APP_HOME
  10 +# Resolve links: $0 may be a link
  11 +PRG="$0"
  12 +# Need this for relative symlinks.
  13 +while [ -h "$PRG" ] ; do
  14 + ls=`ls -ld "$PRG"`
  15 + link=`expr "$ls" : '.*-> \(.*\)$'`
  16 + if expr "$link" : '/.*' > /dev/null; then
  17 + PRG="$link"
  18 + else
  19 + PRG=`dirname "$PRG"`"/$link"
  20 + fi
  21 +done
  22 +SAVED="`pwd`"
  23 +cd "`dirname \"$PRG\"`/" >/dev/null
  24 +APP_HOME="`pwd -P`"
  25 +cd "$SAVED" >/dev/null
  26 +
  27 +APP_NAME="Gradle"
  28 +APP_BASE_NAME=`basename "$0"`
  29 +
  30 +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
  31 +DEFAULT_JVM_OPTS=""
  32 +
  33 +# Use the maximum available, or set MAX_FD != -1 to use that value.
  34 +MAX_FD="maximum"
  35 +
  36 +warn () {
  37 + echo "$*"
  38 +}
  39 +
  40 +die () {
  41 + echo
  42 + echo "$*"
  43 + echo
  44 + exit 1
  45 +}
  46 +
  47 +# OS specific support (must be 'true' or 'false').
  48 +cygwin=false
  49 +msys=false
  50 +darwin=false
  51 +nonstop=false
  52 +case "`uname`" in
  53 + CYGWIN* )
  54 + cygwin=true
  55 + ;;
  56 + Darwin* )
  57 + darwin=true
  58 + ;;
  59 + MINGW* )
  60 + msys=true
  61 + ;;
  62 + NONSTOP* )
  63 + nonstop=true
  64 + ;;
  65 +esac
  66 +
  67 +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
  68 +
  69 +# Determine the Java command to use to start the JVM.
  70 +if [ -n "$JAVA_HOME" ] ; then
  71 + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
  72 + # IBM's JDK on AIX uses strange locations for the executables
  73 + JAVACMD="$JAVA_HOME/jre/sh/java"
  74 + else
  75 + JAVACMD="$JAVA_HOME/bin/java"
  76 + fi
  77 + if [ ! -x "$JAVACMD" ] ; then
  78 + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
  79 +
  80 +Please set the JAVA_HOME variable in your environment to match the
  81 +location of your Java installation."
  82 + fi
  83 +else
  84 + JAVACMD="java"
  85 + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
  86 +
  87 +Please set the JAVA_HOME variable in your environment to match the
  88 +location of your Java installation."
  89 +fi
  90 +
  91 +# Increase the maximum file descriptors if we can.
  92 +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
  93 + MAX_FD_LIMIT=`ulimit -H -n`
  94 + if [ $? -eq 0 ] ; then
  95 + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
  96 + MAX_FD="$MAX_FD_LIMIT"
  97 + fi
  98 + ulimit -n $MAX_FD
  99 + if [ $? -ne 0 ] ; then
  100 + warn "Could not set maximum file descriptor limit: $MAX_FD"
  101 + fi
  102 + else
  103 + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
  104 + fi
  105 +fi
  106 +
  107 +# For Darwin, add options to specify how the application appears in the dock
  108 +if $darwin; then
  109 + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
  110 +fi
  111 +
  112 +# For Cygwin, switch paths to Windows format before running java
  113 +if $cygwin ; then
  114 + APP_HOME=`cygpath --path --mixed "$APP_HOME"`
  115 + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
  116 + JAVACMD=`cygpath --unix "$JAVACMD"`
  117 +
  118 + # We build the pattern for arguments to be converted via cygpath
  119 + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
  120 + SEP=""
  121 + for dir in $ROOTDIRSRAW ; do
  122 + ROOTDIRS="$ROOTDIRS$SEP$dir"
  123 + SEP="|"
  124 + done
  125 + OURCYGPATTERN="(^($ROOTDIRS))"
  126 + # Add a user-defined pattern to the cygpath arguments
  127 + if [ "$GRADLE_CYGPATTERN" != "" ] ; then
  128 + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
  129 + fi
  130 + # Now convert the arguments - kludge to limit ourselves to /bin/sh
  131 + i=0
  132 + for arg in "$@" ; do
  133 + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
  134 + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
  135 +
  136 + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
  137 + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
  138 + else
  139 + eval `echo args$i`="\"$arg\""
  140 + fi
  141 + i=$((i+1))
  142 + done
  143 + case $i in
  144 + (0) set -- ;;
  145 + (1) set -- "$args0" ;;
  146 + (2) set -- "$args0" "$args1" ;;
  147 + (3) set -- "$args0" "$args1" "$args2" ;;
  148 + (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
  149 + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
  150 + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
  151 + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
  152 + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
  153 + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
  154 + esac
  155 +fi
  156 +
  157 +# Escape application args
  158 +save () {
  159 + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
  160 + echo " "
  161 +}
  162 +APP_ARGS=$(save "$@")
  163 +
  164 +# Collect all arguments for the java command, following the shell quoting and substitution rules
  165 +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
  166 +
  167 +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
  168 +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
  169 + cd "$(dirname "$0")"
  170 +fi
  171 +
  172 +exec "$JAVACMD" "$@"
... ...
gradlew.bat 0 → 100644
  1 +++ a/gradlew.bat
... ... @@ -0,0 +1,84 @@
  1 +@if "%DEBUG%" == "" @echo off
  2 +@rem ##########################################################################
  3 +@rem
  4 +@rem Gradle startup script for Windows
  5 +@rem
  6 +@rem ##########################################################################
  7 +
  8 +@rem Set local scope for the variables with windows NT shell
  9 +if "%OS%"=="Windows_NT" setlocal
  10 +
  11 +set DIRNAME=%~dp0
  12 +if "%DIRNAME%" == "" set DIRNAME=.
  13 +set APP_BASE_NAME=%~n0
  14 +set APP_HOME=%DIRNAME%
  15 +
  16 +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
  17 +set DEFAULT_JVM_OPTS=
  18 +
  19 +@rem Find java.exe
  20 +if defined JAVA_HOME goto findJavaFromJavaHome
  21 +
  22 +set JAVA_EXE=java.exe
  23 +%JAVA_EXE% -version >NUL 2>&1
  24 +if "%ERRORLEVEL%" == "0" goto init
  25 +
  26 +echo.
  27 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
  28 +echo.
  29 +echo Please set the JAVA_HOME variable in your environment to match the
  30 +echo location of your Java installation.
  31 +
  32 +goto fail
  33 +
  34 +:findJavaFromJavaHome
  35 +set JAVA_HOME=%JAVA_HOME:"=%
  36 +set JAVA_EXE=%JAVA_HOME%/bin/java.exe
  37 +
  38 +if exist "%JAVA_EXE%" goto init
  39 +
  40 +echo.
  41 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
  42 +echo.
  43 +echo Please set the JAVA_HOME variable in your environment to match the
  44 +echo location of your Java installation.
  45 +
  46 +goto fail
  47 +
  48 +:init
  49 +@rem Get command-line arguments, handling Windows variants
  50 +
  51 +if not "%OS%" == "Windows_NT" goto win9xME_args
  52 +
  53 +:win9xME_args
  54 +@rem Slurp the command line arguments.
  55 +set CMD_LINE_ARGS=
  56 +set _SKIP=2
  57 +
  58 +:win9xME_args_slurp
  59 +if "x%~1" == "x" goto execute
  60 +
  61 +set CMD_LINE_ARGS=%*
  62 +
  63 +:execute
  64 +@rem Setup the command line
  65 +
  66 +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
  67 +
  68 +@rem Execute Gradle
  69 +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
  70 +
  71 +:end
  72 +@rem End local scope for the variables with windows NT shell
  73 +if "%ERRORLEVEL%"=="0" goto mainEnd
  74 +
  75 +:fail
  76 +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
  77 +rem the _cmd.exe /c_ return code!
  78 +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
  79 +exit /b 1
  80 +
  81 +:mainEnd
  82 +if "%OS%"=="Windows_NT" endlocal
  83 +
  84 +:omega
... ...
settings.gradle 0 → 100644
  1 +++ a/settings.gradle
... ... @@ -0,0 +1,10 @@
  1 +/*
  2 + * This file was generated by the Gradle 'init' task.
  3 + *
  4 + * The settings file is used to specify which projects to include in your build.
  5 + *
  6 + * Detailed information about configuring a multi-project build in Gradle can be found
  7 + * in the user guide at https://docs.gradle.org/4.9/userguide/multi_project_builds.html
  8 + */
  9 +
  10 +rootProject.name = 'com-taover-heartbeat'
... ...
src/main/java/com/taover/heartbeat/ClientHolder.java 0 → 100644
  1 +++ a/src/main/java/com/taover/heartbeat/ClientHolder.java
... ... @@ -0,0 +1,14 @@
  1 +package com.taover.heartbeat;
  2 +
  3 +import java.util.List;
  4 +
  5 +import com.taover.heartbeat.bean.ClientInstance;
  6 +import com.taover.heartbeat.bean.ClientRequest;
  7 +
  8 +interface ClientHolder {
  9 + void registryClientInstance(ClientRequest clientRequest);
  10 +
  11 + List<ClientInstance> getClientInstanceList();
  12 +
  13 + void flushClientStatus(ClientInstance clientInstance);
  14 +}
... ...
src/main/java/com/taover/heartbeat/ClientHolderImpl.java 0 → 100644
  1 +++ a/src/main/java/com/taover/heartbeat/ClientHolderImpl.java
... ... @@ -0,0 +1,38 @@
  1 +package com.taover.heartbeat;
  2 +
  3 +import java.util.ArrayList;
  4 +import java.util.HashMap;
  5 +import java.util.List;
  6 +import java.util.Map;
  7 +
  8 +import com.taover.heartbeat.bean.ClientInstance;
  9 +import com.taover.heartbeat.bean.ClientRequest;
  10 +
  11 +public class ClientHolderImpl implements ClientHolder{
  12 + Map<String, ClientInstance> clientMap = new HashMap<String, ClientInstance>();
  13 +
  14 + @Override
  15 + public List<ClientInstance> getClientInstanceList() {
  16 + return new ArrayList<ClientInstance>(clientMap.values());
  17 + }
  18 +
  19 + @Override
  20 + public void flushClientStatus(ClientInstance clientInstance) {
  21 + clientInstance.flush();
  22 + }
  23 +
  24 + @Override
  25 + public void registryClientInstance(ClientRequest clientRequest) {
  26 + synchronized (this.clientMap) {
  27 + ClientInstance client = null;
  28 + if(clientMap.containsKey(clientRequest.getIdentity())) {
  29 + client = clientMap.get(clientRequest.getIdentity());
  30 + clientMap.put(client.getIdentity(), client);
  31 + }else {
  32 + client = new ClientInstance(clientRequest);
  33 + clientMap.put(client.getIdentity(), client);
  34 + }
  35 + client.dealClientRequest(clientRequest);
  36 + }
  37 + }
  38 +}
... ...
src/main/java/com/taover/heartbeat/HeartbeatManager.java 0 → 100644
  1 +++ a/src/main/java/com/taover/heartbeat/HeartbeatManager.java
... ... @@ -0,0 +1,57 @@
  1 +package com.taover.heartbeat;
  2 +
  3 +import java.util.List;
  4 +
  5 +import com.taover.heartbeat.bean.ClientInstance;
  6 +import com.taover.heartbeat.bean.ClientRequest;
  7 +import com.taover.heartbeat.bean.Instance;
  8 +import com.taover.heartbeat.bean.ReformInstance;
  9 +import com.taover.heartbeat.bean.ServerInstance;
  10 +
  11 +public class HeartbeatManager {
  12 + //客户端holder
  13 + private static ClientHolder clientHolder = new ClientHolderImpl();
  14 + //服务端holder
  15 + private static ServerHolder serverHolder = new ServerHolderImpl();
  16 + //通知对象
  17 + private static ReformInstance reformData = new ReformInstance();
  18 +
  19 + public static void registryClient(ClientRequest clientRequest) {
  20 + clientHolder.registryClientInstance(clientRequest);
  21 + }
  22 +
  23 + /**
  24 + * 刷新客户端信息
  25 + */
  26 + public static void flushClientStatus() {
  27 + List<ClientInstance> instances = clientHolder.getClientInstanceList();
  28 + for(ClientInstance item: instances) {
  29 + item.flush();
  30 + if(item.needReform()) {
  31 + HeartbeatManager.sendReform(item);
  32 + }
  33 + }
  34 + }
  35 +
  36 + public static void sendReform(Instance instance) {
  37 + reformData.doReform(instance);
  38 + }
  39 +
  40 + public static void sendServerHeartbeat() {
  41 + List<ServerInstance> instances = serverHolder.getServerInstanceList();
  42 + for(ServerInstance item: instances) {
  43 + item.flush();
  44 + if(item.needReform()) {
  45 + HeartbeatManager.sendReform(item);
  46 + }
  47 + }
  48 + }
  49 +
  50 + public static void registryServers(String code, String url, int fixRateSec, int maxWaitSec) throws Exception{
  51 + serverHolder.registeServer(code, url, fixRateSec, maxWaitSec);
  52 + }
  53 +
  54 + public static void setReformData(String emailTo, String weixinWxid, String mobile) {
  55 + HeartbeatManager.reformData.loadConfig(emailTo, weixinWxid, mobile);
  56 + }
  57 +}
... ...
src/main/java/com/taover/heartbeat/ServerHolder.java 0 → 100644
  1 +++ a/src/main/java/com/taover/heartbeat/ServerHolder.java
... ... @@ -0,0 +1,13 @@
  1 +package com.taover.heartbeat;
  2 +
  3 +import java.util.List;
  4 +
  5 +import com.taover.heartbeat.bean.ServerInstance;
  6 +
  7 +interface ServerHolder {
  8 + List<ServerInstance> getServerInstanceList();
  9 +
  10 + void registeServer(String code, String url, int fixRateSec, int maxWaitSec) throws Exception;
  11 +
  12 + void flushServerStatus(ServerInstance serverInstance);
  13 +}
... ...
src/main/java/com/taover/heartbeat/ServerHolderImpl.java 0 → 100644
  1 +++ a/src/main/java/com/taover/heartbeat/ServerHolderImpl.java
... ... @@ -0,0 +1,35 @@
  1 +package com.taover.heartbeat;
  2 +
  3 +import java.util.ArrayList;
  4 +import java.util.HashMap;
  5 +import java.util.List;
  6 +import java.util.Map;
  7 +
  8 +import com.taover.heartbeat.bean.ServerInstance;
  9 +
  10 +public class ServerHolderImpl implements ServerHolder {
  11 + Map<String, ServerInstance> serverMap = new HashMap<String, ServerInstance>();
  12 +
  13 + @Override
  14 + public List<ServerInstance> getServerInstanceList() {
  15 + return new ArrayList<ServerInstance>(serverMap.values());
  16 + }
  17 +
  18 + @Override
  19 + public void registeServer(String code, String url, int fixRateSec, int maxWaitSec) throws Exception {
  20 + ServerInstance server = new ServerInstance(code, url, fixRateSec, maxWaitSec);
  21 + synchronized (this.serverMap) {
  22 + if(serverMap.containsKey(server.getIdentity())) {
  23 + server = serverMap.get(server.getIdentity());
  24 + }else {
  25 + serverMap.put(server.getIdentity(), server);
  26 + }
  27 + }
  28 + server.flush();
  29 + }
  30 +
  31 + @Override
  32 + public void flushServerStatus(ServerInstance serverInstance) {
  33 + serverInstance.flush();
  34 + }
  35 +}
... ...
src/main/java/com/taover/heartbeat/adaptor/HttpHeartbeatService.java 0 → 100644
  1 +++ a/src/main/java/com/taover/heartbeat/adaptor/HttpHeartbeatService.java
... ... @@ -0,0 +1,40 @@
  1 +package com.taover.heartbeat.adaptor;
  2 +
  3 +import javax.servlet.http.HttpServletRequest;
  4 +
  5 +import com.taover.util.bean.ResultInfo;
  6 +
  7 +public interface HttpHeartbeatService {
  8 +
  9 + /**
  10 + * 处理客户端心跳请求
  11 + * @param clientRequest
  12 + * @return
  13 + */
  14 + ResultInfo registryClient(HttpServletRequest request);
  15 +
  16 + /**
  17 + * 注册服务端
  18 + * @param servers
  19 + * @param reformData
  20 + * @param fixRateSec
  21 + * @param maxWait
  22 + */
  23 + void registryServers(String code, String servers, Integer fixRateSec, Integer maxWaitSec) throws Exception;
  24 +
  25 + /**
  26 + * 刷新客户端状态
  27 + */
  28 + void flushClientStatus();
  29 +
  30 + /**
  31 + * 向服务器发送心跳
  32 + */
  33 + void sendServerHeartbeat();
  34 +
  35 + /**
  36 + * 设置通知信息
  37 + * @param reformData
  38 + */
  39 + void setReformData(String emailTo, String weixinWxid, String mobile);
  40 +}
... ...
src/main/java/com/taover/heartbeat/adaptor/HttpHeartbeatServiceImpl.java 0 → 100644
  1 +++ a/src/main/java/com/taover/heartbeat/adaptor/HttpHeartbeatServiceImpl.java
... ... @@ -0,0 +1,89 @@
  1 +package com.taover.heartbeat.adaptor;
  2 +
  3 +import javax.servlet.http.HttpServletRequest;
  4 +
  5 +import com.taover.heartbeat.HeartbeatManager;
  6 +import com.taover.heartbeat.bean.ClientRequest;
  7 +import com.taover.heartbeat.bean.Instance;
  8 +import com.taover.util.UtilLog;
  9 +import com.taover.util.bean.ResultInfo;
  10 +import com.taover.util.bean.UtilResultInfo;
  11 +
  12 +public class HttpHeartbeatServiceImpl implements HttpHeartbeatService {
  13 + public HttpHeartbeatServiceImpl() {}
  14 +
  15 + /**
  16 + * 处理客户端心跳请求
  17 + * @param clientRequest
  18 + * @return
  19 + */
  20 + @Override
  21 + public ResultInfo registryClient(HttpServletRequest request) {
  22 + try {
  23 + HeartbeatManager.registryClient(ClientRequest.createClientRequest(request));
  24 + return UtilResultInfo.getSuccess("");
  25 + }catch (Exception e) {
  26 + return UtilResultInfo.getFailure(e.getMessage());
  27 + }
  28 + }
  29 +
  30 + /**
  31 + * 刷新客户端状态
  32 + */
  33 + @Override
  34 + public void flushClientStatus() {
  35 + try {
  36 + HeartbeatManager.flushClientStatus();
  37 + }catch (Exception e) {
  38 + UtilLog.errorForException(e, this.getClass());
  39 + }
  40 + }
  41 +
  42 + /**
  43 + * 向服务器发送心跳
  44 + */
  45 + @Override
  46 + public void sendServerHeartbeat() {
  47 + try {
  48 + HeartbeatManager.sendServerHeartbeat();
  49 + }catch (Exception e) {
  50 + UtilLog.errorForException(e, this.getClass());
  51 + }
  52 + }
  53 +
  54 + @Override
  55 + public void registryServers(String code, String servers, Integer fixRateSec, Integer maxWaitSec) throws Exception{
  56 + if(servers == null || servers.trim().equals("")) {
  57 + return;
  58 + }
  59 + String[] serverSplit = servers.split(",");
  60 + if(code == null || code.trim().equals("")) {
  61 + throw new Exception("property[heartbeat.clientCode] is blank");
  62 + }
  63 + if(fixRateSec == null) {
  64 + fixRateSec = Instance.DEFAULT_FIX_RATE_SEC;
  65 + }
  66 + if(maxWaitSec == null) {
  67 + maxWaitSec = Instance.DEFAULT_MAX_WAIT_SEC;
  68 + }
  69 + for(String serverItem: serverSplit) {
  70 + if(code == null || code.trim().equals("") || !serverItem.toLowerCase().startsWith("http")) {
  71 + continue;
  72 + }
  73 + try {
  74 + HeartbeatManager.registryServers(code, serverItem, fixRateSec, maxWaitSec);
  75 + }catch (Exception e) {
  76 + UtilLog.errorForException(e, this.getClass());
  77 + }
  78 + }
  79 + }
  80 +
  81 + @Override
  82 + public void setReformData(String emailTo, String weixinWxid, String mobile) {
  83 + try {
  84 + HeartbeatManager.setReformData(emailTo, weixinWxid, mobile);
  85 + }catch (Exception e) {
  86 + UtilLog.errorForException(e, this.getClass());
  87 + }
  88 + }
  89 +}
... ...
src/main/java/com/taover/heartbeat/bean/ClientInstance.java 0 → 100644
  1 +++ a/src/main/java/com/taover/heartbeat/bean/ClientInstance.java
... ... @@ -0,0 +1,73 @@
  1 +package com.taover.heartbeat.bean;
  2 +
  3 +public class ClientInstance extends ClientRequest implements Instance{
  4 + public int DEFAULT_REFORM_MIN_ERROR_COUNT = 1;
  5 + public int DEFAULT_REFORM_MAX_ERROR_COUNT = 3;
  6 +
  7 + private long lastestServerUnixtime = System.currentTimeMillis()/1000;
  8 + private int lostClientRequestCount = 0;
  9 + private ClientRequest lastestClientRequest;
  10 +
  11 + public ClientInstance(ClientRequest clientRequest) {
  12 + super(clientRequest);
  13 + this.lastestClientRequest = clientRequest;
  14 + }
  15 +
  16 + @Override
  17 + public void flush() {
  18 + //还未收到请求,则无需刷新失败次数
  19 + if(lastestClientRequest == null) {
  20 + return;
  21 + }
  22 +
  23 + //通过服务器时间,判断是否超时未收到客户端请求
  24 + if(isLatestRequestGreateEqualFixRateSec()) {
  25 + ++this.lostClientRequestCount;
  26 + }
  27 + }
  28 +
  29 + private boolean isLatestRequestGreateEqualFixRateSec() {
  30 + return (System.currentTimeMillis()/1000 - this.lastestServerUnixtime) > this.getFixRateSec();
  31 + }
  32 +
  33 + @Override
  34 + public boolean needReform() {
  35 + return isLatestRequestGreateEqualFixRateSec() && this.lostClientRequestCount>=DEFAULT_REFORM_MIN_ERROR_COUNT && this.lostClientRequestCount<=DEFAULT_REFORM_MAX_ERROR_COUNT;
  36 + }
  37 +
  38 + public long getLastestServerUnixtime() {
  39 + return lastestServerUnixtime;
  40 + }
  41 +
  42 + public void setLastestServerUnixtime(long lastestServerUnixtime) {
  43 + this.lastestServerUnixtime = lastestServerUnixtime;
  44 + }
  45 +
  46 + public int getLostClientRequestCount() {
  47 + return lostClientRequestCount;
  48 + }
  49 +
  50 + public void setLostClientRequestCount(int lostClientRequestCount) {
  51 + this.lostClientRequestCount = lostClientRequestCount;
  52 + }
  53 +
  54 + public ClientRequest getLastestClientRequest() {
  55 + return lastestClientRequest;
  56 + }
  57 +
  58 + public void setLastestClientRequest(ClientRequest lastestClientRequest) {
  59 + this.lastestClientRequest = lastestClientRequest;
  60 + }
  61 +
  62 + public void dealClientRequest(ClientRequest clientRequest) {
  63 + if(this.getFixRateSec() != clientRequest.getFixRateSec()) {
  64 + this.setFixRateSec(clientRequest.getFixRateSec());
  65 + }
  66 + if(this.getMaxWaitSec() != clientRequest.getMaxWaitSec()) {
  67 + this.setMaxWaitSec(clientRequest.getMaxWaitSec());
  68 + }
  69 + this.setLastestClientRequest(clientRequest);
  70 + this.lastestServerUnixtime = System.currentTimeMillis()/1000;
  71 + this.lostClientRequestCount = 0;
  72 + }
  73 +}
... ...
src/main/java/com/taover/heartbeat/bean/ClientRequest.java 0 → 100644
  1 +++ a/src/main/java/com/taover/heartbeat/bean/ClientRequest.java
... ... @@ -0,0 +1,74 @@
  1 +package com.taover.heartbeat.bean;
  2 +
  3 +import javax.servlet.http.HttpServletRequest;
  4 +
  5 +public class ClientRequest {
  6 + private String code = "";
  7 + private String ip = "";
  8 + private int maxWaitSec = Instance.DEFAULT_MAX_WAIT_SEC;
  9 + private int fixRateSec = Instance.DEFAULT_FIX_RATE_SEC;
  10 + private long unixtime;
  11 +
  12 + public String getCode() {
  13 + return code;
  14 + }
  15 + public void setCode(String code) {
  16 + this.code = code;
  17 + }
  18 + public String getIp() {
  19 + return ip;
  20 + }
  21 + public void setIp(String ip) {
  22 + this.ip = ip;
  23 + }
  24 + public int getMaxWaitSec() {
  25 + return maxWaitSec;
  26 + }
  27 + public void setMaxWaitSec(int maxWaitSec) {
  28 + this.maxWaitSec = maxWaitSec;
  29 + }
  30 + public int getFixRateSec() {
  31 + return fixRateSec;
  32 + }
  33 + public void setFixRateSec(int fixRateSec) {
  34 + this.fixRateSec = fixRateSec;
  35 + }
  36 + public long getUnixtime() {
  37 + return unixtime;
  38 + }
  39 + public void setUnixtime(long unixtime) {
  40 + this.unixtime = unixtime;
  41 + }
  42 +
  43 + public ClientRequest(String code, String ip, int maxWaitSec, int fixRateSec, long unixtime) {
  44 + this.code = code;
  45 + this.ip = ip;
  46 + this.maxWaitSec = maxWaitSec;
  47 + this.fixRateSec = fixRateSec;
  48 + this.unixtime = unixtime;
  49 + }
  50 +
  51 + public ClientRequest(ClientRequest clientRequest) {
  52 + this.code = clientRequest.getCode();
  53 + this.ip = clientRequest.getIp();
  54 + this.maxWaitSec = clientRequest.getMaxWaitSec();
  55 + this.fixRateSec = clientRequest.getFixRateSec();
  56 + this.unixtime = clientRequest.getUnixtime();
  57 + }
  58 +
  59 + public static ClientRequest createClientRequest(HttpServletRequest request) {
  60 + String code = request.getParameter("code");
  61 + String maxWaitSec = request.getParameter("maxWaitSec");
  62 + String fixRateSec = request.getParameter("fixRateSec");
  63 + String unixtime = request.getParameter("unixtime");
  64 + String ip = request.getRemoteHost();
  65 + return new ClientRequest(code, ip,
  66 + maxWaitSec==null?Instance.DEFAULT_MAX_WAIT_SEC:Integer.valueOf(maxWaitSec),
  67 + fixRateSec==null?Instance.DEFAULT_FIX_RATE_SEC:Integer.valueOf(fixRateSec),
  68 + unixtime==null?System.currentTimeMillis()/1000:Long.valueOf(unixtime));
  69 + }
  70 +
  71 + public String getIdentity() {
  72 + return this.code + "@" + this.ip;
  73 + }
  74 +}
... ...
src/main/java/com/taover/heartbeat/bean/Instance.java 0 → 100644
  1 +++ a/src/main/java/com/taover/heartbeat/bean/Instance.java
... ... @@ -0,0 +1,23 @@
  1 +package com.taover.heartbeat.bean;
  2 +
  3 +public interface Instance {
  4 + public static final int DEFAULT_MAX_WAIT_SEC = -1;
  5 + public static final int DEFAULT_FIX_RATE_SEC = -1;
  6 +
  7 + /**
  8 + * 获取id字符串
  9 + * @return
  10 + */
  11 + String getIdentity();
  12 +
  13 + /**
  14 + * 是否可用
  15 + * @return
  16 + */
  17 + boolean needReform();
  18 +
  19 + /**
  20 + * 刷新状态
  21 + */
  22 + void flush();
  23 +}
... ...
src/main/java/com/taover/heartbeat/bean/ReformInstance.java 0 → 100644
  1 +++ a/src/main/java/com/taover/heartbeat/bean/ReformInstance.java
... ... @@ -0,0 +1,204 @@
  1 +package com.taover.heartbeat.bean;
  2 +
  3 +import java.text.SimpleDateFormat;
  4 +import java.util.Arrays;
  5 +import java.util.Date;
  6 +import java.util.List;
  7 +import java.util.Map;
  8 +
  9 +import com.alibaba.fastjson.JSON;
  10 +import com.alibaba.fastjson.JSONObject;
  11 +import com.taover.util.UtilEmail;
  12 +import com.taover.util.UtilLog;
  13 +import com.taover.util.UtilWeixinMsg;
  14 +
  15 +public class ReformInstance {
  16 + private List<String> emailToList;
  17 + private List<String> weixinWxidList;
  18 + private List<String> mobileList;
  19 +
  20 + public ReformInstance() {}
  21 +
  22 + public void doReform(Instance instance) {
  23 + if(instance == null) {
  24 + return;
  25 + }
  26 + if(this.emailToList != null && !this.emailToList.isEmpty()) {
  27 + this.sendEmail(instance);
  28 + }
  29 + if(this.weixinWxidList != null && !this.weixinWxidList.isEmpty()) {
  30 + this.sendWeixin(instance);
  31 + }
  32 + }
  33 +
  34 + private void sendWeixin(Instance instance) {
  35 + String weixinContent = "报警--项目可用性监控\n";
  36 + if(instance instanceof ClientInstance) {
  37 + weixinContent += this.formatWeixin((ClientInstance)instance);
  38 + }else if(instance instanceof ServerInstance) {
  39 + weixinContent += this.formatWeixin((ServerInstance)instance);
  40 + }else {
  41 + try {
  42 + weixinContent += " JSON序列化:"+JSONObject.toJSONString(instance);
  43 + }catch (Exception e) {
  44 + weixinContent += " 对象无法序列化打印,instance.toString() ==>> "+instance.toString();
  45 + }
  46 + }
  47 + try {
  48 + for(String weixinWxid: this.weixinWxidList) {
  49 + if(weixinWxid == null || weixinWxid.trim().equals("")) {
  50 + UtilWeixinMsg.sendTextMessage(weixinWxid, weixinContent);
  51 + }
  52 + }
  53 + } catch (Exception e) {
  54 + UtilLog.infoForMessage("发送微信消息失败,消息内容:"+weixinContent, this.getClass());
  55 + UtilLog.errorForException(e, this.getClass());
  56 + }
  57 + }
  58 +
  59 + private String formatWeixin(ServerInstance instance) {
  60 + String htmlContent = "";
  61 + if(instance.getLatestServerResponse() == null) {
  62 + htmlContent += " 未收到服务器响应\n";
  63 + }else {
  64 + if(instance.getLatestServerResponse().isOverdue()) {
  65 + htmlContent += " 向服务器接口["+instance.getUrl()+"]发送请求,响应超时["+instance.getMaxWaitSec()+"s],请及时确认服务器是否正常运行\n";
  66 + }else if(!instance.getLatestServerResponse().isCodeOk()) {
  67 + htmlContent += " 向服务器接口["+instance.getUrl()+"]发送请求,响应数据不正常(详细请查看邮件),请及时确认服务器是否正常运行\n";
  68 + }else {
  69 + htmlContent += " 向服务器接口["+instance.getUrl()+"]发送请求,未知异常,请及时确认服务器是否正常运行\n";
  70 + }
  71 + }
  72 + htmlContent += " 最后一次请求时间: "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(instance.getLatestRequestUnixtime()*1000));
  73 + return htmlContent;
  74 + }
  75 +
  76 + private String formatWeixin(ClientInstance instance) {
  77 + String htmlContent = " 超过"+instance.getFixRateSec()+"秒未收到请求,请确认CODE["+instance.getCode()+"]对应的客户端是否运行正常\n";
  78 + htmlContent += " 客户端最后一次请求时间: "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(instance.getUnixtime()*1000));
  79 + htmlContent += " 客户端IP:"+instance.getIp();
  80 + return htmlContent;
  81 + }
  82 +
  83 + private void sendEmail(Instance instance) {
  84 + String subject = "报警-项目可用性监控--监控ID["+instance.getIdentity()+"]";
  85 + String htmlContent = "<h2>监控ID:"+instance.getIdentity()+"</h2>";
  86 + if(instance instanceof ClientInstance) {
  87 + htmlContent += this.formatHtml((ClientInstance)instance);
  88 + }else if(instance instanceof ServerInstance) {
  89 + htmlContent += this.formatHtml((ServerInstance)instance);
  90 + }else {
  91 + try {
  92 + htmlContent += "<p>"+JSONObject.toJSONString(instance)+"</p>";
  93 + }catch (Exception e) {
  94 + htmlContent += "<span style=\"color:red;\">对象无法序列化打印,instance.toString() ==>> "+instance.toString()+"</span>";
  95 + }
  96 + }
  97 + try {
  98 + UtilEmail.sendHtmlMail(emailToList, subject, htmlContent);
  99 + } catch (Exception e) {
  100 + UtilLog.infoForMessage("发送邮件失败,消息内容:[标题:"+subject+"],[正文:"+htmlContent+"]", this.getClass());
  101 + UtilLog.errorForException(e, this.getClass());
  102 + }
  103 + }
  104 +
  105 + private String formatHtml(ServerInstance instance) {
  106 + String htmlContent = "";
  107 + htmlContent += "<h4 style=\"color:red;\">";
  108 + if(instance.getLatestServerResponse() != null) {
  109 + if(instance.getLatestServerResponse().isOverdue()) {
  110 + htmlContent += " 向服务器接口["+instance.getUrl()+"]发送请求,响应超时["+instance.getMaxWaitSec()+"s],请及时确认服务器是否正常运行";
  111 + }else if(!instance.getLatestServerResponse().isCodeOk()) {
  112 + htmlContent += " 向服务器接口["+instance.getUrl()+"]发送请求,响应数据不正常(详细请查看邮件),请及时确认服务器是否正常运行";
  113 + }else {
  114 + htmlContent += "未知异常";
  115 + }
  116 + }else {
  117 + htmlContent += "未记录最后一次响应记录";
  118 + }
  119 + htmlContent += "</h4>";
  120 + htmlContent += "<ul>";
  121 + htmlContent += "<li>CODE: "+instance.getCode()+"</li>";
  122 + htmlContent += "<li>URL: "+instance.getUrl()+"</li>";
  123 + htmlContent += "<li>请求频率: "+instance.getFixRateSec()+"秒/次</li>";
  124 + htmlContent += "<li>请求最大等待时间: "+instance.getMaxWaitSec()+"秒</li>";
  125 + htmlContent += "<li>客户端请求时间戳: "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(instance.getLatestRequestUnixtime()*1000))+"</li>";
  126 + htmlContent += "<li>最后一次收到的响应包: <span style=\"color:gray;\">"+JSON.toJSONString(instance.getLatestServerResponse())+"</span></li>";
  127 + htmlContent += "</ul>";
  128 + return htmlContent;
  129 + }
  130 +
  131 + private String formatHtml(ClientInstance instance) {
  132 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  133 + String htmlContent = "";
  134 + htmlContent += "<h4 style=\"color:red;\">";
  135 + htmlContent += "超过"+instance.getFixRateSec()+"秒未收到请求,请确认CODE["+instance.getCode()+"]对应的客户端是否运行正常<br />";
  136 + htmlContent += "客户端最后一次请求时间: "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(instance.getUnixtime()*1000));
  137 + htmlContent += "</h4>";
  138 + htmlContent += "<ul>";
  139 + htmlContent += "<li>CODE: "+instance.getCode()+"</li>";
  140 + htmlContent += "<li>IP: "+instance.getIp()+"</li>";
  141 + htmlContent += "<li>请求频率: "+instance.getFixRateSec()+"秒/次</li>";
  142 + htmlContent += "<li>请求最大等待时间: "+instance.getMaxWaitSec()+"秒</li>";
  143 + htmlContent += "<li>客户端请求时间戳: "+sdf.format(new Date(instance.getUnixtime()*1000))+"</li>";
  144 + htmlContent += "<li>服务器接收时间: "+sdf.format(new Date(instance.getLastestServerUnixtime()*1000))+"</li>";
  145 + htmlContent += "<li>最后一次收到的请求包: <span style=\"color:gray;\">"+JSON.toJSONString(instance.getLastestClientRequest())+"</span></li>";
  146 + htmlContent += "</ul>";
  147 + return htmlContent;
  148 + }
  149 +
  150 + public void loadConfig(String emailTo, String weixinWxid, String mobile) {
  151 + if(strNotBlank(emailTo)) {
  152 + this.emailToList = Arrays.asList(emailTo.split(","));
  153 + }
  154 + if(strNotBlank(weixinWxid)) {
  155 + this.weixinWxidList = Arrays.asList(weixinWxid.split(","));
  156 + }
  157 + if(strNotBlank(mobile)) {
  158 + this.mobileList = Arrays.asList(mobile.split(","));
  159 + }
  160 + }
  161 +
  162 + public void loadConfig(Map<String, String> data) {
  163 + Object emailTo = data.get("emailTo");
  164 + if(emailTo != null && strNotBlank(emailTo.toString())) {
  165 + this.emailToList = Arrays.asList(emailTo.toString().split(","));
  166 + }
  167 + Object weixinWxid = data.get("weixinWxid");
  168 + if(weixinWxid != null && strNotBlank(weixinWxid.toString())) {
  169 + this.weixinWxidList = Arrays.asList(weixinWxid.toString().split(","));
  170 + }
  171 + Object mobile = data.get("mobile");
  172 + if(mobile != null && strNotBlank(mobile.toString())) {
  173 + this.mobileList = Arrays.asList(mobile.toString().split(","));
  174 + }
  175 + }
  176 +
  177 + private boolean strNotBlank(String data) {
  178 + return !(data == null || data.trim().equals(""));
  179 + }
  180 +
  181 + public List<String> getEmailToList() {
  182 + return emailToList;
  183 + }
  184 +
  185 + public void setEmailToList(List<String> emailToList) {
  186 + this.emailToList = emailToList;
  187 + }
  188 +
  189 + public List<String> getWeixinWxidList() {
  190 + return weixinWxidList;
  191 + }
  192 +
  193 + public void setWeixinWxidList(List<String> weixinWxidList) {
  194 + this.weixinWxidList = weixinWxidList;
  195 + }
  196 +
  197 + public List<String> getMobileList() {
  198 + return mobileList;
  199 + }
  200 +
  201 + public void setMobileList(List<String> mobileList) {
  202 + this.mobileList = mobileList;
  203 + }
  204 +}
... ...
src/main/java/com/taover/heartbeat/bean/ServerInstance.java 0 → 100644
  1 +++ a/src/main/java/com/taover/heartbeat/bean/ServerInstance.java
... ... @@ -0,0 +1,128 @@
  1 +package com.taover.heartbeat.bean;
  2 +
  3 +import java.net.SocketTimeoutException;
  4 +
  5 +import com.taover.util.UtilHttpByOkHttp;
  6 +
  7 +public class ServerInstance implements Instance {
  8 + public int DEFAULT_REFORM_MIN_ERROR_COUNT = 1;
  9 + public int DEFAULT_REFORM_MAX_ERROR_COUNT = 3;
  10 +
  11 + private String code;
  12 + private String url;
  13 + private int fixRateSec;
  14 + private int maxWaitSec;
  15 + private long latestRequestUnixtime;
  16 + private ServerResponse latestServerResponse;
  17 + private int errorServerResponseCount;
  18 +
  19 + public ServerInstance(String code, String url, int fixRateSec, int maxWaitSec) throws Exception {
  20 + super();
  21 + if(fixRateSec < 60) {
  22 + throw new Exception("固定时间间隔不允许小于60s");
  23 + }
  24 +
  25 + this.code = code;
  26 + this.url = url;
  27 + this.fixRateSec = fixRateSec;
  28 + this.maxWaitSec = maxWaitSec;
  29 + }
  30 +
  31 + @Override
  32 + public void flush() {
  33 + //如果小于设置的发送时间间隔,则不发送请求
  34 + if(!this.isLatestRequestGreateEqualFixRateSec()) {
  35 + return;
  36 + }
  37 + this.latestRequestUnixtime = System.currentTimeMillis()/1000;
  38 + try {
  39 + this.latestServerResponse = ServerResponse.createByJSONString(UtilHttpByOkHttp.sendGet(this.url + this.getUrlParams(), null, maxWaitSec));
  40 + if(this.latestServerResponse.isCodeOk()) {
  41 + this.errorServerResponseCount = 0;
  42 + }
  43 + } catch(SocketTimeoutException timeError) {
  44 + this.latestServerResponse = ServerResponse.createOverdue();
  45 + } catch (Exception e) {
  46 + this.latestServerResponse = ServerResponse.createException(e);
  47 + }
  48 + if(this.latestServerResponse.isOverdue() || !this.latestServerResponse.isCodeOk()) {
  49 + ++this.errorServerResponseCount;
  50 + }
  51 + }
  52 +
  53 + private String getUrlParams() {
  54 + return "?code="+this.code+"&fixRateSec="+this.fixRateSec+"&maxWaitSec="+this.maxWaitSec+"&unixtime="+(System.currentTimeMillis()/1000);
  55 + }
  56 +
  57 + private boolean isLatestRequestGreateEqualFixRateSec() {
  58 + return (System.currentTimeMillis()/1000 - this.latestRequestUnixtime) >= this.fixRateSec;
  59 + }
  60 +
  61 + @Override
  62 + public String getIdentity() {
  63 + return this.code + "@" + this.url;
  64 + }
  65 +
  66 + @Override
  67 + public boolean needReform() {
  68 + return this.isLatestRequestGreateEqualFixRateSec()
  69 + && this.errorServerResponseCount>=DEFAULT_REFORM_MIN_ERROR_COUNT
  70 + && this.errorServerResponseCount<=DEFAULT_REFORM_MAX_ERROR_COUNT;
  71 + }
  72 +
  73 + public String getCode() {
  74 + return code;
  75 + }
  76 +
  77 + public void setCode(String code) {
  78 + this.code = code;
  79 + }
  80 +
  81 + public String getUrl() {
  82 + return url;
  83 + }
  84 +
  85 + public void setUrl(String url) {
  86 + this.url = url;
  87 + }
  88 +
  89 + public int getFixRateSec() {
  90 + return fixRateSec;
  91 + }
  92 +
  93 + public void setFixRateSec(int fixRateSec) {
  94 + this.fixRateSec = fixRateSec;
  95 + }
  96 +
  97 + public int getMaxWaitSec() {
  98 + return maxWaitSec;
  99 + }
  100 +
  101 + public void setMaxWaitSec(int maxWaitSec) {
  102 + this.maxWaitSec = maxWaitSec;
  103 + }
  104 +
  105 + public long getLatestRequestUnixtime() {
  106 + return latestRequestUnixtime;
  107 + }
  108 +
  109 + public void setLatestRequestUnixtime(long latestRequestUnixtime) {
  110 + this.latestRequestUnixtime = latestRequestUnixtime;
  111 + }
  112 +
  113 + public ServerResponse getLatestServerResponse() {
  114 + return latestServerResponse;
  115 + }
  116 +
  117 + public void setLatestServerResponse(ServerResponse latestServerResponse) {
  118 + this.latestServerResponse = latestServerResponse;
  119 + }
  120 +
  121 + public int getLostServerResponseCount() {
  122 + return errorServerResponseCount;
  123 + }
  124 +
  125 + public void setLostServerResponseCount(int lostServerResponseCount) {
  126 + this.errorServerResponseCount = lostServerResponseCount;
  127 + }
  128 +}
... ...
src/main/java/com/taover/heartbeat/bean/ServerResponse.java 0 → 100644
  1 +++ a/src/main/java/com/taover/heartbeat/bean/ServerResponse.java
... ... @@ -0,0 +1,73 @@
  1 +package com.taover.heartbeat.bean;
  2 +
  3 +import org.apache.commons.lang.StringUtils;
  4 +
  5 +import com.alibaba.fastjson.JSONObject;
  6 +
  7 +public class ServerResponse {
  8 + public static String RESPONSE_CODE_OK = "ok";
  9 +
  10 + private boolean isOverdue;
  11 + private boolean isCodeOk;
  12 + private String responseContent;
  13 + private Exception exception;
  14 +
  15 + private ServerResponse(boolean isOverdue, boolean isCodeOk, String responseContent, Exception e) {
  16 + super();
  17 + this.isOverdue = isOverdue;
  18 + this.isCodeOk = isCodeOk;
  19 + this.responseContent = responseContent;
  20 + this.exception = e;
  21 + }
  22 +
  23 + public boolean isOverdue() {
  24 + return isOverdue;
  25 + }
  26 + public void setOverdue(boolean isOverdue) {
  27 + this.isOverdue = isOverdue;
  28 + }
  29 + public boolean isCodeOk() {
  30 + return isCodeOk;
  31 + }
  32 + public void setCodeOk(boolean isCodeOk) {
  33 + this.isCodeOk = isCodeOk;
  34 + }
  35 + public String getResponseContent() {
  36 + return responseContent;
  37 + }
  38 + public void setResponseContent(String responseContent) {
  39 + this.responseContent = responseContent;
  40 + }
  41 + public Exception getException() {
  42 + return exception;
  43 + }
  44 + public void setException(Exception exception) {
  45 + this.exception = exception;
  46 + }
  47 +
  48 + public static ServerResponse createByJSONString(String response) {
  49 + if(StringUtils.isBlank(response)) {
  50 + return new ServerResponse(false, false, response, null);
  51 + }else {
  52 + try {
  53 + JSONObject data = JSONObject.parseObject(response);
  54 + String code = data.getString("code");
  55 + if(RESPONSE_CODE_OK.equals(code.toLowerCase())) {
  56 + return new ServerResponse(false, true, response, null);
  57 + }else {
  58 + return new ServerResponse(false, false, response, null);
  59 + }
  60 + }catch (Exception e) {
  61 + return new ServerResponse(false, false, response, e);
  62 + }
  63 + }
  64 + }
  65 +
  66 + public static ServerResponse createOverdue() {
  67 + return new ServerResponse(false, false, "", null);
  68 + }
  69 +
  70 + public static ServerResponse createException(Exception e) {
  71 + return new ServerResponse(false, false, "", e);
  72 + }
  73 +}
... ...