Open-falcon-基础系列(九)-服务监控实践一篇读懂

发布时间:2025-08-19 11:29:25 作者:admin 来源:admin 浏览量(1) 点赞(4)
摘要:服务监控实践 服务监控实际上就是监控我们生产服务器中的所跑的各种服务,例如:mysql、nginx、redis、rabbitMQ、lvs、tomcat等等 这些服务都有它的一些监控指标,这些需要根据实际的服务器性能、业务指标去制定,…

服务监控实践

服务监控实际上就是监控我们生产服务器中的所跑的各种服务,例如:mysql、nginx、redis、rabbitMQ、lvs

、tomcat等等

这些服务都有它的一些监控指标,这些需要根据实际的服务器性能、业务指标去制定,你可以叫监控指标标准化吧

这些指标需要不断进行调整,最终形成适应公司架构、业务、产品的,不是一蹴而就的

原理图

自定义数据push

将其他服务监控之前先说下自定义的push数据。

原理图

就是通过Python、GO、shell常用的开发语言,把我们监控项的数据指标,所需要的数据抓取出来,然后发送到 Falcon的Agent端

举例子

所有运行的脚本都和agent在同一台服务器,当然也可以不在同一台服务器看你自己需求。你会那个语言用哪个就行。

Shell Push 数据
# 注意,http request body是个json,这个json是个列表 ts=`date +%s`; curl -X POST -d "[{"metric": "test-metric", "endpoint": "test-endpoint", "timestamp": $ts,"step": 60,"value": 1,"counterType": "GAUGE","tags": "idc=lg,project=xx"}]" http://127.0.0.1:1988/v1/push
Python Push 数据
#!-*- coding:utf8 -*- import requests import time import json ts = int(time.time()) payload = [ { "endpoint": "test-endpoint", "metric": "test-metric", "timestamp": ts, "step": 60, "value": 1, "counterType": "GAUGE", "tags": "idc=lg,loc=beijing", }, { "endpoint": "test-endpoint", "metric": "test-metric2", "timestamp": ts, "step": 60, "value": 2, "counterType": "GAUGE", "tags": "idc=lg,loc=beijing", }, ] r = requests.post("http://127.0.0.1:1988/v1/push", data=json.dumps(payload)) print r.text
Go Push 数据
package main import ( "bytes" "encoding/json" "fmt" "io/ioutil" "net/http" ) func main() { apiurl := "http://127.0.0.1:1988/v1/push" type item struct { Endpoint string `json:"endpoint"` Metric string `json:"metric"` Timestamp int64 `json:"timestamp"` Step int `json:"step"` Value int64 `json:"value"` CounterType string `json:"counterType"` Tags string `json:"tags"` } type message struct { Item []item `json:"item"` } //json序列化 var post message post.Item = append(post.Item, item{Endpoint: "test-endpoint", Metric: "test-metric", Timestamp: 1500804940, Step: 60, Value: 10, CounterType: "GAUGE", Tags: "idc=xixian"}) jsonStr, _ := json.Marshal(post.Item) req, err := http.NewRequest("POST", apiurl, bytes.NewBuffer([]byte(jsonStr))) req.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() }

Agent HTTP APi接口详解

metric: 最核心的字段,代表这个采集项具体度量的是什么, 比如是cpu_idle呢,还是memory_free, 还是qpsendpoint: 标明Metric的主体(属主),比如metric是cpu_idle,那么Endpoint就表示这是哪台机器的cpu_idletimestamp: 表示汇报该数据时的unix时间戳

,注意是整数,代表的是秒value: 代表该metric在当前时间点的值,float64step: 表示该数据采集项的汇报周期,这对于后续的配置监控策略很重要,必须明确指定。counterType: 只能是COUNTER或者GAUGE二选一,前者表示该数据采集项为计时器类型,后者表示其为原值 (注意大小写)GAUGE:即用户上传什么样的值,就原封不动的存储COUNTER:指标在存储和展现的时候,会被计算为speed,即(当前值 - 上次值)/ 时间间隔tags: 一组逗号分割的键值对, 对metric进一步描述和细化, 可以是空字符串. 比如idc=lg,比如service=xbox等,多个tag之间用逗号分割 说明:这7个字段都是必须指定

服务监控

Mysql 监控

想要监控Mysql 就需要知道我们监控Mysql需要看哪些指标,然后进行数据收集

监控指标

通常会看 - 系统方面

由于太多我就不意义列举了,挑一些比较重要的

有人问这些指标都哪来的都是通过,mysql sql获取的

show master status; show slave status; show global status; show global variables;

我知道指标了、也知道这些指标怎么获取,我们现在要将获得数据转化Json 数据 Push到 Agent API接口就可以了。

由于已经有第三方产品已经完成了,我们直接使用就行。当然你可以用Python、go去收集数据Push。

安装配置

mymon Github 地址

编译包
# 原来go包地址 cd /root/go/src/github.com/open-falcon/ git clone https://github.com/open-falcon/mymon.git cd mymon # 编译 [root@open-falcon-1 mymon]# make Run gofmt on all source files ... gofmt -l -s -w ... ==> Checking that build is using go version >= 1.10... go build -o mymon
配置文件修改 vim etc/myMon.cfg

设置定时任务

[root@open-falcon-1 mymon]# pwd /root/go/src/github.com/open-falcon/mymon crontab -e # 写入如下 * * * * * cd /root/go/src/github.com/open-falcon/mymon && ./mymon -c etc/myMon.cfg

web控制台

更多指标参考:各个指标在/mymon/metrics.txt

Redis

有很多方式: 1. go 参考这个redis-metrics

Python 参考这个 Redismon

或者直接写Python脚本

#!/bin/env python #-*- coding:utf-8 -*- import json import time import socket import os import re import sys import commands import urllib2, base64 class RedisStats: # 如果你是自己编译部署到redis,请将下面的值替换为你到redis-cli路径 _redis_cli = /usr/bin/redis-cli _stat_regex = re.compile(ur(w+):([0-9]+.?[0-9]*) ) def __init__(self, port=6379, passwd=None, host=127.0.0.1): self._cmd = %s -h %s -p %s info % (self._redis_cli, host, port) if passwd not in [, None]: self._cmd = %s -h %s -p %s -a %s info % (self._redis_cli, host, port, passwd) def stats(self): Return a dict containing redis stats info = commands.getoutput(self._cmd) return dict(self._stat_regex.findall(info)) def main(): ip = socket.gethostname() timestamp = int(time.time()) step = 60 # inst_list中保存了redis配置文件列表,程序将从这些配置中读取port和password,建议使用动态发现的方法获得,如: # inst_list = [ i for i in commands.getoutput("find /etc/ -name redis*.conf" ).split( ) ] insts_list = [ /etc/redis/redis.conf ] p = [] monit_keys = [ (connected_clients,GAUGE), (blocked_clients,GAUGE), (used_memory,GAUGE), (used_memory_rss,GAUGE), (mem_fragmentation_ratio,GAUGE), (total_commands_processed,COUNTER), (rejected_connections,COUNTER), (expired_keys,COUNTER), (evicted_keys,COUNTER), (keyspace_hits,COUNTER), (keyspace_misses,COUNTER), (keyspace_hit_ratio,GAUGE), ] for inst in insts_list: port = commands.getoutput("sed -n s/^port *([0-9]{4,5})/\1/p %s" % inst) passwd = commands.getoutput("sed -n s/^requirepass *([^ ]*)/\1/p %s" % inst) metric = "redis" endpoint = ip tags = port=%s % port try: conn = RedisStats(port, passwd) stats = conn.stats() except Exception,e: continue for key,vtype in monit_keys: #一些老版本的redis中info输出的信息很少,如果缺少一些我们需要采集的key就跳过 if key not in stats.keys(): continue #计算命中率 if key == keyspace_hit_ratio: try: value = float(stats[keyspace_hits])/(int(stats[keyspace_hits]) + int(stats[keyspace_misses])) except ZeroDivisionError: value = 0 #碎片率是浮点数 elif key == mem_fragmentation_ratio: value = float(stats[key]) else: #其他的都采集成counter,int try: value = int(stats[key]) except: continue i = { Metric: %s.%s % (metric, key), Endpoint: endpoint, Timestamp: timestamp, Step: step, Value: value, CounterType: vtype, TAGS: tags } p.append(i) print json.dumps(p, sort_keys=True,indent=4) method = "POST" handler = urllib2.HTTPHandler() opener = urllib2.build_opener(handler) url = http://127.0.0.1:1988/v1/push request = urllib2.Request(url, data=json.dumps(p) ) request.add_header("Content-Type",application/json) request.get_method = lambda: method try: connection = opener.open(request) except urllib2.HTTPError,e: connection = e # check. Substitute with appropriate HTTP code. if connection.code == 200: print connection.read() else: print {"err":1,"msg":"%s"} % connection if __name__ == __main__: proc = commands.getoutput( ps -ef|grep %s|grep -v grep|wc -l % os.path.basename(sys.argv[0])) sys.stdout.flush() if int(proc) < 5: main()

使用方法

根据实际部署情况,修改有注释位置附近的配置测试: python redis-monitor.py将脚本加入crontab执行即可

nginx

参考我另一篇文章 open-falcon nginx 监控

业务类型

参考我之前写的另一篇 Open-falcon 自定义监控一些应用

其他服务监控 参考官网地址

,不觉得麻烦自己写就行。

各位小伙伴如果觉得还可以,请关注、点赞、收藏。感谢各位!

感兴趣吗?

欢迎联系我们,我们愿意为您解答任何有关IDC的疑难问题!