基于ELK的nginx-qps监控解决方案

先说说原理:

nginx-log中所有我们需要的信息,都是有的 。

比如user-agent .  http-refer ,  url   remote_addr 等等  . 

我们只需要把nginx-log中的信息进行计算和汇总即可。

效果展示

有人说,有日志了用awk/grep 什么的快速计算就行了 。 ansible+awk/grep 那都不是事

但面临两大困难点 

1.  我们的服务通常是多机 , 基于日志,使用脚本awk计算的话,只能得到单机性能,多机汇总是个问题;

2. 脚本计算的实时性,脚本计算基本无法实现 ;

当然这种nginx-qps监控什么的,肯定也有各路大神,通过其它方式完成过

今天在这里介绍的,是一种纯开源解决方案,对于开发能力不强的运维童鞋,那会是非常适宜的。

过程大约是这样

  1. nginx-log 以固定的json串的方式打印
  2. filebeat将日志以json方式发送到es
  3. 利用ES的计算能力,将日志按字段汇总起来
  4. 最后grafana/kibana 通过ES-API接口,获取数据后,展示到前台

假定你已经搭好 nginx服务和elk服务 , 下面我们来描述关键步骤

nginx - 日志的配置操作 . 定义一个nginx-log-format 为 json串形式的

log_format json '{"@timestamp":"$time_iso8601",'
                '"@version":"1",'
                '"server_addr":"$server_addr",'
                '"remote_addr":"$remote_addr",'
                '"host":"$host",'
                '"uri":"$uri",'
                '"body_bytes_sent":$body_bytes_sent,'
                '"bytes_sent":$body_bytes_sent,'
                '"upstream_response_time":$upstream_response_time,'
                '"request":"$request",'
                '"request_length":$request_length,'
                '"request_time":$request_time,'
                '"status":"$status",'
                '"http_referer":"$http_referer",'
                '"http_x_forwarded_for":"$http_x_forwarded_for",'
                '"http_user_agent":"$http_user_agent"'
                '}';

access_log  log/access.log   json ; 

输出的日志大约是这样
{"@timestamp":"2018-01-21T17:13:20+08:00","@version":"1","server_addr":"2.2.2.2","remote_addr":"1.1.1.1","host":"xxx.tencentyun.com","uri":"/interfaces/interface.php","upstream_response_time":0.131,"body_bytes_sent":312,"bytes_sent":489,"request":"POST /interfaces/interface.php HTTP/1.0","request_length":372,"request_time":0.238,"status":"200","http_referer":"-","http_x_forwarded_for":"-","http_user_agent":"-"}

配置filebeat 日志上报 filebeat.yml 

output.elasticsearch:
  hosts: ["your.elk.address:9200"]
  index: "%{[name]}-%{+yyyyMMdd}"

filebeat.prospectors:

## nginx相关日志的探测器
- input_type: log

  paths:
    - /data/log/tnginx_1_0_0-1.0/access.log 

  fields:
    name: "nginx_log_json"
    ## this is 自定义字段,方便后续按集群名字汇总。 当然也可以起其它名字
    cluster_name: web-access

 ## 一些filebeat的配置,包括从最后一行读取,文件自动释放FD等
 tail_files: true
 close_removed: true
 close_remane: true
 close_inactive: 1h
 ignore_older: 1h
  
  ##非常关键, 自定义的字段在root层。 这个后面稍后讲
  fields_under_root: true
  ##日志以json的方式进行本地解析, 拆词后的发送到filebeat 
  json.keys_under_root: true
  json.add_error_key: true

按上面的步骤配置后,nginx-access-log-json会被filebeat解析到一个一个分好的词,把数据上报到ES , 最后的日志结果类似这样:

{
  "_index": "nginx_log_json-20180121",
  "_type": "doc",
  "_id": "AWEX-dUURCyizcQtzIkX",
  "_score": null,
  "_source": {
    "@timestamp": "2018-01-21T09:12:23.525Z",
    "@version": "1",
    "beat": {
      "hostname": "100_125_96_55",
      "name": "100_125_96_55",
      "version": "5.5.0"
    },
##这一层就是root层, 所有的自定义变量会在这个层级上
    "body_bytes_sent": 1098,
    "bytes_sent": 1303,
    "cluster_name": "web-access",      ##这个是上面自定义的字段
    "host": "xxx.tencentyun.com",
    "http_referer": "-",
    "http_user_agent": "-",
    "http_x_forwarded_for": "-",
    "input_type": "log",
    "name": "nginx_log_json",
    "offset": 192139484,
    "remote_addr": "2.2.2.2",
    "request": "POST /interfaces/interface.php HTTP/1.1",
    "request_length": 432,
    "request_time": 0.045,
    "server_addr": "1.1.1.1",
    "source": "/data/log/tnginx_1_0_0-1.0/access.log",
    "status": "200",
    "type": "log",
    "upstream_response_time": 0.026,
    "uri": "/interfaces/interface.php"
  },
  "fields": {
    "@timestamp": [
      1516525943525
    ]
  },
  "highlight": {
    "cluster_name": [
      "@kibana-highlighted-field@trade@/kibana-highlighted-field@"
    ]
  },
  "sort": [
    1516525943525
  ]
}

kibana上搜索的结果会类似如下

kibana的绘图, 搜索和展示你认为有用的信息

比如,最近一段时间来源IP统计,比如最近一段平均请求时间

总之你能查询到数据,就能自定义你的视图展现

然后通过kibana的dashboarad给老板展示一个酷炫的报表

总结一下:

1.  nginx-log以json串的方式打印日志

2.  filebeat解析日志后,发送到es进行数据实时处理和分析

3. 利用kibana的功能,自定义数据报表

## FAQ 

F. 为什么日志要以json形式打印?  ELK本身也能解析日志拆词的? 

A: 如果日志是普通方式打印, 比如下面这样 ,就需要logstat  or es本身再对日志进行拆词,方式是形得通的。但我们用json打印后, filebeat就能直接解析上报,减少集中过滤带来的性能问题。 相信elk使用者,对于lostat的高CPU占用很头痛。

F: granafa的图表更酷炫,它能代替kibana进行数据展现吗? 

A: 是的,granfa的图表很好看, 它可以做为整个系统平台的有益补充,进行数据展现。 

大约方式是, 在granafa中定义一个数据源,然后用luence的语法查到数据后,然后展示在图表上。适合做数据报表,改动不大的情况, 比如下图的这种。 Kiaban的优势在于 非常高的自定义化,搜索条件可以自行输入。 比如  `status:>200 AND remote_addr:127.0.0.1` 这种组合, 会带你无尽的想像空间。 

F: elk汇总的数据延时是多少? 数据质量如何? 

A: 目前我们实测,100台8c8g500G的机器,支撑30k QPS数据写入,毫无压力 。如果换性能更好的机器,能得到更优的结果。  至于查询 , 应该是目前最好用的开源 全文日志搜索工具 ,  1000w行日志,实测30s内搜索得到结果,非常高效 . 

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云瓣

尝试造了个工具类库,名为 Diana

项目地址: diana 文档地址: http://muyunyun.cn/diana/ 造轮子的意义 为啥已经有如此多的前端工具类库还要自己造轮子呢?个人认...

4766
来自专栏Java进阶干货

微服务架构组件分析

服务描述:服务调用首先解决的问题就是服务如何对外描述。 常用的服务描述方式包括 RESTful API、XML 配置以及 IDL 文件三种。

1271
来自专栏用户2442861的专栏

高性能网络编程5--IO复用与并发编程

对于服务器的并发处理能力,我们需要的是:每一毫秒服务器都能及时处理这一毫秒内收到的数百个不同TCP连接上的报文,与此同时,可能服务器上还有数以十万计的最近几秒...

1081
来自专栏最高权限比特流

漫谈计算机组成原理(二)系统总线

从引言中,我们基本上能够了解到总线在计算机系统中的作用。但是上面的说法只是一个概论,我们需要给出更加详细的总线的作用:总线是计算机中各个部件的信息传输线。在计算...

3703
来自专栏北京马哥教育

Web性能压力测试工具http_load,webbench,ab,Siege详解

1. http_load http_load是基于linux平台的性能测试工具,它体积非常小,仅100KB。它以并行复用的方式运行,可以测试web服务器的吞吐量...

58811

3种提升云可扩展性的方法

部署在亚马逊的云服务器中被认为是实现高可扩展性的好方法,同时只需要为您所使用的计算能力支付费用。不过您要如何从技术中获得最佳的可扩展性呢?

26010
来自专栏深度学习那些事儿

深度学习-在ubuntu16.04安装CUDA9.1-总结(问题完全解决方案)

深度学习大火,为了赶上AI的班车,许多研究生本科生们都在搞深度学习。然而深度学习环境搭建必不可少,这篇文章是我多次为实验室搭建环境所积累起来的经验总结,希望所有...

6005
来自专栏Java架构师学习

你想了解的分布式--从ACID到CAP/BASE

本文先介绍传统关系数据库中事务的ACID特性,再介绍分布式系统中的经典理论——CAP定理和BASE理论。 事务 事务的定义: 事务(Transaction)是由...

3008
来自专栏地方网络工作室的专栏

打造前端MAC工作站(三)使用brew利用命令行安装软件

打造前端MAC工作站(三)使用brew利用命令行安装软件 前情回顾 打造前端MAC工作站(一)简单系统配置 打造前端MAC工作站(二)安装软件的两种方法 前...

21410
来自专栏Aloys的开发之路

Cache模拟器(CacheSim)

最近写了一个Cache的模拟器,由于平时空余时间比较分散,前前后后用了一周多的时间,基本实现的Cache的模拟功能(通过读取trace文件得到相应的命中率),能...

2867

扫码关注云+社区

领取腾讯云代金券