1、创建provider项目
本次部署使用wrapper包装器对项目进行封装,通过wrapper启动器来实现服务的注册与发现,不再使用nacos插件来实现服务注册
provider结构
因为本次测试只是为了测试如何去发布如何去监控,这里就不做持续集成了,上图的Jenkinsfile、Dockerfile忽略即可
cat pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.8.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.teng</groupId>
<artifactId>provider</artifactId>
<version>0.0.5</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
</properties>
<!-- 设置deploy的地址 -->
<distributionManagement>
<repository>
<id>maven-releases</id> <!--库的ID-->
<name>maven-releases</name> <!--库的名字-->
<url>http://192.168.0.152:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>maven-snapshots</id>
<name>maven-snapshot</name>
<url>http://192.168.0.152:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<dependencies>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
该文件去掉了原provider项目的nacos相关插件,添加了prometheus相关插件
cat src/main/resources/appication.properties
server.port=8080
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
这里暂时只能使用8080,要配合wrapper包装器,包装器使用58080代理的端口默认是8080,至于可不可以修改还不确定
mvn clean install
打包生成jar包
2、生成封装镜像
在进行封装前先来了解一下以前wrapper封装hello镜像的具体原理
- 镜像创建时对外暴漏代理端口58080
- 容器启动时,wrapper将应用服务注册至nacos
- 注册成功后wrapper通过laucher.sh脚本启动应用,并配置check,成功后向nacos发出Heartbeat
- 外部访问应用通过wrapper代理端口转发到hello应用的8080端口,同时代理端口接受hello响应返回的数据再返回给请求者
明白其原理后,需要根据应用具体情况来修改
查看wrapper代码结构
cat config/config.yml
# 包装器配置
wrapper:
# 工作模式,默认为 "proxy" 代理模式
# "launcher" 启动器模式,负责为单体应用程序向注册中心注册及注销,并通过脚本控制单体应用执行
# "proxy" 模式为代理模式,包含启动器功能,并启动 HTTP 服务对外提供服务,转发请求至单体应用,可对请求进行日志分析处理
# mode: "proxy"
# HTTP 代理服务主机名, 默认为 "0.0.0.0", 即全部接收
# 该配置项应用于对 wrapper 代理模式下的 HTTP 服务的主机名。对应 http://{hostname}:{port}
# hostname: "0.0.0.0"
# HTTP 代理服务端口,默认 58080
# port: 58080
# HTTP 代理服务请求重试次数,默认值 3
# 转发请求到单体应用时,如果发起请求失败,将进行重试。超过重试次数仍然失败将重新启动单体应用
# request_retry: 3
# 是否根据单体应用 API 进行过滤,默认为否,即透明模式
# 如果为 true 将根据 API MAP 进行过滤,限制对未提供的 API 进行访问,当前版本采用透明模式不过滤,只支持 false
# 过滤 API 需向请求者返回失败信息,如 405 method not allowed,具体返回格式需确认。
# filter_api: false
# 待过滤的 API URL 信息,具体过滤内容需要与单体应用确认
# api:
# data: "/data"
# 单体应用监控 url , 用于确认单体应用运行是否正常,当前版本支持 GET 方法,根据 HTTP 状态 200 进行确认。如果状态不正确,将重新启动单体应用。
# http://{monolith_ip}:{port}/{check_url}
check_url: "http://127.0.0.1:8080"
# 监控 URL 检查间隔, 默认 5 秒
# check_interval: 5
# 重启间隔,默认 5 秒
# HTTP 转发支持并发访问,可能同时由多个线程触发重启操作,需限制重启间隔,如单体应用已经重启,且不能提供服务,将返回 503 Service Unavailable 错误。
# restart_interval: 5
# 单体应用控制脚本,默认为 "./launcher.sh"
# script_path: "./launcher.sh"
# monolith 配置
# monolith:
# 单体应用接收转发请求的 IP , 默认为 "127.0.0.1"。
# 该配置项应用于接收 wrapper 代理服务器转发的单体应用主机名。对应 http://{IP}:{port}。
# 采用 "127.0.0.1" 避免其它微服务通过内部 overlay 网络直接访问单体应用。
# 如果 wrapper 不是代理模式,可以设置为 0.0.0.0
# ip: "127.0.0.1"
# 单体应用接收转发请求端口,默认 8080
# port: 8080
# center 配置
center:
# 注册中心主机名, 默认为 "nacos"。
hostname: "nacos"
# 注册中心端口,默认 8848
# port: 8848
# service 配置
service:
# 命名空间 id, 需要手工在 nacos 中进行创建
namespace_id: "43a700c7-0316-4133-913e-810b520c47e4"
# 服务名,需要注册的服务名
service_name: "wrapper-provider"
# 元数据
metadata:
service_type: "TYPE"
company_name: "NAME"
# 查询服务名
query_name: ["wrapper-provider"]
# 集群名,默认值 "DEFAULT"
# cluster_name: "DEFAULT"
# 组名,默认值 "DEFAULT_GROUP"
# group_name: "DEFAULT_GROUP"
# 用户名,默认值 "nacos"
# username
# 密码,默认值 "nacos"
# password
# 网卡名,默认值 "eth0"
ethernet_name: "eth2"
# prometheus 配置
# prometheus:
# 是否启用 prometheus, 默认值 true
# enable: true
# jaeger 配置
jaeger:
# 是否启用 tracing,默认值 true
# enable: true
# tracer 名称,默认值 "jaeger-service"
name: "wrapper-provider-tracer"
# 采样率,默认值 0.1
sampler: 1
# 服务端点,默认值 ":6831"
endpoint: "jaeger:6831"
# Pool 设置,Job-Worker 线程池
# pool:
# 调度器名称 默认值,"task"
# dispatcher_name: "task"
# 队列长度,默认值 200
# queue_capacity: 200
# 作业容量,默认值 50
# job_capacity: 50
# 工作者容量,默认值 20
# worker_capacity: 20
# breaker 设置
# breaker:
# 阈值,默认值 20,
# 20 次错误后,breaker 为 open 状态
# threshold: 20
# 刷新周期,默认值 10000 毫秒
# tick: 10000
# timing wheel 时间轮设置
# timing_wheel:
# 时间轮单圈容量,默认值 60
# capacity: 60
# 最短间隔周期,默认值 100 毫秒
# tick: 100
cat launcher.sh
#!/bin/sh -e
app="provider"
pid=`ps aux | grep $app | grep -v grep| sed -n '1P' | awk '{print $1}' `
usage(){
echo "Usage: ./launcher start|stop"
exit 1
}
cd ./monolith/
start(){
if [ -z $pid ];then
java -jar *.jar &
echo "`date '+%Y/%m/%d %H:%M:%S'` $app has been started."
else
echo "`date '+%Y/%m/%d %H:%M:%S'` $app is running."
fi
}
stop(){
if [ $pid ];then
kill $pid
echo "`date '+%Y/%m/%d %H:%M:%S'` $app has been stopped."
fi
}
case "$1" in
"start") start ;;
"stop") stop ;;
*) usage;;
esac
将生成的jar包放置在monolith下
构建镜像
docker build -t waka2020/wrapper-provider:latest .
3、启动服务
cat docker-compose.yml
version: "3.4"
services:
provider:
image: waka2020/wrapper-provider:latest
networks:
- service_overlay
- monitor_overlay
ports:
- 58080:58080
volumes:
- "/etc/localtime:/etc/localtime:ro"
environment:
- CENTER_HOSTNAME=nacos
- SERVICE_ETHERNET_NAME=eth2
deploy:
placement:
constraints: [node.hostname==node150]
resources:
limits:
cpus: '1'
memory: '1G'
restart_policy:
condition: any
delay: 5s
max_attempts: 3
networks:
service_overlay:
external: true
monitor_overlay:
external: true
docker stack deploy -c docker-compose.yml wrapper
4、配置监控
cat prometheus.yml
...
- job_name: 'wrapper-provider'
scrape_interval: 5s
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['provider:58080']
...
增加上面配置后重启prometheus,访问http://node150:58080/actuator/prometheus就可以看到暴露的metrics
登录grafana可以在http request指标下找到与wrapper-provider相关的指标信息,编写查询语句就可以出图了
5、监控出图
对于应用及环境架构,通常从以下几个方面来进行监控指标的采集
- 应用的api,比如nginx负载均衡器或者微服务入口,对http request指标数据进行采集,通常有请求地址、状态码、响应时长,从而可以通过这些历史指标数据分析业务的压力,服务状态
- 应用本身的资源使用情况,对于容器可以去监控container的资源使用情况
- 基础设施,一般指虚拟机或物理服务器资源
- 其他,比如集群中用到的数据库、缓存、消息队列等组件的状态
监控wrapper-provider容器内的内存使用情况
- 当前使用内存及分配的内存上限
查询语句
container_memory_usage_bytes{name=~"wrapper_provider.1.+"}
container_spec_memory_limit_bytes{name=~"wrapper_provider.1.+"}
- 内存使用率
查询语句
sum(container_memory_usage_bytes{name=~"wrapper_provider.1.+"}) / sum(container_spec_memory_limit_bytes{name=~"wrapper_provider.1.+"}) * 100 != +inf
监控wrapper-provider容器内cpu使用情况
- 当前使用cpu及分配的cpu上限
查询语句
sum(rate(container_cpu_usage_seconds_total{name=~"wrapper_provider.1.+"}[5m])) by (name)
(sum(container_spec_cpu_quota{name=~"wrapper_provider.1.+"}/100000) by (name))
- cpu使用率
查询语句
sum(container_memory_usage_bytes{name=~"wrapper_provider.1.+"}) / sum(container_spec_memory_limit_bytes{name=~"wrapper_provider.1.+"}) * 100 != +inf
监控http请求
本文的provider应用只返回了一个404的错误页面,所以下面只用语句来说明http指标采集
- 请求数
http_server_requests_seconds_count{job="wrapper-provider",uri!~".*actuator.*"}
- 请求时间
http_server_requests_seconds_sum{job="wrapper-provider",uri!~".*actuator.*"}
- 请求响应时间
rate(http_server_requests_seconds_sum{job="wrapper-provider",uri!~".*actuator.*"}[5m]) / rate(http_server_requests_seconds_count{job="wrapper-provider",uri!~".*actuator.*"}[5m])
监控网络流量
-
发送字节
查询语句
sum(rate(container_network_transmit_bytes_total{name=~"wrapper_provider.+"}[$interval])) by (name)
-
接受字节
查询语句
sum(rate(container_network_receive_bytes_total{name=~"wrapper_hello.1.+"}[$interval])) by (name)
6、代码链接
7、metrics指标参考链接
cAdvisor指标参考1
cAdvisor指标参考2
cAdvisor指标参考3
actuator-http-request指标参考
#