Commit 7c217d06380b469d80474501ce3b6706215e0803
0 parents
Exists in
master
first commit
Showing
22 changed files
with
1234 additions
and
0 deletions
Show diff stats
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 | +} | ... | ... |
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 | ... | ... |
No preview for this file type
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" "$@" | ... | ... |
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 | ... | ... |
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' | ... | ... |
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 | +} | ... | ... |
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 | +} | ... | ... |
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 | +} | ... | ... |