网站集群建设方案,网络推广排名,设计网站页面要注意什么,湖南长沙设计公司“ 阅读本文大概需要 10 分钟。 ”最近我在公司负责的业务已经正式投入上线了#xff0c;既然是线上环境#xff0c;那么就需要保证其可用性。我负责的业务其中就包括一个 Web Service#xff0c;我需要保证 Service 的每个接口都是可用的#xff0c;如果某个时间流量大了或… “ 阅读本文大概需要 10 分钟。 ”最近我在公司负责的业务已经正式投入上线了既然是线上环境那么就需要保证其可用性。我负责的业务其中就包括一个 Web Service我需要保证 Service 的每个接口都是可用的如果某个时间流量大了或者服务器挂掉了那需要第一时间通知到我。这时候可能我有这些需求1.定时测试和监控服务器每个接口是否是可用的包括返回的数据、状态码是不是正确的。2.我可以随时查看到每个接口的响应时间、可用率等信息最好是有可视化的图表呈现一目了然。3.如果接口的错误率超过某一阈值一段时间及时通知我包括电话、短信或邮件。4.需要主动去监测接口的可用性注意这里是主动监测而不是被动监测不是等用户用的时候报错才提醒我。比如在没有用户用的时候我也能及时知道每个接口的可用性。其实国内的一些服务商已经提供了这些功能即主动型服务监控比如「监控宝」但我并不想用这些服务一是需要额外花钱二是数据上并不安全三是我需要把我的服务集成到公司内部的监控体系下。有了这些需求我就结合公司内部现有的一些基础设施先确定一个技术选型然后实施就好了。目前公司内部使用的一套监控体系是基于 Kubernetes Prometheus Grafana Alert Manager 的那么基于我的需求来分析下我怎样利用这一套体系来搭建我想要的监控设施。解决方案分析1.首先关于第四个需求比较特殊现有的监控体系其实已经可以做到服务的被动监测比如某个 Service 的 API 被调用了那么相应的调用数据都会被汇总到 Prometheus 上面Prometheus 里面会计算接口调用的可用率如果一段时间内如果错误率超过一定阈值那就报警追错误的时候去查下 log 就好了。但其实这个不能做到主动监测比如在凌晨三四点当没有用户使用的时候如果这时候服务器出现问题了我也需要第一时间能知道所以我需要有一个定时的主动监测程序来实时监测我的所有接口是否是可用的。要做到主动监控那我一定需要一个接口监测程序定时运行并校验每个接口的结果这里我选用的就是开源的 JMeter它大多数情况下是被用来做压测的但绝对能满足接口调用和检测的需求只要我定时跑 JMeter 来检测就好了。2.关于第一个需求我需要监测我的每个接口都是可用的包括返回的数据也需要是想要的结果。这时候我们可能想到直接跑一些 test case 之类的但这些其实大多数都是在部署或运行时校验的如果我要实时跑或者 test case 有 update 了也不太方便。另外为了写接口测试的时候如果没有现成的工具我们可能得写一堆代码每个接口都写一个包括 GET 请求的 URL 参数、POST 请求的 Body 信息等等然后校验接口的返回结果是不是对的也太麻烦了。所以我们需要找到一个可用的工具来帮助我们快速地完成这些功能。所以我选择的 JMeter 也提供了可视化界面我只需要配置一些接口和参数即可另外它还带有定时器、断言、动态参数、多线程等功能这样我们也可以做到并发测试、随机等待、动态构造请求参数、返回结果判断等功能了。3.其次再说第二个和第三个需求其实用现有的 Prometheus Grafana 就能解决了这里最关键的则是我的接口监控结果能发给 Prometheus 才行。既然我选用了 JMeter那么我怎样把 JMeter 的数据发送给 Prometheus 呢这里需要借助于 JMeter 的一个插件 jmeter-prometheus-pluginhttps://github.com/johrstrom/jmeter-prometheus-plugin利用它就能将 JMeter 变成一个 Data ExporterPrometheus 来抓取就好了。所以综上所述我利用的一套服务监控体系就是 JMeter Kubernetes Prometheus Grafana Alert Manager那么就开干吧。这里先放一张图看下最终的监控 Grafana 面板吧监控面板这里一些接口的名称和 URL 我就打码了这里我可以在 Grafana 中每时每刻都看到每个接口的可用率、响应包括平均、最快、最慢时间、状态码等信息这些信息就是 JMeter 定时检测得到的结果监控数据转到 Prometheus 里面然后经过 Grafana 可视化出来并能通过一些指标来实现报警机制。感兴趣的话可以继续往下看哈。为了达成这些功能我需要解决如下问题•如何使用 JMeter 来测试每个接口的使用情况。•JMeter 如何和 Prometheus 对接起来即如何集成 jmeter-prometheus-plugin 到 JMeter。•JMeter 怎样去部署部署到哪里。•可视化数据怎样来呈现。•错误状态怎样来快速查看。•出错通知如何实现比如打电话、发邮件等等。下面我们就来一个个总结说一下。由于内容比较多整个流程我实践下来然后测试通总共花了两天左右的时间在这里就不完全展开说了只提关键点了。JMeter 测试第一步那就是用 JMeter 来完成接口的测试了接口的调用形式肯定都有相应的规范的比如 GET 请求设置啥参数POST 请求发送什么数据我们利用 JMeter 都能方便地配置。JMeter 是有 GUI 的我们在编写的时候在 GUI 里面设置就好了界面样例如下所示JMeter界面图源https://www.jianshu.com/p/0349441da3c4这里提示几点可能用到的东西•动态参数JMeter 里面是支持动态参数设置的比如循环测试 id 从 1 到 100或者动态 POST 的数据替换都是可以做到的这个可以满足你花样测试接口的需求。•定时器JMeter 里面有很多 Timer可以设置各种各样的延时操作比如每 3 分钟测一次随机等待多少秒测一次都行。•断言测试了接口之后我们不仅要知道是否是可用的同时也要判断其结果是不是正确的如果返回状态码是正确的但是结果不对那也白搭所以可以使用断言来检查返回结果。关于 JMeter 的功能这里就不再展开讲了反正几乎你想实现的任何测试功能都可以实现具体的用法可以参考 JMeter 的官方文档https://jmeter.apache.org/usermanual/get-started.html。嗯写好了之后可以用 JMeter 在本地进行测试测试好了时候可以把 JMeter 的这个 Test Plan 存成一个 jmx 文件留作后面备用。对接 Prometheus接下来就是如何把数据对接到 Prometheus 里面了。默认情况下JMeter 是能导出数据到诸如 InfluxDB 这样的数据库的借助于它自带的 Listener 即可实现。它并不带导出到 Prometheus 的功能。这里我们就需要借助于 jmeter-prometheus-plugin 这个插件了其 GitHub 地址是 https://github.com/johrstrom/jmeter-prometheus-plugin具体的用法可以参考其官方说明。这里提示几点•jmeter-prometheus-plugin 安装的时候把 jar 文件放到 JMeter 目录下就好了jar 文件可以直接看这里下载https://github.com/johrstrom/jmeter-prometheus-plugin#programatically。•安装好这个插件之后需要增加一个 Listener然后配置各种导出字段和参数可以参考这个 jmx 文件的配置https://github.com/johrstrom/jmeter-prometheus-plugin/blob/master/docs/examples/simple_prometheus_example.jmx可以把这个 jmx 打开然后把 Listener 拷贝到你的 Test Plan 即可。•jmeter-prometheus-plugin 这个插件会把 JMeter 变成一个 Data Exporter而不是通过 Prometheus Push Gateway 来主动推送监控信息所以它会在本地启动一个端口默认是 9270。Listener 的配置示例如图所示JMeter Listener这里字段名如 jsr223_rt_as_summary 可以自行修改比如这里我就统一修改为了 jmeter_test_xxx 这样的字段。配置完成之后运行 JMeter 之后我们就能在 http://localhost:9270 上看到 Exporter 的信息如图所示Exporter这里面就包含了 JMeter 的一些接口测试结果包括成功次数、失败次数、状态码等等另外还有 JVM、处理器等各种环境信息。部署之后把对应的 URL 交由 Prometheus 就可以把监控数据收集到 Prometheus 里面了。部署 JMeter完成上述两步我们就能成功测试 Service 的每个接口并能生成测试结果的 Exporter 了。那么 JMeter 写好了怎么来部署呢可以用 crontab放某台服务器上不过这里最理想的方式当然是部署到 Kubernetes 里面了。这里就需要把 JMeter 打包成一个镜像了GitHub 找来找去没找到几个合适的另外也没有把 jmeter-prometheus-plugin 包括进去那只有自己来了。我基于 https://github.com/justb4/docker-jmeter 进行了二次改写最后打包了一个镜像已经开源了地址为https://github.com/Germey/JMeterMonitor镜像名称为 germey/jmeter这里就不再展开讲细节了有点复杂。运行所需要的 docker-compose 文件如下version: 3
services:jmeter:restart: alwaysimage: germey/jmetervolumes:- ./jmx:/appcommand:- sample.jmxports:- 80:80
这里我把本地的 jmx 文件夹 mount 到了 Docker 的 app 文件夹所以这里在运行时需要在项目文件夹下新建 jmx 文件夹用于存放 jmx 文件把刚才写好的 jmx 文件放过来就好了。另外 command 就是 jmx 文件的名称这里需要修改成你的 jmx 文件。另外部署到 Kubernetes 的话可以参考这里的 yml 文件https://github.com/Germey/JMeterMonitor/tree/master/kubernetes。Prometheus 收集数据在成功部署 JMeter 之后呢它肯定会提供一个 Web Service 来暴露 JMeter 的测试数据。如果部署好了 Prometheus 之后可以把它放在 Prometheus 的 scrape_configs比如 Service 的 URL 为 jmeter-monitor.com可以修改 prometheus.ymlglobal:scrape_interval: 15s # By default, scrape targets every 15 seconds.# Attach these labels to any time series or alerts when communicating with# external systems (federation, remote storage, Alertmanager).external_labels:monitor: codelab-monitor# A scrape configuration containing exactly one endpoint to scrape:
# Here its Prometheus itself.
scrape_configs:# The job name is added as a label jobjob_name to any timeseries scraped from this config.- job_name: jmeter-monitor# Override the global default and scrape targets from this job every 5 seconds.scrape_interval: 5sstatic_configs:- targets: [jmeter-monitor.com]
其具体的配置字段可以参见https://prometheus.io/docs/prometheus/latest/configuration/configuration/。另外呢这种方式其实并不怎么好修改 Prometheus 挺麻烦的推荐使用 Helm Prometheus-Operator 来安装 Prometheus然后修改 values.yml 即可修改配置文件了比如修改 https://github.com/helm/charts/blob/master/stable/prometheus-operator/values.yaml 里面的 additionalScrapeConfigs 即可。Grafana 可视化Prometheus 收集完数据之后我们可以将其可视化出来了。比如这里有些字段jmeter_test_can_fail_success 代表成功请求的次数jmeter_test_can_fail_total 代表总的测试次数。那么就可以用一个表达式来计算 Error Rate 了1- jmeter_test_can_fail_success{instance$instance} / jmeter_test_can_fail_total{instance$instance}
效果如下配置面板这里就能实时可视化展示出来错误率了更多的一些配置可以自行修改这些表达式进行定制。最后我配置成的一些监控面板如下所示监控面板这样我要是什么时候想看 Service 接口的情况随时上来看就好了。报警对于报警来说可以使用两种方式配置一个是直接使用 Grafana 自带的报警机制另外是可以通过 Alert Manager后者功能更加强大推荐使用后者。对于 Alert Manager 来说其监控的规则这里推荐使用 Prometheus-Operator 里面自带的 PrometheusRule 来实现比如可以定义这么一个 PrometheusRuleapiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:labels:app: monitorname: monitor-rules
spec:groups:- name: monitorrules:- alert: ServiceErroringlabels:severity: warningannotations:message: Service 连续5分钟错误率过高。expr: |avg(1- jmeter_test_can_fail_success{jobservice-monitor} / jmeter_test_can_fail_total{jobservice-monitor}) 0for: 5m
这样配置好一个 PrometheusRule 之后Prometheus 会自动应用这个 Rule 然后监控。报警方式的话可以通过配置 Alert Manger 的 Receiver 来实现包括打电话、邮件、短信等等配置规则可以见https://prometheus.io/docs/alerting/configuration/。目前我是利用了组内已经提供的报警机制组内已经对接好了电话、短信、邮件报警并可以把每个人的信息进行管理和分组然后应用到某个报警规则里面这样一旦有问题就可以实现报警啦。另外对于一些规则的管理我们可以使用一些开源的 Dashboard 来管理如 Kramahttps://github.com/prymitive/karma利用它我们可以方便配置、禁用和筛选一些报警规则界面如下Krama不过公司内部已经实现了一套了对接了公司的员工账号更加方便所以我就没有再用这个了。定时重启这里另外遇到了一个问题就是 JMeter 导出的监控数据是不断累积的而监控的数据则是需要监控最近几分钟的数据这样一旦发生了 Error那么 Error Rate 由于历史数据的原因在服务恢复之后永远不会降为 0这就导致一些问题。另外如果 JMeter 如果一直运行其占用的内存会越来越大。所以一个最好的方式就是定时将 JMeter 重启这样可以定时清空历史监控数据保证在新的一段时间内测试获取到最近的监控数据而不是混杂历史数据。这里重启就可以利用 Kubernetes 的 Cronjob比如我们可以每隔 10 分钟让 JMeter 重启一次类似配置如下apiVersion: batch/v1beta1
kind: CronJob
metadata:name: jmeter-monitor
spec:successfulJobsHistoryLimit: 0failedJobsHistoryLimit: 0concurrencyPolicy: Replaceschedule: */10 * * * *jobTemplate:spec:template:metadata:labels:service: jmeter-monitorspec:containers:- args:- jmeter-monitor.jmximage: germey/jmeter:1name: jmeter-monitorvolumeMounts:- mountPath: /appname: jmeter-storageports:- containerPort: 80imagePullPolicy: IfNotPresentresources:requests:memory: 4Gicpu: 250mlimits:memory: 4Gicpu: 250mrestartPolicy: OnFailurevolumes:- name: jmeter-storagepersistentVolumeClaim:claimName: jmeter
这里有几个地方值得注意•一个是 concurrencyPolicy这里配置为 Replace意思是重启后新建的 Pod 会替换原来的 Pod保证 JMeter 的 Pod 只有一个。•另外一个是 imagePullPolicy 配置为 IfNotPresent这样可以每次重启的时候不用重新拉镜像。这样的话就能避免发生错误的时候 Error Rate 无法降为 0 的状态了。好了到此为止呢我们就介绍完了使用 JMeter Kubernetes Prometheus Grafana Alert Manager 进行监控的整体思路了希望对大家有帮助。另外由于内容比较多这里很多地方没有展开讲解比如 JMeter 的配置、Grafana 的配置、Prometheus-Operator 的配置、Alert Manager 的配置等等不知道大家感不感兴趣如果感兴趣的话后面可以继续深入写一个小系列来讲解哈。