相信很多小伙伴都见过一些商业产品中的url接口响应时间,实时汇总显示功能。可以理解为web接口的慢查询,与sql的慢查询有异曲同工之妙,但是想做却无从入手不知道怎么实现此功能,所以今天就教大家如何实现用grafana+nginx+mysql来实现此功能。

0x0

其实nginx本身就带有接口响应时间的功能,只不过还需要改造下,比如说单独记录超过1000ms(1秒)的响应,并写入数据库中。要注意的是并不建议大家将记录直接写入数据库中,因为数据库有时会成为nginx的负担,间接写入即可。需要简单修改下log模块,涉及文件ngx_http_log_module.c 通常位于nginx-1.17.9/src/http/modules/ngx_http_log_module.c

大约838行, 找到ngx_http_log_request_time函数并修改如下:

static u_char *ngx_http_log_request_time(ngx_http_request_t *r, u_char *buf,    ngx_http_log_op_t *op){ngx_time_t *tp;ngx_msec_int_t ms;    time_t t = time(NULL);struct tm *loc_time = localtime(&t);tp = ngx_timeofday();u_char slow_log[2048];memset(slow_log, 0, sizeof(slow_log));ms = (ngx_msec_int_t) ((tp->sec - r->start_sec) * 1000+ (tp->msec - r->start_msec));ms = ngx_max(ms, 0);ngx_sprintf(slow_log, "%04d/%02d/%02d %02d:%02d:%02d %V %V?%V waste time %T.%03M",loc_time->tm_year + 1900, loc_time->tm_mon + 1, loc_time->tm_mday,loc_time->tm_hour, loc_time->tm_min, loc_time->tm_sec,&r->headers_in.server, &r->uri, &r->args, (time_t) ms / 1000,ms % 1000);int logfd;if ((logfd = open("/var/log/nginx/nginx_slow.log", O_RDWR | O_CREAT | O_APPEND,S_IRUSR | S_IWUSR)) == -1) {ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,"can not open file:logfile");}char Server_name[256];const char *server_name = "%.*s";memset(Server_name, 0, sizeof(Server_name));snprintf((char *) Server_name, sizeof(Server_name), server_name,r->headers_in.server.len, r->headers_in.server.data);/* 只记录大于1秒的并且域名不是grafana.sshfortress.com  */    if (ms > 1000 && strcmp("grafana.sshfortress.com", Server_name) != 0) write(logfd, slow_log, strlen((char *)slow_log));close(logfd);return ngx_sprintf(buf, "%T.%03M", (time_t) ms / 1000, ms % 1000);}

之后再编译即可

# ./configure --prefix=/usr/local/nginx1.17.9# make -j4 ; make install#mkdir -p /var/log/nginx; chmod -R 777 /var/log/nginx

简单配置下

server { listen *:80; server_name slow.sshfortress.com; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:3000; } }

启动nginx即可,如果接口响应时间超过1秒,那么 /var/log/nginx/nginx_slow.log 中就会有记录了。但这只是将慢查询记录而已,我们还需要排序以及可示化的展示。记录也可以直接写入mysql但我并没有这么做,为什么不直接写入呢,原因是如果mysql如果响应慢则会影响nginx的响应,但写入磁盘就不会出现这种情形了。接下来就简单实现下把数据同步写入到数据库中。

0x01

首先建个表 用于同步写入记录

 CREATE TABLE `nginx_slow` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `date` datetime NOT NULL,  `server_name` varchar(255) NOT NULL,  `url` varchar(255) NOT NULL,  `waste_time` decimal(11,3) NOT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

之后实现一个同步数据的工具,这里用shell即可实现,代码如下:

#!/bin/bash#    insert_mysql.shset -xif [ $# != 1 ]  then echo "Usage insert_mysql.sh /var/log/nginx/nginx_slow.log"  exit 1fitail -n 1 -f ${1}|while read vardo          value=`echo $var|awk '{print $3}'`         value2=`echo $var|awk '{print $4}'`         value3=`echo $var|awk '{print $7}'`         echo "$value $value2 $value3"         mysql -h 127.0.0.1 -usuper -pxxxxxxxxx -e "use nginx; INSERT INTO nginx_slow( date, server_name, url, waste_time) VALUES ( now(), '${value}', '${value2}', '$value3');"done

运行脚本就可以同步写入数据了,是不是很简单呢

# ./insert_mysql.sh /var/log/nginx/nginx_slow.log建议后台运行,因为要实时同步嘛# nohub ./insert_mysql.sh /var/log/nginx/nginx_slow.log >> /dev/null 2>&1 &

0x02

最后在grafana里面配置下当天接口慢查询TOP 20即可,相关语句是

select n.url,avg(n.waste_time) 平均响应时长 from nginx_slow nWHERE n.`date` > curdate()group by 1order by 2 desclimit 20或者 select n.server_name,n.url,avg(n.waste_time) 平均响应时长,count(1) 调用次数from nginx_slow nWHERE n.`date` > curdate()group by 1,2order by 3 desclimit 50

最后效果图如下

sql server排序慢_用Nginx实现接口慢查询并可示化展示TOP 20相关推荐

  1. Sql Server排序规则的简介、选择、应用

    用SQL语句查询当前数据库的默认排序规则 use db_name  exec sp_helpsort  go --以下转自:http://hi.baidu.com/jztchina/blog/item ...

  2. sql server表分区_介绍分区表SQL Server增量统计信息

    sql server表分区 If you are maintaining a very large database, you might be well aware of the pain to p ...

  3. 在SQL Server中为什么不建议使用Not In子查询

    原文:在SQL Server中为什么不建议使用Not In子查询 在SQL Server中,子查询可以分为相关子查询和无关子查询,对于无关子查询来说,Not In子句比较常见,但Not In潜在会带来 ...

  4. SQL Server 排序规则(摘)

    3Sql Server数据库,在跨库多表连接查询时,若两数据库默认字符集不同,系统就会返回这样的错误:"无法解决equal to操作的排序规则冲突" 一.错误分析: 这个错误是因为 ...

  5. sql server合并行_合并SQL Server复制参数化的行筛选器问题

    sql server合并行 In this article we will discuss about SQL Server Merge Replication Parameterized row f ...

  6. mysql的组内排序生成序号_sql 分组查询,组内排序, 组内添加序号 (SQL Server 排序函数 ROW_NUMBER和RANK 用法总结)...

    下面的例子和SQL语句均在SQL Server 2008环境下运行通过,使用SQL Server自带的AdventureWorks数据库. -- 添加序列号 -- 行号用法: ROW_NUMBER() ...

  7. SQL Server 排序函数 ROW_NUMBER和RANK 用法总结

    下面的例子和SQL语句均在SQL Server 2008环境下运行通过,使用SQL Server自带的AdventureWorks数据库. 转载请注明此文原创自 CSDN TJVictor的专栏:ht ...

  8. sql server java类型_使用基本 JDBC 数据类型 - SQL Server | Microsoft Docs

    使用基本数据类型Using basic data types 01/29/2021 本文内容 Microsoft JDBC Driver for SQL ServerMicrosoft JDBC Dr ...

  9. java sql server连接字符串_关于Java:SQL Server的等效jdbc连接字符串

    我目前正在使用以下连接字符串连接到数据库(该数据库与ServerIP在同一服务器上): String constr ="Data Source=ServerIP,1433;Network L ...

最新文章

  1. centos 安装php5.6
  2. extjs4 textfield width
  3. python3ide_Python IDE Windows下载3.4.2 安装版
  4. python续行_python中如何优雅续行和换行
  5. Tomcat下部署多个项目
  6. 一种真正意义上的Session劫持
  7. openmv 神经网络 超出内存_【openmv】openmv各种bug问题记录
  8. 小程序中曾经遇到的坑(1)----canvas画布
  9. 悬赏17万:美国“知乎”的沙雕问题,需要AI来识别
  10. Java集合(一) —— ArrayList
  11. utuntu 视频 无声
  12. Ubuntu18.04安装npm失败解决
  13. 未能正确加载包“Microsoft.Data.Entity.Design.Package.MicrosoftDataEntityDesignPackage
  14. 记录一次使用ghidra逆向分析斐讯K3官改固件web登录验证的经历
  15. visio使用手册---网络拓扑图的利器
  16. Xilinx Petalinux安装和使用
  17. foobar2000在线标签服务器,在Foobar2000播放器中从音乐名获取标签的技巧
  18. Windows10 启动 Docker Desktop 时报错 Containers feature is disabled
  19. 关于达梦数据库认证介绍
  20. Genesis公链加速区块链行业发展

热门文章

  1. Docker使用自定义网络实现容器互联
  2. Python3学习笔记-面向对象
  3. Linux下Tomcat的启动、关闭、杀死进程
  4. 自定义标签 tag AttachTag 实现附件jsp方便的显示和下载
  5. SDRAM 相关资料
  6. ASP.NET 开发知识小结
  7. 基于Springboot实现就业管理系统
  8. KS003基于JSP和Servlet实现的商城系统
  9. matplotlib画图绘制辅助线
  10. UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x80 in position 658: illegal multibyte sequence