每日一博 | 用 Nginx 实现接口慢查询并可示化展示 TOP 20
相信很多小伙伴都见过一些商业产品中的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\n", 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\n"); } 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.sh set -x if [ $# != 1 ] then echo "Usage insert_mysql.sh /var/log/nginx/nginx_slow.log" exit 1 fi tail -n 1 -f ${1}|while read var do 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 n WHERE n.`date` > curdate() group by 1 order by 2 desc limit 20 或者 select n.server_name,n.url,avg(n.waste_time) 平均响应时长,count(1) 调用次数 from nginx_slow n WHERE n.`date` > curdate() group by 1,2 order by 3 desc limit 50
最后效果图如下
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Qt 5.15 LTS 发布
Qt 5.15 LTS 已经发布了,这是 Qt 5 系列的最后一个功能版本,为下一个主要版本 Qt 6 做了大量准备工作。此版本将为所有商业许可证持有者提供三年的长期支持,在三年的支持期后,可以选择提供扩展支持,而对于开源用户,它将以与其它常规 Qt 版本相同的方式得到支持,直到 Qt 6 发布为止。此版本亮点包括: 抽象 3D 图形 API 过去的一年中,开发团队一直在努力对图形技术栈的架构进行全面改造。此版本带来了研发一年多的 Qt 渲染硬件接口(RHI,Rendering Hardware Interface),它是 OpenGL、Metal 与 Direct 3D等不同平台 3D API 的抽象层,可用于在 Direct 3D、Metal 和 Vulkan 以及 OpenGL 之上运行 Qt Quick 应用程序。 这是 Qt 5.15 中的技术预览支持,可以通过环境变量启用,而在 Qt 6 中,这一层将构成 Qt 架构的核心部分。 Qt Quick 3D Qt Quick 简化了基于触摸的动画 2D 用户界面的创建,现在Qt 5.15 带来了Qt Quick 3D,它扩展了易...
- 下一篇
微软开源 Tye 项目,可简化微服务开发
微软近期开源了一款开发人员工具 Tye,能够用于简化微服务以及分布式应用程序的开发、测试以及部署过程。 该项目负责人Amiee表示,在构建由多个项目组成的应用程序时,开发者通常希望能够同时运行多个程序或服务。这仅仅是构建分布式应用程序的第一步,但实施起来可能有些困难,更不用说在之后将这些程序移植到Kubernetes 等平台上的难度。因此,Tye 项目旨在让这些过程更加轻松。 Tye 的首要目标是简化微服务的开发,具体方式包括仅用一行命令执行多项服务、在容器中使用依赖项目,以及使用简单的方法探索其他服务的地址。 将 .NET 应用程序自动部署到 Kubernetes也是 Tye 的一大用途。该项目通过自动容器化 .NET 应用程序、降低生成 Kubernetes 清单的配置要求,还有使用单个配置文件来达成此目标。Tye包含一个本地协调器,从而以最少的配置将微服务部署到 Kubernetes。 Tye 现已集成了 Ingress、Redis、Dapr、Zipkin和 Elastic Stack等项目,它目前仍处于实验阶段,这一阶段预计将持续至.NET 5 发行之时。在此期间,微软计划每个...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS6,CentOS7官方镜像安装Oracle11G
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8编译安装MySQL8.0.19
- CentOS6,7,8上安装Nginx,支持https2.0的开启