开发一个简单的http模板之序章

news2024/11/15 5:06:05

流程

1.当通过开发 HTTP 模块来实现产品功能时,是可以完全享用 Nginx 的优秀设计所带来的、
与官方模块相同的高并发特性的。不过,如何开发一个充满异步调用、无阻塞的 HTTP 模块
2. 需要把程序嵌入到Nginx中,也就是说,最终编译出的二进制程序Nginx要包含我
们的代码
3.个全新的HTTP 模块要能介入到 HTTP 请求的处理流程中
4.我们的模块才能开始处理 HTTP 请求,但在开始处理请求前还需要先了解一些Nginx 框架定义的数据结构
5.正式处理请求时,还要可以获得 Nginx 框架接收、解析后的用户请求信息
6.业务执行完毕后,则要考虑发送响应给用户
7包括将磁盘中的文 件以HTTP 包体的形式发送给用户

调用模板

首先需要了解典型的 HTTP 模块是如何介入 Nginx 处理用户请求流 程的。下图是一个简化的时序图,这里省略了许多异步调用,忽略了多个不同的 HTTP 处理阶段,仅标识了在一个典型请求的处理过程中主要模块被调用的流程,以此帮助读者理解 HTTP模块如何处理用户请求。

worker进程会在一个for 循环语句里反复调用事件模块检测网络事件
事件模块检测到某个客户端发起的TCP 请求时(接收到 SYN 包),将会为它建立 TCP 连 接,
成功建立连接后根据nginx.conf文件中的配置会交由HTTP框架处理HTTP框架会试图接收完整的HTTP头部,并在接收到完整的HTTP头部后将请求分发到具体的HTTP模块中处理
处理策略: 其中最常见的是根据请求的URI nginx.conf location 配置项
的匹配度来决定如何分发
HTTP 模块在处理请求的结束时,大多会向客户端发送响应,此时会自动地依次调
用所有的 HTTP 过滤模块,每个过滤模块可以根据配置文件决定自己的行为

准备工作

Nginx模块需要使用C(或者C++)语言编写代码来实现,每个模块都要有自己的名字。 按照Nginx约定俗成的命名规则,我们把第一个HTTP模块命名为ngx_http_mytest_module。由 于第一个模块非常简单,一个C源文件就可以完成

为了做到跨平台,Nginx定义、封装了一些基本的数据结构。由于Nginx对内存分配比较“吝啬(只有保证低内存消耗,才可能实现十万甚至百万级别的同时并发连接数),所以 这些Nginx数据结构天生都是尽可能少占用内存。(看我nginx源码解析即可)

如何将自己的HTTP模块编译进Nginx

方法一 config文件 

Nginx 提供了一种简单的方式将第三方的模块编译到 Nginx 中。首先把源代码文件全部放
到一个目录下,同时在该目录中编写一个文件用于通知 Nginx 如何编译本模块,这个文件名
必须为 config

config写法

  config文件其实是一个可执行的Shell脚本。如果只想开发一个HTTP模块,那么config文 件中需要定义以下3个变量

·ngx_addon_name:仅在configure执行时使用,一般设置为模块名称。
·HTTP_MODULES:保存所有的HTTP模块名称,每个HTTP模块间由空格符相连。在
重新设置HTTP_MODULES变量时,不要直接覆盖它,因为configure调用到自定义的config脚
本前,已经将各个HTTP模块设置到HTTP_MODULES变量中了,因此,要像如下这样设
"$HTTP_MODULES ngx_http_mytest_module"
  NGX_ADDON_SRCS:用于指定新增模块的源代码,多个待编译的源代码间以空格
符相连。注意,在设置NGX_ADDON_SRCS时可以使用$ngx_addon_dir变量,它等价于
configure执行时--add-module=PATH的PATH参数
总的文件
ngx_addon_name=ngx_http_mytest_module
HTTP_MODULES="$HTTP_MODULES ngx_http_mytest_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest_

下面完整地解释一下configure上文提到的config文件配合起来把定制的 第三方模块加入到Nginx中的:

configure --add-module=PATh(config文件)
   "ngx_http_uwsgi_module",
    "ngx_http_scgi_module",
    "ngx_http_memcached_module",
    "ngx_http_empty_gif_module",
    "ngx_http_browser_module",
    "ngx_http_upstream_hash_module",
    "ngx_http_upstream_ip_hash_module",
    "ngx_http_upstream_least_conn_module",
    "ngx_http_upstream_keepalive_module",
    "ngx_http_upstream_zone_module",
    "ngx_http_mytest_mudule",//我们自己的
    "ngx_http_write_filter_module",
    "ngx_http_header_filter_module",
    "ngx_http_chunked_filter_module",
    "ngx_http_range_header_filter_module",
    "ngx_http_gzip_filter_module",
    "ngx_http_postpone_filter_module",
    "ngx_http_ssi_filter_module",
    "ngx_http_charset_filter_module",
    "ngx_http_userid_filter_module",
    "ngx_http_headers_filter_module",
    "ngx_http_copy_filter_module",
    "ngx_http_range_body_filter_module",
    "ngx_http_not_modified_filter_module",

在执行configure--add-module=PATH命令时,PATH就是第三方模块所在的路径。在configure中,通过auto/options脚本设置了NGX_ADDONS变量

方法二 修改makefile

  我们有时可能需要更灵活的方式,比如重新决定ngx_module_t*ngx_modules[] 数组中各个
模块的顺序,或者在编译源代码时需要加入一些独特的编译选项,那么可以在执行完 configure后,对生成的 objs/ngx_modules.cobjs/Makefile文件直接进行修改。
在修改 objs/ngx_modules.c 时,首先要添加新增的第三方模块的声明,如下所示:
extern ngx_module_t ngx_http_mytest_module;
其次,在合适的地方将模块加入到 ngx_modules 数组中
ngx_module_t *ngx_modules[] = {
…
&ngx_http_upstream_ip_hash_module,
&ngx_http_mytest_module,
&ngx_http_write_filter_module,
…
NULL
};

note:

模块的顺序很重要。如果同时有两个模块表示对同一个请求感兴趣,那么只有顺
序在前的模块会被调用。
修改 objs/Makefile 时需要增加编译源代码的部分,例如:
objs/addon/httpmodule/ngx_http_mytest_module.o: $(ADDON_DEPS) \
../sample/httpmodule// ngx_http_mytest_module.c
$(CC) -c $(CFLAGS) $(ALL_INCS) \
-o objs/addon/httpmodule/ngx_http_mytest_module.o \
../sample/httpmodule// ngx_http_mytest_module.c
还需要把目标文件链接到 Nginx 中,例如:
objs/nginx: objs/src/core/nginx.o \
...
objs/addon/httpmodule/ngx_http_mytest_module.o \
objs/ngx_modules.o
$(LINK) -o objs/nginx \
objs/src/core/nginx.o \
...
objs/addon/httpmodule/ngx_http_mytest_module.o \
objs/ngx_modules.o \
-lpthread -lcrypt -lpcre -lcrypto -lcrypto -lz

推荐方法一:因为请慎用这种直接修改Makefilengx_modules.c的方法,不正确的修改可能导致Nginx工作 不正常。

拓展知识

关于利用configure过程中发生了什么

结果:

creating objs/Makefile
auto/make: line 420: syntax error near unexpected token `then'
auto/make: line 420: `        if{$ext="cpp"};then'

Configuration summary
  + using system PCRE library
  + OpenSSL library is not used
  + using system zlib library

  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx/conf"
  nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/usr/local/nginx/logs/error.log"
  nginx http access log file: "/usr/local/nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"
1 可以参照(  Nginx源码解析--configure_编程界的谢菲尔德的博客-CSDN博客)添加进去
. auto/modules
. auto/make

2.在configure命令执行到auto/modules脚本时,将在生成的ngx_modules.c文件中加入定制的

第三方模块
if test -n "$NGX_ADDONS"; then
echo configuring additional modules
for ngx_addon_dir in $NGX_ADDONS
do
echo "adding module in $ngx_addon_dir"
if test -f $ngx_addon_dir/config; then
#在这里执行自定义的
config脚本
. $ngx_addon_dir/config
echo " + $ngx_addon_name was configured"
else
echo "$0: error: no $ngx_addon_dir/config was found"
exit 1
fi
done
fi
可以看到, $NGX_ADDONS 可以包含多个目录,对于每个目录,如果其中存在 config
件就会执行,也就是说,在 config 中重新定义的变量都会生效。之后, auto/modules 脚本开始
创建 ngx_modules.c 文件,这个文件的关键点就是定义了 ngx_module_t*ngx_modules[] 数组,这
个数组存储了 Nginx 中的所有模块。 Nginx 在初始化、处理请求时,都会循环访问 ngx_modules
数组,确定该用哪一个模块来处理

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

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

相关文章

考虑阶梯式碳交易机制与电制氢的综合能源系统热电优化(Matlab代码实现)

💥💥💥💞💞💞欢迎来到本博客❤️❤️❤️💥💥💥 📝目前更新:🌟🌟🌟电力系统相关知识,期刊论文&…

【YOLO系列改进NO.45】首发最新特征融合技术RepGFPN(DAMO-YOLO)

文章目录前言一、解决问题二、基本原理三、​添加方法四、总结前言 作为当前先进的深度学习目标检测算法YOLOv7,已经集合了大量的trick,但是还是有提高和改进的空间,针对具体应用场景下的检测难点,可以不同的改进方法。此后的系列…

[附源码]计算机毕业设计springboot云南美食管理系统

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

语义分割在线标注思路

语义分割选择使用多边形框标注,相对于物体检测它多了一项计算mask掩膜的需求。 一个图片,可能会进行多项标注。每项标注里面都会在物体检测的格式基础上增加mask属性,mask解释为图像掩膜,里面存与图像宽高对应大小的二维数组。 此…

什么是蛋白质组学?

导读 本文[1] 将从蛋白质组学的定义,蛋白质组包含的类型,常用技术,面临的挑战等方面,对蛋白质组学进行一个简要的介绍。 1. 定义 “蛋白质组学”一词于 1995 年首次出现,被定义为对细胞系、组织或生物体所有蛋白质的大…

Vue-router 路由间参数传递看完让你明明白白!

目录概述路由传参的两大载体分类声明式路由 【router-link 】编程式路由 【this.$router.push()】传参的方式1. 通过 params 传递参数配置路由参数字段占位(编程式路由实现)配置路由参数字段占位(声明式路由实现)无需配置路由参数…

Spring框架(四):Spring命名空间和配置标签

Spring框架(四):Spring命名空间和配置标签命名空间介绍配置标签Beans标签DemoImport标签Demoalias标签的Demo和Debug痛定思痛,主要问题出现在自己雀氏不熟悉框架基础、一些面试题,以及sql的使用淡忘了。本章节的开始是…

剩余内存无法满足申请时,系统会怎么做?

文章目录前言内存的分配机制回收可回收内存的类型如何在保证系统性能前提下回收内存可回收类型角度: 调整文件页回收倾向回收的方式角度: 尽早触发kswapd内核线程从计算机CPU架构角度: 采用NUMA如何保护进程不被OOM杀掉总结前言 当我们向操作系统申请内存时候,是否有想过一个问…

Bootstrap页面整合(十二)

首先引入bootstrap&#xff1a; 复制导航条代码&#xff1a; 修改导航条&#xff1a; 删除 改完的导航条&#xff1a; <!--导航条--> <nav class"navbar navbar-inverse"><div class"container-fluid"><!--屏幕自适应的--><d…

【吴恩达机器学习笔记】十、支持向量机

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4e3;专栏定位&#xff1a;为学习吴恩达机器学习视频的同学提供的随堂笔记。 &#x1f4da;专栏简介&#xff1a;在这个专栏&#xff0c;我将整理吴恩达机器学习视频的所有内容的笔记&…

神经气体网络(NGN)和不断增长的神经气体网络(GNGN)研究(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

[附源码]计算机毕业设计springboot影评网站系统

项目运行 环境配置&#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…

Python案例实战,gopup模块,Python3行代码就能获取海量数据

前言 今天给大家分享一个三行代码就能获取海量数据 包含了有指数数据、宏观经济数据、新经济数据、微博KOL数据、信息数据、生活数据、疫情数据等。 开发工具 Python版本&#xff1a; 3.6.4 相关模块&#xff1a; gopup模块 环境搭建 安装Python并添加到环境变量&#…

Linux权限管理(umask、粘滞位)

目录 Linux权限管理 文件访问权限的相关设置方法 目录的权限 umask 粘滞位 Linux下有两种用户&#xff1a;超级用户&#xff08;root&#xff09;、普通用户。 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受限制 普通用户&#xff1a;在linux下做有限…

闲鱼话术,必须收藏

今天分享&#xff1a;闲鱼卖货&#xff0c;常用的客服话术。建议收藏 很多学员&#xff0c;货也上了&#xff0c;有人咨询的时候忽然手忙脚乱&#xff0c;懵啊&#xff0c;怎么感觉没人问期待有人问&#xff0c;有人问&#xff0c;自己啥也说不出来了呢?哈哈&#xff0c;不知…

【BOOST C++ 19 应用库】(6)序列数据封装和优化

一、说明 用于优化的包装函数&#xff1a;本节介绍包装函数以优化序列化过程。这些函数标记对象以允许 Boost.Serialization 应用某些优化技术。 二、示范和代码 示例 64.14。在没有包装函数的情况下序列化数组 #include <boost/archive/text_oarchive.hpp> #include &…

[附源码]计算机毕业设计springboot医院门诊管理信息系统

项目运行 环境配置&#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…

SpringBoot中使用MySQL存用户信息, 日志的使用

SpringBoot中使用MySQL存用户信息 UserController类 package com.tedu.secboot.controller; import com.tarena.mnmp.api.SendParam; import com.tedu.secboot.entity.User; import com.tedu.secboot.util.DBUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory;…

flink教程(2)-source- sink

一、flink可识别的source分类 Sources are where your program reads its input from. You can attach a source to your program by using StreamExecutionEnvironment.addSource(sourceFunction). Flink comes with a number of pre-implemented source functions, but you c…

[附源码]计算机毕业设计游戏商城平台论文Springboot程序

项目运行 环境配置&#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…