$ curl -LO https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u242-b08/OpenJDK8U-jdk_x64_linux_hotspot_8u242b08.tar.gz
$ tar -xvf jdk_x64_linux_hotspot_8u242b08.tar.gz
$ mv jdk8u242-b08/ ~/jdk8
$ export JAVA_HOME=~/jdk8
$ curl -LO http://www.trieuvan.com/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
$ tar -xvf apache-maven-3.6.3-bin.tar.gz
$ mv apache-maven-3.6.3 ~/maven
$ export PATH=~/maven/bin:$PATH
$ curl -LO https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-19.3.1/graalvm-ce-java8-linux-amd64-19.3.1.tar.gz
$ tar -xvf graalvm-ce-java8-linux-amd64-19.3.1.tar.gz
$ mv graalvm-ce-java8-19.3.1 ~/graalvm
$ export PATH=~/graalvm/bin:$PATH
$ gu install native-image
Downloading: Component catalog from www.graalvm.org
Processing Component: Native Image
Downloading: Component native-image: Native Image from github.com
Installing new component: Native Image (org.graalvm.native-image, version 19.3.1)
$ gu list
ComponentId Version Component name Origin
--------------------------------------------------------------------------------
graalvm 19.3.1 GraalVM Core
native-image 19.3.1 Native Image github.com
$ mvn io.quarkus:quarkus-maven-plugin:1.2.1.Final:create \
-DprojectGroupId=org.acme \
-DprojectArtifactId=getting-started \
-DclassName="org.acme.quickstart.GreetingResource" \
-Dextensions="metrics" \
-Dpath="/hello"
$ cd getting-started
$ mvn compile quarkus:dev
$ curl http://localhost:8080/hello
hello
$ curl http://localhost:8080/metrics
。。。
# HELP vendor_memory_usedNonHeap_bytes Displays the amount of used non-heap memory in bytes.
# TYPE vendor_memory_usedNonHeap_bytes gauge
vendor_memory_usedNonHeap_bytes 3.2114336E7
package org.acme.quickstart;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.eclipse.microprofile.metrics.annotation.Counted; //Add line.
@Path("/hello")
public class GreetingResource {
@GET
@Counted(name = "greetings", description = "How many greetings we've given.") //Add line.
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
}
$ curl http://localhost:8080/metrics/application
# HELP application_org_acme_quickstart_GreetingResource_greetings_total How many greetings we've given.
# TYPE application_org_acme_quickstart_GreetingResource_greetings_total counter
application_org_acme_quickstart_GreetingResource_greetings_total 0.0
package org.acme.quickstart;
import org.eclipse.microprofile.metrics.MetricUnits;
import org.eclipse.microprofile.metrics.annotation.Counted;
import org.eclipse.microprofile.metrics.annotation.Gauge;
import org.eclipse.microprofile.metrics.annotation.Timed;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@Path("/prime")
public class PrimeNumberChecker {
private long highestPrimeNumberSoFar = 2;
@GET
@Path("/{number}")
@Produces("text/plain")
@Counted(name = "performedChecks", description = "How many primality checks have been performed.")
@Timed(name = "checksTimer", description = "A measure of how long it takes to perform the primality test.", unit = MetricUnits.MILLISECONDS)
public String checkIfPrime(@PathParam("number") long number) {
if (number < 1) {
return "Only natural numbers can be prime numbers.";
}
if (number == 1) {
return "1 is not prime.";
}
if (number == 2) {
return "2 is prime.";
}
if (number % 2 == 0) {
return number + " is not prime, it is divisible by 2.";
}
for (int i = 3; i < Math.floor(Math.sqrt(number)) + 1; i = i + 2) {
if (number % i == 0) {
return number + " is not prime, is divisible by " + i + ".";
}
}
if (number > highestPrimeNumberSoFar) {
highestPrimeNumberSoFar = number;
}
return number + " is prime.";
}
@Gauge(name = "highestPrimeNumberSoFar", unit = MetricUnits.NONE, description = "Highest prime number so far.")
public Long highestPrimeNumberSoFar() {
return highestPrimeNumberSoFar;
}
}
$ curl http://localhost:8080/prime/5
5 is prime.
$ curl http://localhost:8080/prime/350
351 is not prime, is divisible by 3.
$ curl http://localhost:8080/prime/359
359 is prime.
$ curl http://localhost:8080/metrics/application | grep performedChecks
# HELP application_org_acme_quickstart_PrimeNumberChecker_performedChecks_total How many primality checks have been performed.
# TYPE application_org_acme_quickstart_PrimeNumberChecker_performedChecks_total counter
application_org_acme_quickstart_PrimeNumberChecker_performedChecks_total 3.0
$ curl http://localhost:8080/metrics/application | grep highestPrimeNumberSoFar
# HELP application_org_acme_quickstart_PrimeNumberChecker_highestPrimeNumberSoFar Highest prime number so far.
# TYPE application_org_acme_quickstart_PrimeNumberChecker_highestPrimeNumberSoFar gauge
application_org_acme_quickstart_PrimeNumberChecker_highestPrimeNumberSoFar 359.0
$ curl http://localhost:8080/metrics/application | grep checksTimer
# TYPE application_org_acme_quickstart_PrimeNumberChecker_checksTimer_rate_per_second gauge
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_rate_per_second 0.009651120871431985
# TYPE application_org_acme_quickstart_PrimeNumberChecker_checksTimer_one_min_rate_per_second gauge
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_one_min_rate_per_second 0.0015203946095816126
# TYPE application_org_acme_quickstart_PrimeNumberChecker_checksTimer_five_min_rate_per_second gauge
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_five_min_rate_per_second 0.07491811314937041
# TYPE application_org_acme_quickstart_PrimeNumberChecker_checksTimer_fifteen_min_rate_per_second gauge
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_fifteen_min_rate_per_second 0.14412698663875181
# TYPE application_org_acme_quickstart_PrimeNumberChecker_checksTimer_min_seconds gauge
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_min_seconds 1.07824E-4
# TYPE application_org_acme_quickstart_PrimeNumberChecker_checksTimer_max_seconds gauge
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_max_seconds 8.55019E-4
# TYPE application_org_acme_quickstart_PrimeNumberChecker_checksTimer_mean_seconds gauge
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_mean_seconds 4.0862461940924336E-4
# TYPE application_org_acme_quickstart_PrimeNumberChecker_checksTimer_stddev_seconds gauge
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_stddev_seconds 3.0210634938071025E-4
# HELP application_org_acme_quickstart_PrimeNumberChecker_checksTimer_seconds A measure of how long it takes to perform the primality test.
# TYPE application_org_acme_quickstart_PrimeNumberChecker_checksTimer_seconds summary
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_seconds_count 3.0
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_seconds{quantile="0.5"} 4.36168E-4
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_seconds{quantile="0.75"} 8.55019E-4
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_seconds{quantile="0.95"} 8.55019E-4
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_seconds{quantile="0.98"} 8.55019E-4
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_seconds{quantile="0.99"} 8.55019E-4
application_org_acme_quickstart_PrimeNumberChecker_checksTimer_seconds{quantile="0.999"} 8.55019E-4
$ mvn clean package -DskipTests
$ oc new-build registry.access.redhat.com/redhat-openjdk-18/openjdk18-openshift:1.5 --binary --name=primes -l app=primes
$ rm -rf target/binary && mkdir -p target/binary && cp -r target/*-runner.jar target/lib target/binary
$ oc new-app primes
$ oc expose service primes
$ oc rollout status -w dc/primes
$ curl http://$(oc get route primes |awk 'NR==2 {print $2}')/prime/5
5 is prime.
$ curl http://$(oc get route primes |awk 'NR==2 {print $2}')/prime/351
351 is not prime, is divisible by 3.
$ curl http://$(oc get route primes |awk 'NR==2 {print $2}')/prime/359
359 is prime.
$ oc new-project quarkus-prometheus --display-name="Prometheus Monitoring Quarkus App"
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets:
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'hello-app'
static_configs:
- targets: ['primes:8080']
$ oc create configmap prom --from-file=prometheus.yml=prometheus.yml
configmap/prom created
$ oc new-app prom/prometheus
$ oc expose svc/prometheus
$ oc set volume dc/prometheus --add -t configmap --configmap-name=prom -m /etc/prometheus/prometheus.yml --sub-path=prometheus.yml
info: Generated volume name: volume-2vbzq
deploymentconfig.apps.openshift.io/prometheus volume updated
$ oc rollout status -w dc/prometheus
Waiting for rollout to finish: 0 out of 1 new replicas have been updated...
Waiting for rollout to finish: 0 out of 1 new replicas have been updated...
Waiting for rollout to finish: 0 of 1 updated replicas are available...
Waiting for latest deployment config spec to be observed by the controller loop...
replication controller "prometheus-2" successfully rolled out
PRIME_URL=http://$(oc get route primes |awk 'NR==2 {print $2}')
while [ true ] ; do
BITS=$(( ( RANDOM % 60 ) + 1 ))
NUM=$(openssl prime -generate -bits $BITS)
curl ${PRIME_URL}/prime/${NUM} && echo
sleep 2
done
$ oc get route prometheus
3. 点击Graph,然后将时间调整到5m(分钟)。此时将会以图形化方式显示监控结果。
4. 将监控指标改为“base_memory_usedHeap_bytes”,然后再Execute,可以查看监控到的内存指标情况。
$ oc new-app grafana/grafana && oc expose svc/grafana
$ oc rollout status -w dc/grafana
$ oc get route grafana
3. 在控制台初始化页面中点击“Add data source”。
4. 设置HTTP的URL为本地Prometheus的metrics地址“http://prometheus:9090”,然后点击“Save & Test”。
5. 在Grafana控制台中点击“+”,然后进入Dashboard菜单。在New dashborad界面中进入Add Query。
6. 在设置Query步骤中将Metrics设为“application_org_acme_quickstart_PrimeNumberChecker_performedChecks_total”。
7. 在设置General步骤中将Title设为“Prime Checks”。
8. 此时界面已经显示监控的指标图。点击右上方的Save Dashboard图标,并指定名称为“Quarkus Primes”,然后Save。
9. 按照以上的操作方式再新建以下的Dashboard。
指标名1:application_org_acme_quickstart_PrimeNumberChecker_checksTimer_seconds
保存名1:Primes Performance
指标名2:application_org_acme_quickstart_PrimeNumberChecker_highestPrimeNumberSoFar
图样式2:Singlestat
保存名2:Highest So Far
指标名3:base_memory_usedHeap_bytes
图样式3:Gauge
显示单位:Field Units to bytes
保存名3:Memory
10. 最后可以在Grafana的Dashboard显示如下图的监控控制台。