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

news2024/11/29 0:54:01

Nginx模块开发之http handler实现流量统计

  • 一、Nginx模块之http handler简介
  • 二、Nginx handler模块开发
    • 2.1、示例代码
    • 2.2、编写config文件
    • 2.3、编译模块到Nginx源码中
    • 2.4、修改conf文件
    • 2.5、执行效果
  • 三、Nginx的热更新
  • 总结
  • 后言

一、Nginx模块之http handler简介

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

二、Nginx handler模块开发

2.1、示例代码

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


#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文件

创建:

touch config

内容:

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)配置中添加模块:

./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

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

configuring additional modules
adding module in /mnt/hgfs/sourcecode_learning/ngx_http_handler_module
 + ngx_http_handler_module was configured
creating objs/Makefile

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

cat objs/ngx_modules.c

(3)编译安装:

make
sudo make install

2.4、修改conf文件

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


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、执行效果

sudo /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/fly.conf 

在网页输入IP和端口,执行效果如下:
ngx_handler_show
可以看到,返回的网页中多出了访问次数统计。

三、Nginx的热更新

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

总结

  1. 上述代码虽然实现了IP访问服务器的流量统计;但是,Nginx是多进程的,上述示例代码没有实现统计数在进程间的共享,这回造成其他进程是重新计数的问题。解决这个问题可以使用共享内存的方式在进程间通信。
  2. 上述代码使用了最简单的数据结构:数组。这不是好的决策,可以将其改为红黑树。

后言

本专栏知识点是通过<零声教育>的系统学习,进行梳理总结写下文章,对c/c++linux系统提升感兴趣的读者,可以点击链接,详细查看详细的服务:C/C++服务器课程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/26635.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机毕业设计之java+ssm手机综合类门户网站

项目介绍 手机综合类门户网站采用ssm框架和eclipse编辑器、MySQL数据库设计并实现的,主要包括系统手机评测管理模块、文章管理模块、手机新闻管理、所有评论管理、登录模块、和退出模块等多个模块。 管理员的登录模块&#xff1a;管理员登录系统对本系统其他管理模块进行管理。…

2016-2021年各省高考分数线

2016-2021年各省高考分数线 包含各省市不同招生类别的高考分数线&#xff0c;包括普通本科、特殊类型招生、艺术类本科、体育类本科、普通专科的分数线。 普通高等学校招生全国统一考试&#xff08;Nationwide Unified Examination for Admissions to General Universities a…

网络防火墙入门

防火墙的作用&#xff1f; 防止从外向内的网络入侵行为的策略。后来&#xff0c;防火墙不但用于防范外网&#xff0c;例如&#xff1a;对企业内网的 DoS 攻击或非法访问等&#xff0c;也开始防范从内部网络向互联网泄露信息、把内部网络作为攻击跳板等行为。 什么是代理服务器…

Hash表(哈希表、散列表)

哈希表 概念 为什么需要哈希表 静态查找表与动态查找表中&#xff0c;为了查找某关键字值等于某个值的记录&#xff0c;都要经过一系列的关键字进行比较&#xff0c;以确定待查记录的储存位置或查找失败&#xff0c;查找的时间总是与比较次数有关 什么是哈希表 哈希表&…

[附源码]java毕业设计校园征兵及退役复原管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

视听杂志视听杂志社视听编辑部2022年第11期目录

专题:对外传播 共塑与去精英化&#xff1a;国家形象建构的实践创新——基于纪录片《柴米油盐之上》的多模态分析 董星雨;程欣;刘苏情; 3-7《视听》投稿&#xff1a;cnqikantg126.com 网络赋权下抖音国际版TikTok的海外传播策略探析 吴梦玲; 7-10 以画对话&#xff…

m3u8 文件格式详解

简介 M3U8 是 Unicode 版本的 M3U&#xff0c;用 UTF-8 编码。"M3U" 和 "M3U8" 文件都是苹果公司使用的 HTTP Live Streaming&#xff08;HLS&#xff09; 协议格式的基础&#xff0c;这种协议格式可以在 iPhone 和 Macbook 等设备播放。上述文字定义来自于…

一文玩转Java 泛型知识

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;前端开发者…

青岛品质水稻共养 国稻种芯·中国水稻节:山东西海岸收获季

青岛品质水稻共养 国稻种芯中国水稻节&#xff1a;山东西海岸收获季 半岛全媒体记者 孟达 新闻中国采编网 中国新闻采编网 谋定研究中国智库网 中国农民丰收节国际贸易促进会 国稻种芯中国水稻节 中国三农智库网-功能性农业农业大健康大会报道&#xff1a;山东青岛西海岸新区王…

发了3000个短视频作品才总结出的9点快速破播放的技巧

大家好&#xff0c;我是我赢助手&#xff0c;专注于自媒体短视频去水印、去重和文案提取运营。 今天给大家分享下发了3000个短视频作品才总结出的9点快速破播放的技巧&#xff1a; 1、前期养号: 新号创建前7天不要急着发作品&#xff0c;刷兴趣标签养号&#xff0c;能让账号…

【机器学习】数据驱动方法在电网稳定分析应用浅谈

目录 一、数据驱动概述 二、数据驱动特点 三、数据驱动与其他方法对比 四、总结 五、参考文献 一、数据驱动概述 数据驱动在电力系统稳定分析中的应用&#xff0c;主要目标是从电网运行数据角度建立电力系统稳定分析模型&#xff0c;以数据之间的关联性分析视角挖掘电力系…

MySQL数据库期末考试试题及参考答案(08)

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 一、 填空题 MySQL用户变量由符号____和变量名组成。MySQL中____循环语句会无条件执行一次语句列表。DELIMITER语句可以设置MySQL的____。MySQL中打开游标使用____关键字。…

基于PaddleOCR的集装箱箱号检测识别

基于PaddleOCR的集装箱箱号检测识别 项目背景 国际航运咨询分析机构 Alphaliner 在今年 3 月公布的一组数据&#xff0c;2021 年集装箱吞吐量排名前 30 的榜单中&#xff0c;上海港以 4702.5 万标箱的「成绩单」雄踞鳌头。 较上一年同期&#xff0c;上海港集装箱吞吐量增长 8…

在host上窥探kvm虚拟机内存

1. kvm内存虚拟化 kvm虚拟机的内存虚拟化&#xff0c;使用了内存转换技术&#xff0c;过程如下&#xff1a;GVA -> GPA -> HVA -> HPA 通过qemu启动了一个8G内存的虚拟机&#xff0c;查看内存smaps&#xff0c;可以发现有个内存就是8G&#xff0c;这个就是guest所使用…

Pioneer | X METAVERSE PRO Explores the New Value of “Mining + Finance“

“The mining boom driven by Bitcoin has created many wealth myths: miners can earn 50 BTC every 10 minutes at that time. If you successfully get a Bitcoin block and hold it since 2009, you will have BTC worth $827,930 in your wallet by 2022. “ Cryptocurr…

AE插件:Composite Brush Mac(画面颜色选取替换修改)

Composite Brush for Mac是一款由AEscripts出品的AE画面颜色选取替换修改插件&#xff0c;可以直接在视频画面上选取颜色&#xff0c;然后对选择部分修改替换成自己需要的颜色&#xff0c;有了Composite Brush插件用户可以直接在视频画面上选取自己想要的颜色。 单击并拖动&am…

图像运算和图像增强十一

图像运算和图像增强十一 图像锐化之 Scharr、Canny、LOG 实现边缘检测 &#xff08;1&#xff09;Scharr算子 Scharr算子又称为Scharr滤波器&#xff0c;也是计算x或y方向上的图像差分。Scharr 算子的函数原型如下所示&#xff0c;和 Sobel 算子几乎一致&#xff0c;只是没有…

服务器的区别跟服务器被攻击了怎么解决

大陆服务器都是需要备案的&#xff0c;想必这是众所周知的&#xff0c;备案的过程繁琐且严格。除此之外&#xff0c;备案还有期限的限制&#xff0c;若网站没有在规定的期限内完成备案&#xff0c;可能会导致我们不能在相应的时间内完成建站。而海外服务器是不存在备案的问题的…

【读论文】DIVFusion: Darkness-free infrared and visible image fusion

【读论文】DIVFusion: Darkness-free infrared and visible image fusion介绍网络结构SIDNet损失函数TCEFNetGRM&#xff08;梯度保持模块&#xff09;CEM&#xff08;对比度增强模块&#xff09;损失函数总结参考论文&#xff1a;https://www.sciencedirect.com/science/artic…

IPv6与VoIP——ipv6接口标识与VoIP概述

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.ipv6接口标识符 1.IPv6接口标识符有以下几种 基于EUI-64地址…