在压测工作流程的"前期准备"章节中曾提到搭建监控,使用Prometheus和Grafana相结合就可以快速搭建一个强大的监控平台。
Prometheus主要负责监控数据的采集,存储以及对外提供查询功能,Grafana主要负责监控数据的图形化展示。
Prometheus是一套开源监控系统,它的架构主要如下所示:
Prometheus Serve是Prometheus组件中的核心部分,负责实现对监控数据的采集,存储以及查询。
我们可以将Exporter即理解为上面prometheus server中提到的监控目标。
它主要是负责搜集系统指标以及业务指标,将这些数据通过http接口以promethues约定的数据格式对外提供。
prometheus支持基于PromQL创建告警规则,如果满足告警条件,则产生告警信息并push到告警管理中心进行后续处理。
如果网络条件不支持prometheus server直接获取监控对象的数据,或者监控对象是一个很短时的任务,prometheus server还没来得及采集数据可能被销毁了,这个时候可以用pushGateway来做一个中转站,监控目标把监控数据push到中转站,prometheus server从中转站去pull数据。
本次实践主要是基于一个mock server添加一些业务监控。
该mock server主要是模拟数据上报的接收方,建立及维护与数据上报服务器的tcp长连接,接受并解析约定格式的上报数据,最后对每条数据返回一个ack。
公司已经有pormetheus和Grafana了,所以这里不做额外搭建。需要做的事情主要如下:
我的mock server是用python实现的,因此选用官方python版的prometheus_client
`pip install prometheus_client `
Prometheus定义了4中不同的指标类型(metric type):Counter(计数器)、Gauge(仪表盘)、Histogram(直方图)、Summary(摘要),根据你想要的业务指标特性来选择。
在本例中,我定义了一个简单的统计收到的数据个数的计数器,然后在函数处理的合适位置打监控点加1计数
from prometheus_client import Counter
# 创建Counter类型
prom_received_total = Counter('evm_mocker_received_total', 'The total of evm mocker received event numbers')
def message_handle():
...
# 在合适的位置埋点
prom_received_total.inc()
只要在服务的入口函数中调用prometheus_client.start_http_server方法,即可以启动并暴露http监控端口,本例监控端口是8000。
from prometheus_client import start_http_server
start_http_server(8000)
Dockerfile文件大致如下:
FROM python:3.6
LABEL maintainer="[email protected]"
# copy源码到image的指定路径
COPY . /data/evm_mocker
# 安装必要的包
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y net-tools
RUN pip3 install fire \
pymysql \
prometheus_client
# 工作路径及入口方法
WORKDIR /data/evm_mocker
CMD [ "python3", "/data/evm_mocker/server.py" ]
k8s的Deployment配置如下 evm-mocker-deployment.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: evm-mocker-monitor
spec:
replicas: 1
selector:
matchLabels:
app: evm-mocker-monitor
template:
metadata:
labels:
app: evm-mocker-monitor
spec:
containers:
- name: evm-mocker
image: swc-harbor.nioint.com/sqe/evm_mocker:monitor
imagePullPolicy: Always
ports:
- containerPort: 5555
name: comm
- containerPort: 8000
name: monitor
service配置如下 evm-mocker-service.yml
apiVersion: v1
kind: Service
metadata:
name: evm-mocker-monitor-service
labels:
name: evm-mocker-monitor-service
spec:
type: NodePort
ports:
- port: 5555
targetPort: 5555
protocol: TCP
name: comm
- port: 8000
targetPort: 8000
protocol: TCP
name: monitor
selector:
app: evm-mocker-monitor
部署好后,尝试访问服务的8000端口,观察是否能正常获取prometheus格式的数据。
调用kubectl get pods -o wide
获得pod所在的node ip地址,调用kubectrl get svc
获得pod 8000端口对应的外部端口号。
本例中最终的http接口是http://10.125.236.24:25448/ 。注意:此处访问接口后面接任意路径如/metrics, /prometheus也都能获取同样的数据。
部署在k8s中的服务,如何由同样部署在k8s中的Prometheus server采集数据呢?
配置
还记得在上文Promethues数据采集中提到的静态配置和动态发现吗?
静态配置指的是往Prometheus server的配置文件中写死Exporter暴露的监控接口,这种方式每部署一个服务都得去配置文件里写一遍,不够灵活。好在k8s还支持动态发现,
只要在部署service的yaml文件中添加metadata.annotations.prometheus.io/scrape='true’即可。
evm-mocker-service.yml
apiVersion: v1
kind: Service
metadata:
...
annotations:
prometheus.io/scrape: 'true' # 添加此行使得api能被发现
spec:
...
校验
在prometheus页面检查是否可以查询到上文配置的指标。
Graph页面输入"evm_mocker_received_total" 查看console是否有数据。
还可以通过Prometheus UI中的Status->Targets页面查看当前所有的监控采集任务。
PromQL
无论是grafana监控的展现和告警的配置,都涉及到PromQL,因此,监控的配置很重要一点是写好PromQL,例如如果我们需要监控mock server的QPS,此处可写成rate(evm_mocker_received_total[1m])
实践中,经常先在prometheus页面调试PromQL,图像符合预期后再把它填入到Grafana中。
关于PromQl的详细介绍可以参考promql
服务的监控数据能被prometheus采集后,接下来就是用Grafana展现数据。
在Grafana页面创建一个dashboard,dashboard可以理解为监控图表的集合。然后在dashboard中创建一个个监控Panel。
本文介绍了prometheus的框架,然后用一个实例介绍一个监控指标从产生到展现的完整流程,包括:在业务代码中埋点监控指标并暴露接口,部署到k8s中并被prometheus的动态发现,通过grafana展现该指标的监控图。