前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Nginx模块开发:http handler实现流量统计(入门篇)

Nginx模块开发:http handler实现流量统计(入门篇)

作者头像
Lion 莱恩呀
发布于 2025-01-11 04:08:54
发布于 2025-01-11 04:08:54
15100
代码可运行
举报
概述
本文将带你入门Nginx模块开发,聚焦于使用HTTP handler实现流量统计。从Nginx模块的基本概念入手,逐步讲解如何创建一个简单的handler模块,用于捕获请求并记录相关信息,例如请求次数和请求大小。
文章被收录于专栏:后端开发技术后端开发技术
运行总次数:0
代码可运行

一、Nginx模块之http handler简介

Nginx通过模块化的方式提供了丰富的功能扩展能力。其中,HTTP Handler是Nginx模块开发中非常重要的一个概念。HTTP Handler可以用来拦截、处理和操作传入的HTTP请求,在请求的生命周期中执行特定的逻辑。它可以用于实现各种功能,如流量统计、访问控制、缓存管理等。

通过使用HTTP Handler,可以自定义和扩展Nginx的功能,根据具体需求进行灵活的定制。HTTP Handler可以通过Nginx模块的代码编写和配置来实现,无需修改或重新编译Nginx的核心代码。

当nginx解析conf文件时,可以为cmd加上handler。

在本文中探讨如何使用Nginx模块开发来实现流量统计功能。从基础的HTTP Handler编写开始,逐步引导完成一个简单而功能强大的流量统计模块。

让我们一起探索Nginx模块开发中的HTTP Handler,并为网站添加流量统计功能提供强大的基础!

二、Nginx handler模块开发

2.1、示例代码

代码中在重点地方带有详细的注释。

代码语言:C
换行
代码运行次数:0
自动换行
运行AI代码解释
#include <ngx_config.h> #include <ngx_http.h> #include <ngx_core.h> #include <arpa/inet.h> #include <netinet/in.h> /* * ip的访问次数存放在一个key-value数据结构里面,ip是key,value是统计的次数 * 可用的数据结构: * hash * rbtree * 最简单的是数组 */ typedef struct { int count; struct in_addr addr; }ngx_pv_table; ngx_pv_table pv_table[256] = { 0 }; //这只适合局域网内存储,正在的数据结构最好用rbtree // 重新组织网页 (网页组包) void ngx_encode_http_page(char *html) { sprintf(html, "<h1>Hello, NGX handler! I am FLY.</h1>"); strcat(html, "<h2>"); int i = 0; for (i = 0; i < 256; i++) { if (pv_table[i].count != 0) { char str[INET_ADDRSTRLEN] = { 0 }; char buffer[128] = { 0 }; sprintf(buffer, "req from : %s, count: %d <br/>", inet_ntop(AF_INET, &pv_table[i].addr, str, sizeof(str)), pv_table[i].count); strcat(html, buffer); } } strcat(html, "</h2>"); } ngx_int_t ngx_http_count_handler(ngx_http_request_t *r) { // 这里做统计功能 // 获取ip地址 struct sockaddr_in *cliaddr = (struct sockaddr_in *)r->connection->sockaddr; // 地址和我们看到的是反着的,通过右移得到ip地址的末尾.符号后面那个位数 int idx = cliaddr->sin_addr.s_addr >> 24; pv_table[idx].count++; memcpy(&pv_table[idx].addr, &cliaddr->sin_addr, sizeof(cliaddr->sin_addr)); // 重新组织网页 u_char html[1024] = { 0 }; int len = sizeof(html); ngx_encode_http_page((char*)html); /* * 发送http响应 */ r->headers_out.status = 200; ngx_str_set(&r->headers_out.content_type, "text/html"); // 发送http 头 ngx_http_send_header(r); // 内存池拿出一个buffer的内存空间 ngx_buf_t *b = ngx_palloc(r->pool, sizeof(ngx_buf_t)); b->pos = html; b->last = html + len; b->memory = 1;//内存里操作 b->last_buf = 1;//最后内存块 // 缓冲链 ngx_chain_t out; out.buf = b; out.next = NULL; return ngx_http_output_filter(r, &out); } char *ngx_http_handler_count_set(ngx_conf_t *cf,ngx_command_t *cmd,void *conf) { ngx_http_core_loc_conf_t *ccf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); // 设置handler的入口函数 ccf->handler = ngx_http_count_handler; memset(pv_table, 0, sizeof(pv_table)); return NGX_OK; } // conf文件中的每一行都是一个指令指令 ngx_command_t ngx_http_handler_module_cmd[] = { { //命令名称,比如listen,定义了就可以在conf文件中使用,注意不能和其他的起冲突 ngx_string("count"), // 指示name命令放的位置在哪里以及可以带多少个参数,NGX_CONF_FLAGE表示开关标志 // predix on/off NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS, // 命令解析,可以使用nginx内部的也可以自己实现 ngx_http_handler_count_set,//ngx_http_handler_set_slot, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL, }, ngx_null_command }; // 用来解析对应的conf文件 static ngx_http_module_t ngx_http_handler_module_ctx = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; // 模块定义 ngx_module_t ngx_http_handler_module = { NGX_MODULE_V1, &ngx_http_handler_module_ctx, ngx_http_handler_module_cmd, // http的ascii值,指示是什么模块 NGX_HTTP_MODULE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NGX_MODULE_V1_PADDING // 填充 };

2.2、编写config文件

创建:

代码语言:Bash
换行
自动换行
AI代码解释
touch config

内容:

代码语言:Bash
换行
自动换行
AI代码解释
ngx_addon_name=ngx_http_handler_module HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES ngx_http_handler_module" NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_handler_module.c"

注意,config文件要和模块的代码在相同目录。

2.3、编译模块到Nginx源码中

(1)配置中添加模块:

代码语言:Bash
换行
自动换行
AI代码解释
./configure --prefix=/usr/local/nginx --with-http_realip_module --with-http_addition_module --with-http_gzip_static_module --with-http_secure_link_module --with-http_stub_status_module --with-stream --with-pcre=/home/fly/workspace/pcre-8.41 --with-zlib=/home/fly/workspace/zlib-1.2.11 --with-openssl=/home/fly/workspace/openssl-1.1.0g --add-module=/mnt/hgfs/sourcecode_learning/ngx_http_handler_module

注意模块路径要正确。出现如下表示成功:

代码语言:Bash
换行
自动换行
AI代码解释
configuring additional modules adding module in /mnt/hgfs/sourcecode_learning/ngx_http_handler_module + ngx_http_handler_module was configured creating objs/Makefile

(2)查看是否添加模块到动态代码中:

代码语言:Bash
换行
自动换行
AI代码解释
cat objs/ngx_modules.c

(3)编译安装:

代码语言:Bash
换行
自动换行
AI代码解释
make sudo make install

2.4、修改conf文件

编译安装完成后,conf文件添加count;

代码语言:JSON
换行
自动换行
AI代码解释
worker_processes 4; events { worker_connections 1024; } http { upstream backend { server 192.168.7.146:8889; server 192.168.7.146:8890; } server { listen 8888; location / { proxy_pass http://backend; } } server { listen 8889; location / { count; } } server { listen 8890; } server { listen 8891; } }

2.5、执行效果

代码语言:Bash
换行
自动换行
AI代码解释
sudo /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/fly.conf

在网页输入IP和端口,执行效果如下:

可以看到,返回的网页中多出了访问次数统计。

三、Nginx的热更新

(1)conf文件热更新:通过reload指令进行重新加成conf文件。reload过程中是重新开启新的进程来加载新的conf文件;比如原来有4个进程在运行,加载新的conf文件时就重新开启4个进程来加载新的配置文件。(2)可执行程序的热更新:编译安装新的nginx,会把原来的nginx重命名为nginx.old,然后调用nginx reload就会更新。

四、总结

  1. 上述代码虽然实现了IP访问服务器的流量统计;但是,Nginx是多进程的,上述示例代码没有实现统计数在进程间的共享,这回造成其他进程是重新计数的问题。解决这个问题可以使用共享内存的方式在进程间通信。

  2. 上述代码使用了最简单的数据结构:数组。这不是好的决策,可以将其改为红黑树。

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

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Nginx模块开发:http handler实现流量统计(进阶篇)
Nginx通过模块化的方式提供了丰富的功能扩展能力。其中,HTTP Handler是Nginx模块开发中非常重要的一个概念。HTTP Handler可以用来拦截、处理和操作传入的HTTP请求,在请求的生命周期中执行特定的逻辑。它可以用于实现各种功能,如流量统计、访问控制、缓存管理等。
Lion 莱恩呀
2025/01/12
2100
Nginx模块开发:http handler实现流量统计(进阶篇)
Nginx模块开发:自定义HTTP过滤器filter
/src/http/ngx_http_config.h中定义的相关宏(type会用到):
Lion 莱恩呀
2025/01/07
4130
Nginx模块开发:自定义HTTP过滤器filter
编写 Nginx 模块进行 RSA 加解密
在《Nginx 模块系统:前篇》一文中,曾提过要展开聊聊如何编写和编译一个 Nginx 模块。
soulteary
2021/08/16
2K0
编写 Nginx 模块进行 RSA 加解密
nginx0.1.0之http模块初始化源码分析(1)
http模块的初始化类似event模块,初始化的起点在解析到http指令的时候。对应的处理函数是ngx_http_block,因为该函数比较长,所以我们分段解析。第一部分先解析http模块的pre_conf、create_main_conf函数的实现。
theanarkh
2019/03/06
6040
nginx0.1.0之http模块初始化源码分析(4)
我们继续分析ngx_http_block函数剩余的代码,剩下的代码就是处理phases和监听的端口、地址、servername的。
theanarkh
2019/03/06
4330
nginx源代码分析–模块分类
比方。对一个普通的訪问本地静态文件的请求处理,从 Nginx 收到请求并開始处理。到处 理结果的响应包体发送到网络上结束,整个过程的两个步骤 – 请求处理和响应处理 – 分别 由 handler 和 filter 处理完毕。
全栈程序员站长
2022/07/07
7470
Nginx 第三方模块使用与开发
Nginx 允许引入第三方模块来扩展 Nginx 的功能。官方网站 NGINX 3rd Party Modules 列出了 Nginx 很多的第三方模块。除此之外,很多很有用的模块也能在 github 等网站上找到。
Se7en258
2021/07/01
2.5K0
Nginx解读内置非默认模块 ngx_http_stub_status_module
http://nginx.org/en/docs/http/ngx_http_stub_status_module.html
星哥玩云
2022/07/24
8790
深入理解nginx的请求限流模块
  当构建高流量的Web应用程序时,保护服务器免受过多请求的影响是至关重要的。过多的请求可能会导致服务器过载,降低性能甚至导致系统崩溃。为了解决这个问题,nginx提供了一个强大的请求限速模块。该模块允许您根据自定义规则限制客户端请求的速率,并且还可以使用延迟机制来平滑处理超出限制的请求。在本文中,我们将深入探讨nginx的请求限速模块,了解它的工作原理、配置选项以及如何在实际应用中使用它来保护您的服务器免受恶意或异常请求的影响。
码农心语
2024/04/09
1.1K0
深入理解nginx的请求限流模块
nginx的timeout(基于nginx1.17.9)
nginx中使用timeout的地方非常多,本文主要分析客户端和nginx通信时涉及到的几个timeout。
theanarkh
2020/06/19
8410
接入层Nginx架构及模块介绍分享
1)帮助大家对Nginx有一定的认识 2)熟悉Nginx有哪些应用场景 3)熟悉Nginx特点和架构模型以及相关流程 4)熟悉Nginx定制化开发的几种模块分类
Lucien168
2020/07/20
9550
接入层Nginx架构及模块介绍分享
深入理解nginx mp4流媒体模块[上]
  在当今数字化时代,视频已成为互联网上最主要的内容形式之一。NGINX作为一款高性能的Web服务器和反向代理服务器,提供了强大的MP4模块,用于优化MP4视频的点播传输功能,并支持播放器的任意拖拽功能。本文将通过通过源码分析深入探讨NGINX MP4模块的实现源码,介绍其功能和实现原理。
码农心语
2024/04/09
1.2K0
深入理解nginx mp4流媒体模块[上]
Nginx模块之Upstream解析
Nginx模块一般被分成三大类:handler、filter和upstream。前面的文章系列中,读者已经了解了handler、filter。利用这两类模块,可以使nginx轻松完成任何单机工作。而本文介绍的upstream模块,将使nginx跨越单机的限制,完成网络数据的接收、处理和转发。 数据转发功能,为nginx提供了跨越单机的横向处理能力,使nginx摆脱只能为终端节点提供单一功能的限制,而使它具备了网路应用级别的拆分、封装和整合的战略功能。在云模型大行其道的今天,数据转发是nginx有能力构建一个
用户1263954
2018/01/30
2.4K0
Nginx模块之Upstream解析
聊聊nginx的keepalive_time参数
nginx/src/http/ngx_http_header_filter_module.c
code4it
2023/12/05
3250
Nginx(三):http模块的处理流程解析之正向代理
无疑,在nginx的核心服务中,http服务占据了相当大的份量。那么,要想多了解nginx多一点,则必须要了解其http模块的工作机制。
烂猪皮
2021/01/28
2K0
Nginx(三):http模块的处理流程解析之正向代理
nginx0.1.0 access_handler模块源码分析
access模块主要是对连接到nginx中的客户端进行权限管理,nginx会根据access模块注册的命令,在解析命令的时候,遇到对应的命令的时候,会调用access注册的处理函数,access模块的处理函数会解析并记录这些配置,然后在每个连接到来时,判断ip是否在封禁的池子了。nginx只判断deny的规则,即同一个ip命中多条规则的时候,只要有一条是deny则结果就是deny。即deny优先。
theanarkh
2019/04/24
4160
解读Nginx:深入剖析HTTP启动流程
1、遇到conf文件的http模块。http不是在Nginx的mian函数中启动,而是解析conf文件时遇到http才会去解析并启动。
Lion 莱恩呀
2025/01/08
1400
解读Nginx:深入剖析HTTP启动流程
nginx源码阅读(6)http处理流程
Nginx作为一款开源的、高性能的HTTP服务器和反向代理服务器而闻名,本文基于nginx-1.15.0,将为读者简要介绍其HTTP处理流程。
golangLeetcode
2022/08/02
1.2K0
nginx源码阅读(6)http处理流程
Nginx(六):配置解析之location解析
nginx成为非常流行的代理服务软件,最根本的原因也许是在于其强悍性能。但还有一些必要的条件,比如功能的完整,配置的易用,能够解决各种各样的实际需求问题,这些是一个好的软件的必备特性。
烂猪皮
2021/01/28
2K0
Nginx(六):配置解析之location解析
Nginx(二): worker 进程处理流程框架解析
Nginx 启动起来之后,会有几个进程运行:1. master 进程接收用户命令并做出响应; 2. worker 进程负责处理各网络事件,并同时接收来自master的处理协调命令;
烂猪皮
2021/01/28
1.4K0
Nginx(二): worker 进程处理流程框架解析
相关推荐
Nginx模块开发:http handler实现流量统计(进阶篇)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验