├── .gitignore
├── LICENSE
├── README.md
├── http-simulator
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── README.md
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ ├── META-INF
│ │ │ └── MANIFEST.MF
│ │ └── io
│ │ │ └── spring2go
│ │ │ └── promdemo
│ │ │ └── httpsimulator
│ │ │ ├── ActivitySimulator.java
│ │ │ ├── HttpSimulatorApplication.java
│ │ │ ├── SimulatorOpts.java
│ │ │ └── SpikeMode.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── io
│ └── spring2go
│ └── promdemo
│ └── httpsimulator
│ └── HttpSimulatorApplicationTests.java
├── lab01
└── README.md
├── lab02
└── README.md
├── lab03
└── README.md
├── lab04
├── README.md
├── instrumentation-example
│ ├── .gitignore
│ ├── .mvn
│ │ └── wrapper
│ │ │ ├── maven-wrapper.jar
│ │ │ └── maven-wrapper.properties
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ ├── META-INF
│ │ │ └── MANIFEST.MF
│ │ └── io
│ │ │ └── spring2go
│ │ │ └── promdemo
│ │ │ └── instrument
│ │ │ ├── InstrumentApplication.java
│ │ │ ├── Job.java
│ │ │ ├── JobQueue.java
│ │ │ ├── Worker.java
│ │ │ └── WorkerManager.java
│ │ └── resources
│ │ └── application.properties
└── queueUpJobs.sh
├── lab05
└── README.md
├── lab06
├── README.md
└── actuatordemo
│ ├── .gitignore
│ ├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ ├── META-INF
│ │ │ └── MANIFEST.MF
│ │ └── io
│ │ │ └── spring2go
│ │ │ └── promdemo
│ │ │ └── actuatordemo
│ │ │ └── ActuatordemoApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── io
│ └── spring2go
│ └── promdemo
│ └── actuatordemo
│ └── ActuatordemoApplicationTests.java
└── ppt
└── 微服务监控告警Prometheus架构和实践.pdf
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 |
25 | target/
26 | !.mvn/wrapper/maven-wrapper.jar
27 |
28 | ### STS ###
29 | .classpath
30 | .project
31 | .settings
32 | workspace
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 spring2go.com
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # prom_lab
2 | 微服务监控告警Prometheus实验,极客时间微服务架构实践课程
3 |
4 | # 课程ppt
5 | 1. [微服务监控告警Prometheus架构和实践](ppt/微服务监控告警Prometheus架构和实践.pdf)
6 |
7 | # 实验软件需求
8 | 1. [JDK 1.8+](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)
9 | 2. [Git for Windows](https://gitforwindows.org/)
10 | 3. Eclipse STS 3.9.5下载1[网盘](https://pan.baidu.com/s/1xqy4G_r9N24WODBBuGlIog) 下载2[国外](https://spring.io/tools)
11 | 4. [Postman](https://www.getpostman.com/)
12 | 5. [Prometheus 2.4.3 for Windows](https://github.com/prometheus/prometheus/releases/download/v2.4.3/prometheus-2.4.3.windows-amd64.tar.gz)
13 | 6. [Grafana 5.3.2 for Windows](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.3.2.windows-amd64.zip)
14 | 7. [Alertmanager 0.15.2 for Windows](https://github.com/prometheus/alertmanager/releases/download/v0.15.2/alertmanager-0.15.2.windows-amd64.tar.gz)
15 |
16 | # 实验目录
17 | 1. [lab01](lab01)~Prometheus起步查询实验
18 | 2. [lab02](lab02)~Prometheus+Grafana展示实验
19 | 3. [lab03](lab03)~Prometheus+Alertmanager告警实验
20 | 4. [lab04](lab04)~Java应用埋点和监控实验
21 | 2. [lab05](lab05)~NodeExporter系统监控实验
22 | 3. [lab06](lab06)~Spring Cloud Actuator监控实验
23 |
24 | # 注意
25 | 1. 所有实验仅供学习参考,不是生产级
26 | 2. 实验和ppt采用[Mit license](LICENSE)
27 |
28 | # 极客时间课程
29 |
30 | 《微服务架构实战160讲》
31 |
32 | 
33 |
--------------------------------------------------------------------------------
/http-simulator/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/http-simulator/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geektime-geekbang/prom_lab/0cdb3794ce56a45ab84467fd31efb559737d708d/http-simulator/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/http-simulator/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip
2 |
--------------------------------------------------------------------------------
/http-simulator/README.md:
--------------------------------------------------------------------------------
1 | # Prometheus HTTP Metrics Simulator
2 |
3 | 模拟一个简单的HTTP微服务,生成Prometheus Metrics,可以Spring Boot方式运行
4 |
5 | ### Metrics
6 |
7 | 运行时访问端点:
8 | ```
9 | http://SERVICE_URL:8080/prometheus
10 | ```
11 |
12 | 包括:
13 | * `http_requests_total`:请求计数器,`endpoint`和`status`为label
14 | * `http_request_duration_milliseconds`:请求延迟分布(histogram)
15 |
16 | ### 运行时options
17 |
18 | #### Spike Mode
19 |
20 | 在Spike模式下,请求数会乘以一个因子(5~15),延迟加倍
21 |
22 | Spike模式可以是`on`, `off`或者`random`, 改变方式:
23 |
24 | ```
25 | # ON
26 | curl -X POST http://SERVICE_URL:8080/spike/on
27 |
28 | # OFF
29 | curl -X POST http://SERVICE_URL:8080/spike/off
30 |
31 | # RANDOM
32 | curl -X POST http://SERVICE_URL:8080/spike/random
33 |
34 | ```
35 |
36 | #### Error rate
37 |
38 | 缺省错误率1%,可以调整(0~100),方法:
39 |
40 | ```
41 | # Setting error to 50%
42 | curl -X POST http://SERVICE_URL:8080/error_rate/50
43 |
44 | ```
45 |
46 | #### 其它参数
47 |
48 | 配置在`application.properties`中
49 |
50 | ```
51 | opts.endpoints=/login, /login, /login, /login, /login, /login, /login, /users, /users, /users, /users/{id}, /register, /register, /logout, /logout, /logout, /logout
52 | opts.request_rate=1000
53 | opts.request_rate_uncertainty=70
54 | opts.latency_min=10
55 | opts.latency_p50=25
56 | opts.latency_p90=150
57 | opts.latency_p99=750
58 | opts.latency_max=10000
59 | opts.latency_uncertainty=70
60 |
61 | opts.error_rate=1
62 | opts.spike_start_chance=5
63 | opts.spike_end_chance=30
64 | ```
65 |
66 |
67 | 运行时校验端点:
68 | ```
69 | http://SERVICE_URL:8080/opts
70 | ```
71 |
72 | ### 参考
73 |
74 | https://github.com/PierreVincent/prom-http-simulator
75 |
76 |
--------------------------------------------------------------------------------
/http-simulator/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Migwn, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | # TODO classpath?
118 | fi
119 |
120 | if [ -z "$JAVA_HOME" ]; then
121 | javaExecutable="`which javac`"
122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
123 | # readlink(1) is not available as standard on Solaris 10.
124 | readLink=`which readlink`
125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
126 | if $darwin ; then
127 | javaHome="`dirname \"$javaExecutable\"`"
128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
129 | else
130 | javaExecutable="`readlink -f \"$javaExecutable\"`"
131 | fi
132 | javaHome="`dirname \"$javaExecutable\"`"
133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
134 | JAVA_HOME="$javaHome"
135 | export JAVA_HOME
136 | fi
137 | fi
138 | fi
139 |
140 | if [ -z "$JAVACMD" ] ; then
141 | if [ -n "$JAVA_HOME" ] ; then
142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
143 | # IBM's JDK on AIX uses strange locations for the executables
144 | JAVACMD="$JAVA_HOME/jre/sh/java"
145 | else
146 | JAVACMD="$JAVA_HOME/bin/java"
147 | fi
148 | else
149 | JAVACMD="`which java`"
150 | fi
151 | fi
152 |
153 | if [ ! -x "$JAVACMD" ] ; then
154 | echo "Error: JAVA_HOME is not defined correctly." >&2
155 | echo " We cannot execute $JAVACMD" >&2
156 | exit 1
157 | fi
158 |
159 | if [ -z "$JAVA_HOME" ] ; then
160 | echo "Warning: JAVA_HOME environment variable is not set."
161 | fi
162 |
163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
164 |
165 | # traverses directory structure from process work directory to filesystem root
166 | # first directory with .mvn subdirectory is considered project base directory
167 | find_maven_basedir() {
168 |
169 | if [ -z "$1" ]
170 | then
171 | echo "Path not specified to find_maven_basedir"
172 | return 1
173 | fi
174 |
175 | basedir="$1"
176 | wdir="$1"
177 | while [ "$wdir" != '/' ] ; do
178 | if [ -d "$wdir"/.mvn ] ; then
179 | basedir=$wdir
180 | break
181 | fi
182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
183 | if [ -d "${wdir}" ]; then
184 | wdir=`cd "$wdir/.."; pwd`
185 | fi
186 | # end of workaround
187 | done
188 | echo "${basedir}"
189 | }
190 |
191 | # concatenates all lines of a file
192 | concat_lines() {
193 | if [ -f "$1" ]; then
194 | echo "$(tr -s '\n' ' ' < "$1")"
195 | fi
196 | }
197 |
198 | BASE_DIR=`find_maven_basedir "$(pwd)"`
199 | if [ -z "$BASE_DIR" ]; then
200 | exit 1;
201 | fi
202 |
203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
204 | echo $MAVEN_PROJECTBASEDIR
205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
206 |
207 | # For Cygwin, switch paths to Windows format before running java
208 | if $cygwin; then
209 | [ -n "$M2_HOME" ] &&
210 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
211 | [ -n "$JAVA_HOME" ] &&
212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
213 | [ -n "$CLASSPATH" ] &&
214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
215 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
217 | fi
218 |
219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
220 |
221 | exec "$JAVACMD" \
222 | $MAVEN_OPTS \
223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
226 |
--------------------------------------------------------------------------------
/http-simulator/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/http-simulator/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | io.spring2go.promdemo
7 | http-simulator
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | http-simulator
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 1.5.17.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-web
31 |
32 |
33 |
34 |
35 | io.prometheus
36 | simpleclient_spring_boot
37 | 0.5.0
38 |
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-starter-test
43 | test
44 |
45 |
46 |
47 |
48 |
49 |
50 | org.springframework.boot
51 | spring-boot-maven-plugin
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/http-simulator/src/main/java/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Class-Path:
3 |
4 |
--------------------------------------------------------------------------------
/http-simulator/src/main/java/io/spring2go/promdemo/httpsimulator/ActivitySimulator.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.promdemo.httpsimulator;
2 |
3 | import java.util.Random;
4 |
5 | import io.prometheus.client.Counter;
6 | import io.prometheus.client.Histogram;
7 |
8 | public class ActivitySimulator implements Runnable {
9 |
10 | private SimulatorOpts opts;
11 |
12 | private Random rand = new Random();
13 |
14 | private boolean spikeMode = false;
15 |
16 | private volatile boolean shutdown = false;
17 |
18 | private final Counter httpRequestsTotal = Counter.build()
19 | .name("http_requests_total")
20 | .help("Total number of http requests by response status code")
21 | .labelNames("endpoint", "status")
22 | .register();
23 |
24 | private final Histogram httpRequestDurationMs = Histogram.build()
25 | .name("http_request_duration_milliseconds")
26 | .help("Http request latency histogram")
27 | .exponentialBuckets(25, 2, 7)
28 | .labelNames("endpoint", "status")
29 | .register();
30 |
31 | public ActivitySimulator(SimulatorOpts opts) {
32 | this.opts = opts;
33 | System.out.println(opts);
34 | }
35 |
36 | public void shutdown() {
37 | this.shutdown = true;
38 | }
39 |
40 | public void updateOpts(SimulatorOpts opts) {
41 | this.opts = opts;
42 | }
43 |
44 | public boolean setSpikeMode(String mode) {
45 | boolean result = true;
46 | switch (mode) {
47 | case "on":
48 | opts.setSpikeMode(SpikeMode.ON);
49 | System.out.println("Spike mode is set to " + mode);
50 | break;
51 | case "off":
52 | opts.setSpikeMode(SpikeMode.OFF);
53 | System.out.println("Spike mode is set to " + mode);
54 | break;
55 | case "random":
56 | opts.setSpikeMode(SpikeMode.RANDOM);
57 | System.out.println("Spike mode is set to " + mode);
58 | break;
59 | default:
60 | result = false;
61 | System.out.println("Can't recognize spike mode " + mode);
62 | }
63 | return result;
64 | }
65 |
66 | public void setErrorRate(int rate) {
67 | if (rate > 100) {
68 | rate = 100;
69 | }
70 | if (rate < 0) {
71 | rate = 0;
72 | }
73 | opts.setErrorRate(rate);
74 | System.out.println("Error rate is set to " + rate);
75 | }
76 |
77 | public SimulatorOpts getOpts() {
78 | return this.opts;
79 | }
80 |
81 | public void simulateActivity() {
82 | int requestRate = this.opts.getRequestRate();
83 | if (this.giveSpikeMode()) {
84 | requestRate *= (5 + this.rand.nextInt(10));
85 | }
86 |
87 | int nbRequests = this.giveWithUncertainty(requestRate, this.opts.getRequestRateUncertainty());
88 | for (int i = 0; i < nbRequests; i++) {
89 | String statusCode = this.giveStatusCode();
90 | String endpoint = this.giveEndpoint();
91 | this.httpRequestsTotal.labels(endpoint, statusCode).inc();
92 | int latency = this.giveLatency(statusCode);
93 | if (this.spikeMode) {
94 | latency *= 2;
95 | }
96 | this.httpRequestDurationMs.labels(endpoint, statusCode).observe(latency);
97 | }
98 | }
99 |
100 | public boolean giveSpikeMode() {
101 | switch (this.opts.getSpikeMode()) {
102 | case ON:
103 | this.spikeMode = true;
104 | break;
105 | case OFF:
106 | this.spikeMode = false;
107 | break;
108 | case RANDOM:
109 | int n = rand.nextInt(100);
110 | if (!this.spikeMode && n < this.opts.getSpikeStartChance()) {
111 | this.spikeMode = true;
112 | } else if (this.spikeMode && n < this.opts.getSpikeEndChance()) {
113 | this.spikeMode = false;
114 | }
115 | break;
116 | }
117 |
118 | return this.spikeMode;
119 | }
120 |
121 | public int giveWithUncertainty(int n, int u) {
122 | int delta = this.rand.nextInt(n * u / 50) - (n * u / 100);
123 | return n + delta;
124 | }
125 |
126 | public String giveStatusCode() {
127 | if (this.rand.nextInt(100) < this.opts.getErrorRate()) {
128 | return "500";
129 | } else {
130 | return "200";
131 | }
132 | }
133 |
134 | public String giveEndpoint() {
135 | int n = this.rand.nextInt(this.opts.getEndopints().length);
136 | return this.opts.getEndopints()[n];
137 | }
138 |
139 | public int giveLatency(String statusCode) {
140 | if (!"200".equals(statusCode)) {
141 | return 5 + this.rand.nextInt(50);
142 | }
143 |
144 | int p = this.rand.nextInt(100);
145 |
146 | if (p < 50) {
147 | return this.giveWithUncertainty(this.opts.getLatencyMin() + this.rand.nextInt(this.opts.getLatencyP50() - this.opts.getLatencyMin()), this.opts.getLatencyUncertainty());
148 | }
149 | if (p < 90) {
150 | return this.giveWithUncertainty(this.opts.getLatencyP50() + this.rand.nextInt(this.opts.getLatencyP90() - this.opts.getLatencyP50()), this.opts.getLatencyUncertainty());
151 | }
152 | if (p < 99) {
153 | return this.giveWithUncertainty(this.opts.getLatencyP90() + this.rand.nextInt(this.opts.getLatencyP99() - this.opts.getLatencyP90()), this.opts.getLatencyUncertainty());
154 | }
155 |
156 | return this.giveWithUncertainty(this.opts.getLatencyP99() + this.rand.nextInt(this.opts.getLatencyMax() - this.opts.getLatencyP99()), this.opts.getLatencyUncertainty());
157 | }
158 |
159 | @Override
160 | public void run() {
161 | while(!shutdown) {
162 | System.out.println("Simulator is running...");
163 | this.simulateActivity();
164 | try {
165 | Thread.sleep(1000);
166 | } catch (InterruptedException e) {
167 | // TODO Auto-generated catch block
168 | e.printStackTrace();
169 | }
170 | }
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/http-simulator/src/main/java/io/spring2go/promdemo/httpsimulator/HttpSimulatorApplication.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.promdemo.httpsimulator;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.CommandLineRunner;
5 | import org.springframework.boot.SpringApplication;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.context.ApplicationListener;
8 | import org.springframework.context.annotation.Bean;
9 | import org.springframework.context.event.ContextClosedEvent;
10 | import org.springframework.core.task.SimpleAsyncTaskExecutor;
11 | import org.springframework.core.task.TaskExecutor;
12 | import org.springframework.stereotype.Controller;
13 | import org.springframework.web.bind.annotation.PathVariable;
14 | import org.springframework.web.bind.annotation.RequestMapping;
15 | import org.springframework.web.bind.annotation.RequestMethod;
16 | import org.springframework.web.bind.annotation.ResponseBody;
17 |
18 | import io.prometheus.client.spring.boot.EnablePrometheusEndpoint;
19 |
20 | @Controller
21 | @SpringBootApplication
22 | @EnablePrometheusEndpoint
23 | public class HttpSimulatorApplication implements ApplicationListener {
24 |
25 | @Autowired
26 | private SimulatorOpts opts;
27 |
28 | private ActivitySimulator simulator;
29 |
30 | public static void main(String[] args) {
31 |
32 | SpringApplication.run(HttpSimulatorApplication.class, args);
33 | }
34 |
35 | @RequestMapping(value = "/opts")
36 | public @ResponseBody String getOps() {
37 | return opts.toString();
38 | }
39 |
40 | @RequestMapping(value = "/spike/{mode}", method = RequestMethod.POST)
41 | public @ResponseBody String setSpikeMode(@PathVariable("mode") String mode) {
42 | boolean result = simulator.setSpikeMode(mode);
43 | if (result) {
44 | return "ok";
45 | } else {
46 | return "wrong spike mode " + mode;
47 | }
48 | }
49 |
50 | @RequestMapping(value = "error_rate/{error_rate}", method = RequestMethod.POST)
51 | public @ResponseBody String setErrorRate(@PathVariable("error_rate") int errorRate) {
52 | simulator.setErrorRate(errorRate);
53 | return "ok";
54 | }
55 |
56 | @Bean
57 | public TaskExecutor taskExecutor() {
58 | return new SimpleAsyncTaskExecutor();
59 | }
60 |
61 | @Bean
62 | public CommandLineRunner schedulingRunner(TaskExecutor executor) {
63 | return new CommandLineRunner() {
64 | public void run(String... args) throws Exception {
65 | simulator = new ActivitySimulator(opts);
66 | executor.execute(simulator);
67 | System.out.println("Simulator thread started...");
68 | }
69 | };
70 | }
71 |
72 | @Override
73 | public void onApplicationEvent(ContextClosedEvent event) {
74 | simulator.shutdown();
75 | System.out.println("Simulator shutdown...");
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/http-simulator/src/main/java/io/spring2go/promdemo/httpsimulator/SimulatorOpts.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.promdemo.httpsimulator;
2 |
3 | import java.util.Arrays;
4 |
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.context.annotation.Configuration;
7 |
8 | import com.fasterxml.jackson.annotation.JsonAutoDetect;
9 |
10 | @Configuration
11 | @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
12 | public class SimulatorOpts {
13 |
14 | // Endpoints, Weighted map of endpoints to simulate
15 | @Value("${opts.endpoints}")
16 | private String[] endopints;
17 |
18 | // RequestRate, requests per second
19 | @Value("${opts.request_rate}")
20 | private int requestRate;
21 |
22 | // RequestRateUncertainty, Percentage of uncertainty when generating requests (+/-)
23 | @Value("${opts.request_rate_uncertainty}")
24 | private int requestRateUncertainty;
25 |
26 | // LatencyMin in milliseconds
27 | @Value("${opts.latency_min}")
28 | private int latencyMin;
29 |
30 | // LatencyP50 in milliseconds
31 | @Value("${opts.latency_p50}")
32 | private int latencyP50;
33 |
34 | // LatencyP90 in milliseconds
35 | @Value("${opts.latency_p90}")
36 | private int latencyP90;
37 |
38 | // LatencyP99 in milliseconds
39 | @Value("${opts.latency_p99}")
40 | private int latencyP99;
41 |
42 | // LatencyMax in milliseconds
43 | @Value("${opts.latency_max}")
44 | private int latencyMax;
45 |
46 | // LatencyUncertainty, Percentage of uncertainty when generating latency (+/-)
47 | @Value("${opts.latency_uncertainty}")
48 | private int latencyUncertainty;
49 |
50 | // ErrorRate, Percentage of chance of requests causing 500
51 | @Value("${opts.error_rate}")
52 | private int errorRate;
53 |
54 | // SpikeStartChance, Percentage of chance of entering spike mode
55 | @Value("${opts.spike_start_chance}")
56 | private int spikeStartChance;
57 |
58 | // SpikeStartChance, Percentage of chance of exiting spike mode
59 | @Value("${opts.spike_end_chance}")
60 | private int spikeEndChance;
61 |
62 | // SpikeModeStatus ON/OFF/RANDOM
63 | private SpikeMode spikeMode = SpikeMode.OFF;
64 |
65 | public String[] getEndopints() {
66 | return endopints;
67 | }
68 |
69 | public void setEndopints(String[] endopints) {
70 | this.endopints = endopints;
71 | }
72 |
73 | public int getRequestRate() {
74 | return requestRate;
75 | }
76 |
77 | public void setRequestRate(int requestRate) {
78 | this.requestRate = requestRate;
79 | }
80 |
81 | public int getRequestRateUncertainty() {
82 | return requestRateUncertainty;
83 | }
84 |
85 | public void setRequestRateUncertainty(int requestRateUncertainty) {
86 | this.requestRateUncertainty = requestRateUncertainty;
87 | }
88 |
89 | public int getLatencyMin() {
90 | return latencyMin;
91 | }
92 |
93 | public void setLatencyMin(int latencyMin) {
94 | this.latencyMin = latencyMin;
95 | }
96 |
97 | public int getLatencyP50() {
98 | return latencyP50;
99 | }
100 |
101 | public void setLatencyP50(int latencyP50) {
102 | this.latencyP50 = latencyP50;
103 | }
104 |
105 | public int getLatencyP90() {
106 | return latencyP90;
107 | }
108 |
109 | public void setLatencyP90(int latencyP90) {
110 | this.latencyP90 = latencyP90;
111 | }
112 |
113 | public int getLatencyP99() {
114 | return latencyP99;
115 | }
116 |
117 | public void setLatencyP99(int latencyP99) {
118 | this.latencyP99 = latencyP99;
119 | }
120 |
121 | public int getLatencyMax() {
122 | return latencyMax;
123 | }
124 |
125 | public void setLatencyMax(int latencyMax) {
126 | this.latencyMax = latencyMax;
127 | }
128 |
129 | public int getLatencyUncertainty() {
130 | return latencyUncertainty;
131 | }
132 |
133 | public void setLatencyUncertainty(int latencyUncertainty) {
134 | this.latencyUncertainty = latencyUncertainty;
135 | }
136 |
137 | public int getErrorRate() {
138 | return errorRate;
139 | }
140 |
141 | public void setErrorRate(int errorRate) {
142 | this.errorRate = errorRate;
143 | }
144 |
145 | public int getSpikeStartChance() {
146 | return spikeStartChance;
147 | }
148 |
149 | public void setSpikeStartChance(int spikeStartChance) {
150 | this.spikeStartChance = spikeStartChance;
151 | }
152 |
153 | public int getSpikeEndChance() {
154 | return spikeEndChance;
155 | }
156 |
157 | public void setSpikeEndChance(int spikeEndChance) {
158 | this.spikeEndChance = spikeEndChance;
159 | }
160 |
161 | public SpikeMode getSpikeMode() {
162 | return spikeMode;
163 | }
164 |
165 | public void setSpikeMode(SpikeMode spikeMode) {
166 | this.spikeMode = spikeMode;
167 | }
168 |
169 | @Override
170 | public String toString() {
171 | return "SimulatorOpts [endopints=" + Arrays.toString(endopints) + ", requestRate=" + requestRate
172 | + ", requestRateUncertainty=" + requestRateUncertainty + ", latencyMin=" + latencyMin + ", latencyP50="
173 | + latencyP50 + ", latencyP90=" + latencyP90 + ", latencyP99=" + latencyP99 + ", latencyMax="
174 | + latencyMax + ", latencyUncertainty=" + latencyUncertainty + ", errorRate=" + errorRate
175 | + ", spikeStartChance=" + spikeStartChance + ", spikeEndChance=" + spikeEndChance + ", spikeMode="
176 | + spikeMode + "]";
177 | }
178 |
179 | }
180 |
--------------------------------------------------------------------------------
/http-simulator/src/main/java/io/spring2go/promdemo/httpsimulator/SpikeMode.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.promdemo.httpsimulator;
2 |
3 | public enum SpikeMode {
4 |
5 | OFF, ON, RANDOM
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/http-simulator/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | management.security.enabled=false
2 |
3 | opts.endpoints=/login, /login, /login, /login, /login, /login, /login, /users, /users, /users, /users/{id}, /register, /register, /logout, /logout, /logout, /logout
4 | opts.request_rate=1000
5 | opts.request_rate_uncertainty=70
6 | opts.latency_min=10
7 | opts.latency_p50=25
8 | opts.latency_p90=150
9 | opts.latency_p99=750
10 | opts.latency_max=10000
11 | opts.latency_uncertainty=70
12 |
13 | opts.error_rate=1
14 | opts.spike_start_chance=5
15 | opts.spike_end_chance=30
16 |
--------------------------------------------------------------------------------
/http-simulator/src/test/java/io/spring2go/promdemo/httpsimulator/HttpSimulatorApplicationTests.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.promdemo.httpsimulator;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class HttpSimulatorApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/lab01/README.md:
--------------------------------------------------------------------------------
1 | 实验一、Prometheus起步查询实验
2 | ======
3 |
4 | ### 实验步骤
5 |
6 | #### 1. 运行Prometheus HTTP Metrics Simulator
7 |
8 | * 将[http-simulator](../http-simulator)导入Eclipse IDE
9 | * Review代码理解模拟器原理
10 | * 以Spring Boot方式运行模拟器
11 | * 通过`http://localhost:8080/prometheus`查看metrics
12 | * 通过Postman启用随机Spike模式
13 |
14 | ```
15 | curl -X POST http://SERVICE_URL:8080/spike/random
16 | ```
17 |
18 | #### 2. 安装运行Promethus
19 |
20 | 下载[Prometheus 2.4.3 for Windows](https://github.com/prometheus/prometheus/releases/download/v2.4.3/prometheus-2.4.3.windows-amd64.tar.gz),并解压到本地目录。
21 |
22 | 调整全配置项
23 | ```yml
24 |
25 | # my global config
26 | global:
27 | scrape_interval: 5s # Set the scrape interval to every 5 seconds. Default is every 1 minute.
28 | scrape_timeout: 5s
29 | evaluation_interval: 5s # Evaluate rules every 5 seconds. The default is every 1 minute.
30 |
31 | ```
32 |
33 | 添加http-simulator Job配置项
34 |
35 | ```yml
36 | # A scrape configuration containing exactly one endpoint to scrape:
37 | # Here it's Prometheus itself.
38 | scrape_configs:
39 | # The job name is added as a label `job=` to any timeseries scraped from this config.
40 | - job_name: 'prometheus'
41 |
42 | # metrics_path defaults to '/metrics'
43 | # scheme defaults to 'http'.
44 |
45 | static_configs:
46 | - targets: ['localhost:9090']
47 | - job_name: 'http-simulator'
48 | metrics_path: /prometheus
49 | static_configs:
50 | - targets: ['localhost:8080']
51 |
52 | ```
53 |
54 | 运行Prometheus
55 | ```
56 | ./prometheus.exe
57 | ```
58 |
59 | 访问Prometheus Web UI
60 | ```
61 | http://localhost:9090
62 | ```
63 |
64 | 通过`Status->Targets`,或者通过`Graph`查询
65 | ```
66 | up
67 | ```
68 | metric方式校验`prometheus`和`http-simulator`两个jobs在**UP**或**1**状态。
69 |
70 | #### 3. 请求率(Request Rate)查询
71 |
72 | 校验http-simulator在**1**状态
73 | ```
74 | up{job="http-simulator"}
75 | ```
76 |
77 | 查询http请求数
78 | ```
79 | http_requests_total{job="http-simulator"}
80 | ```
81 |
82 | 查询成功login请求数
83 | ```
84 | http_requests_total{job="http-simulator", status="200", endpoint="/login"}
85 | ```
86 |
87 | 查询成功请求数,以endpoint区分
88 | ```
89 | http_requests_total{job="http-simulator", status="200"}
90 | ```
91 |
92 | 查询总成功请求数
93 | ```
94 | sum(http_requests_total{job="http-simulator", status="200"})
95 | ```
96 |
97 | 查询成功请求率,以endpoint区分
98 | ```
99 | rate(http_requests_total{job="http-simulator", status="200"}[5m])
100 | ```
101 |
102 | 查询总成功请求率
103 | ```
104 | sum(rate(http_requests_total{job="http-simulator", status="200"}[5m]))
105 | ```
106 |
107 | #### 4. 延迟分布(Latency distribution)查询
108 |
109 | 查询http-simulator延迟分布
110 | ```
111 | http_request_duration_milliseconds_bucket{job="http-simulator"}
112 | ```
113 |
114 | 查询成功login延迟分布
115 | ```
116 | http_request_duration_milliseconds_bucket{job="http-simulator", status="200", endpoint="/login"}
117 | ```
118 |
119 | 不超过200ms延迟的成功login请求占比
120 | ```
121 | sum(http_request_duration_milliseconds_bucket{job="http-simulator", status="200", endpoint="/login", le="200.0"}) / sum(http_request_duration_milliseconds_count{job="http-simulator", status="200", endpoint="/login"})
122 | ```
123 |
124 | 成功login请求延迟的99百分位
125 | ```
126 | histogram_quantile(0.99, rate(http_request_duration_milliseconds_bucket{job="http-simulator", status="200", endpoint="/login"}[5m]))
127 | ```
--------------------------------------------------------------------------------
/lab02/README.md:
--------------------------------------------------------------------------------
1 | 实验二、Prometheus+Grafana展示实验
2 | ======
3 |
4 | ### 实验步骤
5 |
6 | #### 1. 先决条件
7 |
8 | * 运行Prometheus HTTP Metrics Simulator
9 | * 运行Prometheus服务器
10 |
11 | #### 2. 安装运行Grafana
12 |
13 | 下载[Grafana 5.3.2 for Windows](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.3.2.windows-amd64.zip),并解压到本地目录。
14 |
15 | 运行:
16 | ```
17 | ./bin/grafana-server.exe
18 | ```
19 |
20 | 访问Granfa UI,使用缺省账号`admin/admin`登录
21 | ```
22 | http://localhost:3000
23 | ```
24 |
25 | 添加Proemethes数据源
26 |
27 | * Name -> prom-datasource
28 | * Type -> Prometheus
29 | * HTTP URL -> http://localhost:9090
30 |
31 | 其它缺省即可
32 |
33 | **Save & Test**确保连接成功
34 |
35 |
36 | #### 3. 创建一个Dashboard
37 |
38 | 点击**+**图标创建一个Dashbaord,点击**保存**图标保存Dashboard,使用缺省Folder,给Dashboard起名为`prom-demo`。
39 |
40 | #### 4. 展示请求率
41 |
42 | 点击**Add panel**图标,点击**Graph**图标添加一个Graph,
43 |
44 | 点击Graph上的*Panel Title*->*Edit*进行编辑
45 |
46 | 修改Title:*General* -> Title = Request Rate
47 |
48 | 设置*Metrics*
49 | ```
50 | sum(rate(http_requests_total{job="http-simulator"}[5m]))
51 | ```
52 |
53 | 调整*Lagend*
54 |
55 | * 以表格展示*As Table*
56 | * 显示*Min/Max/Avg/Current/Total*
57 | * 根据需要调整*Axis*
58 |
59 | 注意保存Dahsboard。
60 |
61 | #### 5. 展示实时错误率
62 |
63 | 点击**Add panel**图标,点击**Singlestat**图标添加一个Singlestat,
64 |
65 | 点击Graph上的*Panel Title->Edit*进行编辑
66 |
67 | 修改Title:*General* -> Title = Live Error Rate
68 |
69 | 设置*Metrics*
70 | ```
71 | sum(rate(http_requests_total{job="http-simulator", status="500"}[5m])) / sum(rate(http_requests_total{job="http-simulator"}[5m]))
72 | ```
73 |
74 | 调整显示单位unit:*Options->Unit*,设置为*None->percent(0.0-1.0)*
75 |
76 | 调整显示值(目前为平均)为当前值(now):*Options->Value->Stat*,设置为*Current*
77 |
78 | 添加阀值和颜色:*Options->Coloring*,选中*Value*,将*Threshold*设置为*0.01,0.05*,表示
79 | * 绿色:0-1%
80 | * 橙色:1-5%
81 | * 红色:>5%
82 |
83 | 添加测量仪效果:*Options->Gauge*,选中*Show*,并将*Max*设为*1*
84 |
85 | 添加错误率演变曲线:选中*Spark lines -> Show*
86 |
87 | 注意保存Dahsboard。
88 |
89 | #### 6. 展示Top requested端点
90 |
91 | 点击**Add panel**图标,点击**Table**图标添加一个Table,
92 |
93 | 设置*Metrics*
94 | ```
95 | sum(rate(http_requests_total{job="http-simulator"}[5m])) by (endpoint)
96 | ```
97 | 减少表中数据项,在*Metrics*下,选中*Instant*只显示当前值
98 |
99 | 隐藏*Time*列,在*Column Sytle*下,*Apply to columns named*为*Time*,将*Type->Type*设置为*Hidden*
100 |
101 | 将*Value*列重命名,添加一个*Column Style*,*Apply to columns named*为*Value*,将*Column Header*设置为*Requests/s*
102 |
103 | 点击表中的*Requests/s* header,让其中数据根据端点活跃度进行排序。
104 |
105 | 注意调整Widget位置并保存Dahsboard。
106 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/lab03/README.md:
--------------------------------------------------------------------------------
1 | 实验三、Prometheus+Alertmanager告警实验
2 | ======
3 |
4 | ### 实验步骤
5 |
6 | #### 1. 先决条件
7 |
8 | * 运行Prometheus HTTP Metrics Simulator
9 | * 运行Prometheus服务器
10 |
11 | 注意启用`--web.enable-lifecycle`,让Prometheus支持通过web端点动态更新配置
12 |
13 | #### 2. HttpSimulatorDown告警
14 |
15 | 在Prometheus目录下:
16 |
17 | 添加`simulator_alert_rules.yml`告警配置文件
18 |
19 | ```
20 | groups:
21 | - name: simulator-alert-rule
22 | rules:
23 | - alert: HttpSimulatorDown
24 | expr: sum(up{job="http-simulator"}) == 0
25 | for: 1m
26 | labels:
27 | severity: critical
28 | ```
29 |
30 | 修改`prometheus.yml`,引用`simulator_alert_rules.yml`文件
31 |
32 | ```
33 | # Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
34 | rule_files:
35 | - "simulator_alert_rules.yml"
36 | # - "second_rules.yml"
37 |
38 | ```
39 |
40 | 通过Postman动态更新Prometheus配置
41 | ```
42 | curl -X POST http://PROMETHEUS_URL:9090/-/reload
43 | ```
44 |
45 | 通过`Prometheus->Status`的`Configuration`和`Rules`确认配置和告警设置生效
46 |
47 | 关闭`Prometheus HTTP Metrics Simulator`应用,通过`Prometheus->Alert`界面上查看告警触发情况
48 |
49 |
50 | #### 3. ErrorRateHigh告警
51 |
52 | 假设已经执行上面的步骤2,则重新运行Prometheus HTTP Metrics Simulator
53 |
54 | 在`simulator_alert_rules.yml`文件中增加告警配置
55 |
56 | ```
57 | - alert: ErrorRateHigh
58 | expr: sum(rate(http_requests_total{job="http-simulator", status="500"}[5m])) / sum(rate(http_requests_total{job="http-simulator"}[5m])) > 0.02
59 | for: 1m
60 | labels:
61 | severity: major
62 | annotations:
63 | summary: "High Error Rate detected"
64 | description: "Error Rate is above 2% (current value is: {{ $value }}"
65 | ```
66 |
67 | 通过Postman动态更新Prometheus配置
68 | ```
69 | curl -X POST http://PROMETHEUS_URL:9090/-/reload
70 | ```
71 |
72 | 通过`Prometheus->Status`的`Configuration`和`Rules`确认配置和告警设置生效
73 |
74 | 通过Postman调高HTTP Simulator的错误率到10%
75 | ```
76 | curl -X POST http://localhost:8080/error_rate/10
77 | ```
78 |
79 | 通过`Prometheus->Graph`界面校验错误率上升
80 |
81 | 通过`Prometheus->Alert`界面校验查看触发情况
82 |
83 | #### 4. 安装和配置Alertmanager
84 |
85 | 下载[Alertmanager 0.15.2 for Windows](https://github.com/prometheus/alertmanager/releases/download/v0.15.2/alertmanager-0.15.2.windows-amd64.tar.gz),并解压到本地目录。
86 |
87 | 在`Alertmanager`目录下修改`alertmanager.yml`文件:
88 | ```
89 | global:
90 | smtp_smarthost: 'smtp.163.com:25'
91 | smtp_from: 'xxxxx@163.com'
92 | smtp_auth_username: 'xxxxx@163.com'
93 | smtp_auth_password: 'xxxxx'
94 |
95 | route:
96 | group_interval: 1m
97 | repeat_interval: 1m
98 | receiver: 'mail-receiver'
99 | receivers:
100 | - name: 'mail-receiver'
101 | email_configs:
102 | - to: 'xxxxxx@163.com'
103 |
104 | ```
105 |
106 | 启动Alertmanager
107 | ```
108 | ./alertmanager.exe
109 | ```
110 |
111 | 在`Prometheus`目录下,修改`prometheus.yml`配置Alertmanager地址
112 | ```
113 | # Alertmanager configuration
114 | alerting:
115 | alertmanagers:
116 | - static_configs:
117 | - targets:
118 | - localhost:9093
119 | ```
120 |
121 | 通过Postman动态更新Prometheus配置
122 | ```
123 | curl -X POST http://PROMETHEUS_URL:9090/-/reload
124 | ```
125 |
126 | 通过`Prometheus->Status`的`Configuration`和`Rules`确认配置和告警设置生效
127 |
128 | 通过Alertmanager UI界面和设置的邮箱,校验`ErrorRateHigh`告警触发
129 |
130 | Alertmanager UI访问地址:
131 | ```
132 | http://localhost:9093
133 | ```
134 |
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/lab04/README.md:
--------------------------------------------------------------------------------
1 | 实验四、Java应用埋点和监控实验
2 | ======
3 |
4 | ### 实验步骤
5 |
6 | #### 1. Review和运行埋点样例代码
7 |
8 | * 将[instrumentation-example](instrumentation-example)导入Eclipse IDE
9 | * Review代码理解模拟任务系统原理和埋点方式
10 | * 以Spring Boot方式运行埋点案例
11 | * 通过`http://localhost:8080/prometheus`查看metrics
12 |
13 | #### 2. 配置和运行Promethus
14 |
15 | 添加针对`instrumentation-example`的监控job
16 |
17 | ```
18 | - job_name: 'instrumentation-example'
19 | metrics_path: /prometheus
20 | static_configs:
21 | - targets: ['localhost:8080']
22 | ```
23 |
24 | 运行Prometheus
25 |
26 | ```
27 | ./prometheus.exe
28 | ```
29 |
30 | 通过`Prometheus->Status`的`configuration`和`targets`校验配置正确
31 |
32 | #### 3. 生成测试数据和查询Metrics
33 |
34 | 查询`instrumentation-example`在UP**1**状态
35 | ```
36 | up{job="instrumentation-example"}
37 | ```
38 |
39 | 运行[queueUpJobs.sh](queueUpJobs.sh)产生100个job
40 | ```
41 | ./queueUpJobs.sh
42 | ```
43 |
44 | 查询JobQueueSize变化曲线(调整时间范围到5m):
45 | ```
46 | job_queue_size{job="instrumentation-example"}
47 | ```
48 |
49 | 查询90分位Job执行延迟分布:
50 | ```
51 | histogram_quantile(0.90, rate(jobs_completion_duration_seconds_bucket{job="instrumentation-example"}[5m]))
52 | ```
53 |
54 |
--------------------------------------------------------------------------------
/lab04/instrumentation-example/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/lab04/instrumentation-example/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geektime-geekbang/prom_lab/0cdb3794ce56a45ab84467fd31efb559737d708d/lab04/instrumentation-example/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/lab04/instrumentation-example/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip
2 |
--------------------------------------------------------------------------------
/lab04/instrumentation-example/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Migwn, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | # TODO classpath?
118 | fi
119 |
120 | if [ -z "$JAVA_HOME" ]; then
121 | javaExecutable="`which javac`"
122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
123 | # readlink(1) is not available as standard on Solaris 10.
124 | readLink=`which readlink`
125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
126 | if $darwin ; then
127 | javaHome="`dirname \"$javaExecutable\"`"
128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
129 | else
130 | javaExecutable="`readlink -f \"$javaExecutable\"`"
131 | fi
132 | javaHome="`dirname \"$javaExecutable\"`"
133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
134 | JAVA_HOME="$javaHome"
135 | export JAVA_HOME
136 | fi
137 | fi
138 | fi
139 |
140 | if [ -z "$JAVACMD" ] ; then
141 | if [ -n "$JAVA_HOME" ] ; then
142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
143 | # IBM's JDK on AIX uses strange locations for the executables
144 | JAVACMD="$JAVA_HOME/jre/sh/java"
145 | else
146 | JAVACMD="$JAVA_HOME/bin/java"
147 | fi
148 | else
149 | JAVACMD="`which java`"
150 | fi
151 | fi
152 |
153 | if [ ! -x "$JAVACMD" ] ; then
154 | echo "Error: JAVA_HOME is not defined correctly." >&2
155 | echo " We cannot execute $JAVACMD" >&2
156 | exit 1
157 | fi
158 |
159 | if [ -z "$JAVA_HOME" ] ; then
160 | echo "Warning: JAVA_HOME environment variable is not set."
161 | fi
162 |
163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
164 |
165 | # traverses directory structure from process work directory to filesystem root
166 | # first directory with .mvn subdirectory is considered project base directory
167 | find_maven_basedir() {
168 |
169 | if [ -z "$1" ]
170 | then
171 | echo "Path not specified to find_maven_basedir"
172 | return 1
173 | fi
174 |
175 | basedir="$1"
176 | wdir="$1"
177 | while [ "$wdir" != '/' ] ; do
178 | if [ -d "$wdir"/.mvn ] ; then
179 | basedir=$wdir
180 | break
181 | fi
182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
183 | if [ -d "${wdir}" ]; then
184 | wdir=`cd "$wdir/.."; pwd`
185 | fi
186 | # end of workaround
187 | done
188 | echo "${basedir}"
189 | }
190 |
191 | # concatenates all lines of a file
192 | concat_lines() {
193 | if [ -f "$1" ]; then
194 | echo "$(tr -s '\n' ' ' < "$1")"
195 | fi
196 | }
197 |
198 | BASE_DIR=`find_maven_basedir "$(pwd)"`
199 | if [ -z "$BASE_DIR" ]; then
200 | exit 1;
201 | fi
202 |
203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
204 | echo $MAVEN_PROJECTBASEDIR
205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
206 |
207 | # For Cygwin, switch paths to Windows format before running java
208 | if $cygwin; then
209 | [ -n "$M2_HOME" ] &&
210 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
211 | [ -n "$JAVA_HOME" ] &&
212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
213 | [ -n "$CLASSPATH" ] &&
214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
215 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
217 | fi
218 |
219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
220 |
221 | exec "$JAVACMD" \
222 | $MAVEN_OPTS \
223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
226 |
--------------------------------------------------------------------------------
/lab04/instrumentation-example/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/lab04/instrumentation-example/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | io.spring2go.promdemo
7 | instrumentation-example
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | instrumentation-example
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 1.5.17.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-web
31 |
32 |
33 |
34 |
35 | io.prometheus
36 | simpleclient_spring_boot
37 | 0.5.0
38 |
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-starter-test
43 | test
44 |
45 |
46 |
47 |
48 |
49 |
50 | org.springframework.boot
51 | spring-boot-maven-plugin
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/lab04/instrumentation-example/src/main/java/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Class-Path:
3 |
4 |
--------------------------------------------------------------------------------
/lab04/instrumentation-example/src/main/java/io/spring2go/promdemo/instrument/InstrumentApplication.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.promdemo.instrument;
2 |
3 | import org.springframework.boot.CommandLineRunner;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.core.task.SimpleAsyncTaskExecutor;
8 | import org.springframework.core.task.TaskExecutor;
9 | import org.springframework.stereotype.Controller;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.RequestMethod;
12 | import org.springframework.web.bind.annotation.ResponseBody;
13 |
14 | import io.prometheus.client.spring.boot.EnablePrometheusEndpoint;
15 |
16 | @Controller
17 | @SpringBootApplication
18 | @EnablePrometheusEndpoint
19 | public class InstrumentApplication {
20 |
21 | private JobQueue queue = new JobQueue();
22 |
23 | private WorkerManager workerManager;
24 |
25 | public static void main(String[] args) {
26 |
27 | SpringApplication.run(InstrumentApplication.class, args);
28 | }
29 |
30 | @RequestMapping(value = "/hello-world")
31 | public @ResponseBody String sayHello() {
32 | return "hello, world";
33 | }
34 |
35 | @RequestMapping(value = "/jobs", method = RequestMethod.POST)
36 | public @ResponseBody String jobs() {
37 | queue.push(new Job());
38 | return "ok";
39 | }
40 |
41 | @Bean
42 | public TaskExecutor taskExecutor() {
43 | return new SimpleAsyncTaskExecutor();
44 | }
45 |
46 | @Bean
47 | public CommandLineRunner schedulingRunner(TaskExecutor executor) {
48 | return new CommandLineRunner() {
49 | public void run(String... args) throws Exception {
50 | // 10 jobs per worker
51 | workerManager = new WorkerManager(queue, 1, 4, 10);
52 | executor.execute(workerManager);
53 | System.out.println("WorkerManager thread started...");
54 | }
55 | };
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/lab04/instrumentation-example/src/main/java/io/spring2go/promdemo/instrument/Job.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.promdemo.instrument;
2 |
3 | import java.util.Random;
4 | import java.util.UUID;
5 |
6 | public class Job {
7 |
8 | private String id;
9 |
10 | private Random rand = new Random();
11 |
12 | public Job() {
13 | this.id = UUID.randomUUID().toString();
14 | }
15 |
16 | public void run() {
17 | try {
18 | // Run the job (5 - 15 seconds)
19 | Thread.sleep((5 + rand.nextInt(10)) * 1000);
20 | } catch (InterruptedException e) {
21 | // TODO Auto-generated catch block
22 | e.printStackTrace();
23 | }
24 | }
25 |
26 | public String getId() {
27 | return id;
28 | }
29 |
30 | public void setId(String id) {
31 | this.id = id;
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/lab04/instrumentation-example/src/main/java/io/spring2go/promdemo/instrument/JobQueue.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.promdemo.instrument;
2 |
3 | import java.util.Queue;
4 | import java.util.concurrent.LinkedBlockingQueue;
5 |
6 | import io.prometheus.client.Gauge;
7 |
8 | public class JobQueue {
9 |
10 | private final Gauge jobQueueSize = Gauge.build()
11 | .name("job_queue_size")
12 | .help("Current number of jobs waiting in queue")
13 | .register();
14 |
15 | private Queue queue = new LinkedBlockingQueue();
16 |
17 | public int size() {
18 | return queue.size();
19 | }
20 |
21 | public void push(Job job) {
22 | queue.offer(job);
23 | jobQueueSize.inc();
24 | }
25 |
26 | public Job pull() {
27 | Job job = queue.poll();
28 | if (job != null) {
29 | jobQueueSize.dec();
30 | }
31 | return job;
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/lab04/instrumentation-example/src/main/java/io/spring2go/promdemo/instrument/Worker.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.promdemo.instrument;
2 |
3 | import java.util.UUID;
4 |
5 | import io.prometheus.client.Histogram;
6 |
7 | public class Worker extends Thread {
8 |
9 | private static final Histogram jobsCompletionDurationSeconds = Histogram.build()
10 | .name("jobs_completion_duration_seconds")
11 | .help("Histogram of job completion time")
12 | .linearBuckets(4, 1, 16)
13 | .register();
14 |
15 | private String id;
16 |
17 | private JobQueue queue;
18 |
19 | private volatile boolean shutdown;
20 |
21 | public Worker(JobQueue queue) {
22 | this.queue = queue;
23 | this.id = UUID.randomUUID().toString();
24 | }
25 |
26 | @Override
27 | public void run() {
28 | System.out.println(String.format("[Worker %s] Starting", this.id));
29 | while(!shutdown) {
30 | this.pullJobAndRun();
31 | }
32 | System.out.println(String.format("[Worker %s] Stopped", this.id));
33 | }
34 |
35 | public void shutdown() {
36 | this.shutdown = true;
37 | System.out.println(String.format("[Worker %s] Shutting down", this.id));
38 | }
39 |
40 | public void pullJobAndRun() {
41 | Job job = this.queue.pull();
42 | if (job != null) {
43 | long jobStart = System.currentTimeMillis();
44 | System.out.println(String.format("[Worker %s] Starting job: %s", this.id, job.getId()));
45 | job.run();
46 | System.out.println(String.format("[Worker %s] Finished job: %s", this.id, job.getId()));
47 | int duration = (int)((System.currentTimeMillis() - jobStart) / 1000);
48 | jobsCompletionDurationSeconds.observe(duration);
49 | } else {
50 | System.out.println(String.format("[Worker %s] Queue is empty. Backing off 5 seconds", this.id));
51 | try {
52 | Thread.sleep(5 * 1000);
53 | } catch (InterruptedException e) {
54 | // TODO Auto-generated catch block
55 | e.printStackTrace();
56 | }
57 | }
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/lab04/instrumentation-example/src/main/java/io/spring2go/promdemo/instrument/WorkerManager.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.promdemo.instrument;
2 |
3 | import java.util.LinkedList;
4 | import java.util.Queue;
5 |
6 | public class WorkerManager extends Thread {
7 |
8 | private Queue workers = new LinkedList();
9 |
10 | private JobQueue queue;
11 |
12 | private int minWorkers;
13 | private int maxWorkers;
14 |
15 | private int jobsWorkerRatio;
16 |
17 | public WorkerManager(JobQueue queue, int minWorkers, int maxWorkers, int jobsWorkerRatio) {
18 | this.queue = queue;
19 | this.minWorkers = minWorkers;
20 | this.maxWorkers = maxWorkers;
21 | this.jobsWorkerRatio = jobsWorkerRatio;
22 |
23 | // Initialize workerpool
24 | for (int i = 0; i < minWorkers; i++) {
25 | this.addWorker();
26 | }
27 | }
28 |
29 | public void addWorker() {
30 | Worker worker = new Worker(queue);
31 | this.workers.offer(worker);
32 | worker.start();
33 | }
34 |
35 | public void shutdownWorker() {
36 | if (this.workers.size() > 0) {
37 | Worker worker = this.workers.poll();
38 | worker.shutdown();
39 | }
40 | }
41 |
42 | public void run() {
43 | this.scaleWorkers();
44 | }
45 |
46 | public void scaleWorkers() {
47 | while(true) {
48 | int queueSize = this.queue.size();
49 | int workerCount = this.workers.size();
50 |
51 | if ((workerCount + 1) * jobsWorkerRatio < queueSize && workerCount < this.maxWorkers) {
52 | System.out.println("[WorkerManager] Too much work, starting extra worker.");
53 | this.addWorker();
54 | }
55 |
56 | if ((workerCount - 1) * jobsWorkerRatio > queueSize && workerCount > this.minWorkers) {
57 | System.out.println("[WorkerManager] Too much workers, shutting down 1 worker");
58 | this.shutdownWorker();
59 | }
60 |
61 | try {
62 | Thread.sleep(10 * 1000);
63 | } catch (InterruptedException e) {
64 | // TODO Auto-generated catch block
65 | e.printStackTrace();
66 | }
67 | }
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/lab04/instrumentation-example/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | management.security.enabled=false
2 |
3 |
--------------------------------------------------------------------------------
/lab04/queueUpJobs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | for i in {1..100}; do
4 | curl -X POST http://localhost:8080/jobs
5 | done
--------------------------------------------------------------------------------
/lab05/README.md:
--------------------------------------------------------------------------------
1 | 实验五、NodeExporter系统监控实验
2 | ======
3 |
4 | ### 实验步骤
5 |
6 | #### 1. 下载和运行wmi-exporter
7 |
8 | 下载[wmi_exporter-amd64](https://github.com/martinlindhe/wmi_exporter/releases/download/v0.4.3/wmi_exporter-amd64.zip),并解压到本地目录
9 |
10 | 运行wmi-exporter
11 |
12 | ```
13 | ./wmi_exporter.exe
14 | ```
15 |
16 | 校验metrics端点
17 |
18 | ```
19 | http://localhost:9182/metrics
20 | ```
21 |
22 | #### 2. 配置和运行Promethus
23 |
24 | 在`Prometheus`安装目录下
25 |
26 | 在`prometheus.yml` 中添加针对`wmi-exporter`的监控job
27 |
28 | ```
29 | - job_name: 'wmi-exporter'
30 | static_configs:
31 | - targets: ['localhost:9182']
32 | ```
33 |
34 | 运行`Prometheus`
35 |
36 | ```
37 | ./prometheus.exe
38 | ```
39 |
40 | 访问`Prometheus` UI
41 |
42 | ```
43 | http://localhost:9090
44 | ```
45 |
46 | 通过`Prometheus->Status`的`configuration`和`targets`校验配置正确
47 |
48 | 通过`Prometheus->Graph`查询`wmi-exporter`在UP**1**状态
49 |
50 | ```
51 | up{job="wmi-exporter"}
52 | ```
53 |
54 | #### 3. Grafana Dashboard for wmi-exporter
55 |
56 | 在Grafana安装目录下启动Grafana服务器
57 |
58 | ```
59 | ./bin/grafana-server.exe
60 | ```
61 |
62 | 登录Grafana UI(admin/admin)
63 |
64 | ```
65 | http://localhost:3000
66 | ```
67 |
68 | 通过Grafana的**+**图标导入(**Import**) wmi-exporter dashboard:
69 |
70 | * grafana id = **2129**
71 | * 注意选中`prometheus`数据源
72 |
73 | 查看`Windows Node` dashboard。
74 |
75 | #### 4. 参考
76 |
77 | Grafana Dashboard仓库
78 |
79 | ```
80 | https://grafana.com/dashboards
81 | ```
82 |
83 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/lab06/README.md:
--------------------------------------------------------------------------------
1 | 实验六、Spring Boot Actuator监控实验
2 | ======
3 |
4 | ### 实验步骤
5 |
6 | #### 1. 运行Spring Boot + Actuator
7 |
8 | 将[actuatordemo](actuatordemo)应用导入Eclipse IDE
9 |
10 | Review `actuatordemo`代码
11 |
12 | 以Spring Boot方式运行actuatordemo
13 |
14 | 校验metrics端点
15 |
16 | ```
17 | http://localhost:8080/prometheus
18 | ```
19 |
20 | #### 2. 配置和运行Promethus
21 |
22 | 在`Prometheus`安装目录下
23 |
24 | 在`prometheus.yml` 中添加针对`wmi-exporter`的监控job
25 |
26 | ```
27 | - job_name: 'actuator-demo'
28 | metrics_path: '/prometheus'
29 | static_configs:
30 | - targets: ['localhost:8080']
31 | ```
32 |
33 | 运行`Prometheus`
34 |
35 | ```
36 | ./prometheus.exe
37 | ```
38 |
39 | 访问`Prometheus` UI
40 |
41 | ```
42 | http://localhost:9090
43 | ```
44 |
45 | 通过`Prometheus->Status`的`configuration`和`targets`校验配置正确
46 |
47 | 通过`Prometheus->Graph`查询`actuator-demo`在UP=**1**状态
48 |
49 | ```
50 | up{job="actuatordemo"}
51 | ```
52 |
53 | #### 3. Grafana Dashboard for JVM (Micrometer)
54 |
55 | 在Grafana安装目录下启动Grafana服务器
56 |
57 | ```
58 | ./bin/grafana-server.exe
59 | ```
60 |
61 | 登录Grafana UI(admin/admin)
62 |
63 | ```
64 | http://localhost:3000
65 | ```
66 |
67 | 通过Grafana的**+**图标导入(**Import**) `JVM (Micrometer)` dashboard:
68 |
69 | * grafana id = **4701**
70 | * 注意选中`prometheus`数据源
71 |
72 | 查看`JVM (Micormeter)` dashboard。
73 |
74 | #### 4. 参考
75 |
76 | Grafana Dashboard仓库
77 | ```
78 | https://grafana.com/dashboards
79 | ```
80 |
81 | Micrometer Prometheus支持
82 | ```
83 | https://micrometer.io/docs/registry/prometheus
84 | ```
85 | Micrometer Springboot 1.5支持
86 | ```
87 | https://micrometer.io/docs/ref/spring/1.5
88 | ```
89 |
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/lab06/actuatordemo/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/lab06/actuatordemo/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geektime-geekbang/prom_lab/0cdb3794ce56a45ab84467fd31efb559737d708d/lab06/actuatordemo/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/lab06/actuatordemo/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip
2 |
--------------------------------------------------------------------------------
/lab06/actuatordemo/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Migwn, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | # TODO classpath?
118 | fi
119 |
120 | if [ -z "$JAVA_HOME" ]; then
121 | javaExecutable="`which javac`"
122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
123 | # readlink(1) is not available as standard on Solaris 10.
124 | readLink=`which readlink`
125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
126 | if $darwin ; then
127 | javaHome="`dirname \"$javaExecutable\"`"
128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
129 | else
130 | javaExecutable="`readlink -f \"$javaExecutable\"`"
131 | fi
132 | javaHome="`dirname \"$javaExecutable\"`"
133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
134 | JAVA_HOME="$javaHome"
135 | export JAVA_HOME
136 | fi
137 | fi
138 | fi
139 |
140 | if [ -z "$JAVACMD" ] ; then
141 | if [ -n "$JAVA_HOME" ] ; then
142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
143 | # IBM's JDK on AIX uses strange locations for the executables
144 | JAVACMD="$JAVA_HOME/jre/sh/java"
145 | else
146 | JAVACMD="$JAVA_HOME/bin/java"
147 | fi
148 | else
149 | JAVACMD="`which java`"
150 | fi
151 | fi
152 |
153 | if [ ! -x "$JAVACMD" ] ; then
154 | echo "Error: JAVA_HOME is not defined correctly." >&2
155 | echo " We cannot execute $JAVACMD" >&2
156 | exit 1
157 | fi
158 |
159 | if [ -z "$JAVA_HOME" ] ; then
160 | echo "Warning: JAVA_HOME environment variable is not set."
161 | fi
162 |
163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
164 |
165 | # traverses directory structure from process work directory to filesystem root
166 | # first directory with .mvn subdirectory is considered project base directory
167 | find_maven_basedir() {
168 |
169 | if [ -z "$1" ]
170 | then
171 | echo "Path not specified to find_maven_basedir"
172 | return 1
173 | fi
174 |
175 | basedir="$1"
176 | wdir="$1"
177 | while [ "$wdir" != '/' ] ; do
178 | if [ -d "$wdir"/.mvn ] ; then
179 | basedir=$wdir
180 | break
181 | fi
182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
183 | if [ -d "${wdir}" ]; then
184 | wdir=`cd "$wdir/.."; pwd`
185 | fi
186 | # end of workaround
187 | done
188 | echo "${basedir}"
189 | }
190 |
191 | # concatenates all lines of a file
192 | concat_lines() {
193 | if [ -f "$1" ]; then
194 | echo "$(tr -s '\n' ' ' < "$1")"
195 | fi
196 | }
197 |
198 | BASE_DIR=`find_maven_basedir "$(pwd)"`
199 | if [ -z "$BASE_DIR" ]; then
200 | exit 1;
201 | fi
202 |
203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
204 | echo $MAVEN_PROJECTBASEDIR
205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
206 |
207 | # For Cygwin, switch paths to Windows format before running java
208 | if $cygwin; then
209 | [ -n "$M2_HOME" ] &&
210 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
211 | [ -n "$JAVA_HOME" ] &&
212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
213 | [ -n "$CLASSPATH" ] &&
214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
215 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
217 | fi
218 |
219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
220 |
221 | exec "$JAVACMD" \
222 | $MAVEN_OPTS \
223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
226 |
--------------------------------------------------------------------------------
/lab06/actuatordemo/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/lab06/actuatordemo/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | io.spring2go.promdemo
7 | actuatordemo
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | actuatordemo
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 1.5.17.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-actuator
31 |
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-web
36 |
37 |
38 |
39 | io.micrometer
40 | micrometer-spring-legacy
41 | 1.0.6
42 |
43 |
44 |
45 | io.micrometer
46 | micrometer-registry-prometheus
47 | 1.0.6
48 |
49 |
50 |
51 | io.github.mweirauch
52 | micrometer-jvm-extras
53 | 0.1.2
54 |
55 |
56 |
57 | org.springframework.boot
58 | spring-boot-starter-test
59 | test
60 |
61 |
62 |
63 |
64 |
65 |
66 | org.springframework.boot
67 | spring-boot-maven-plugin
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/lab06/actuatordemo/src/main/java/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Class-Path:
3 |
4 |
--------------------------------------------------------------------------------
/lab06/actuatordemo/src/main/java/io/spring2go/promdemo/actuatordemo/ActuatordemoApplication.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.promdemo.actuatordemo;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.ResponseBody;
9 |
10 | import io.micrometer.core.instrument.MeterRegistry;
11 | import io.micrometer.spring.autoconfigure.MeterRegistryCustomizer;
12 |
13 | @SpringBootApplication
14 | @Controller
15 | public class ActuatordemoApplication {
16 |
17 | public static void main(String[] args) {
18 | SpringApplication.run(ActuatordemoApplication.class, args);
19 | }
20 |
21 | @RequestMapping(value = "/hello-world")
22 | public @ResponseBody String sayHello() {
23 | return "hello, world";
24 | }
25 |
26 | @Bean
27 | MeterRegistryCustomizer metricsCommonTags() {
28 | return registry -> registry.config().commonTags("application", "actuator-demo");
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lab06/actuatordemo/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | endpoints.sensitive=false
--------------------------------------------------------------------------------
/lab06/actuatordemo/src/test/java/io/spring2go/promdemo/actuatordemo/ActuatordemoApplicationTests.java:
--------------------------------------------------------------------------------
1 | package io.spring2go.promdemo.actuatordemo;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class ActuatordemoApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/ppt/微服务监控告警Prometheus架构和实践.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geektime-geekbang/prom_lab/0cdb3794ce56a45ab84467fd31efb559737d708d/ppt/微服务监控告警Prometheus架构和实践.pdf
--------------------------------------------------------------------------------